about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md66
-rw-r--r--Cargo.lock140
-rw-r--r--RELEASES.md149
-rw-r--r--src/bootstrap/test.rs8
-rw-r--r--src/ci/docker/x86_64-gnu-llvm-7/Dockerfile19
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/liballoc/macros.rs5
-rw-r--r--src/liballoc/slice.rs2
-rw-r--r--src/liballoc/string.rs9
-rw-r--r--src/libcore/future/mod.rs7
-rw-r--r--src/libcore/ops/arith.rs21
-rw-r--r--src/libcore/ptr/const_ptr.rs28
-rw-r--r--src/libcore/ptr/mut_ptr.rs28
-rw-r--r--src/libcore/slice/mod.rs2
-rw-r--r--src/libcore/str/pattern.rs36
-rw-r--r--src/librustc_ast_lowering/expr.rs49
-rw-r--r--src/librustc_ast_lowering/item.rs4
-rw-r--r--src/librustc_ast_lowering/lib.rs23
-rw-r--r--src/librustc_ast_passes/ast_validation.rs25
-rw-r--r--src/librustc_codegen_ssa/Cargo.toml2
-rw-r--r--src/librustc_codegen_ssa/back/link.rs17
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs10
-rw-r--r--src/librustc_error_codes/error_codes/E0517.md3
-rw-r--r--src/librustc_error_codes/error_codes/E0518.md6
-rw-r--r--src/librustc_expand/expand.rs6
-rw-r--r--src/librustc_hir/definitions.rs24
-rw-r--r--src/librustc_hir/hir.rs17
-rw-r--r--src/librustc_hir/hir_id.rs3
-rw-r--r--src/librustc_hir/lang_items.rs2
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs2
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/util.rs2
-rw-r--r--src/librustc_lint/builtin.rs8
-rw-r--r--src/librustc_lint/types.rs10
-rw-r--r--src/librustc_lint/unused.rs2
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs4
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs14
-rw-r--r--src/librustc_middle/hir/map/collector.rs9
-rw-r--r--src/librustc_middle/hir/map/mod.rs10
-rw-r--r--src/librustc_middle/middle/stability.rs16
-rw-r--r--src/librustc_middle/traits/specialization_graph.rs4
-rw-r--r--src/librustc_middle/ty/adjustment.rs2
-rw-r--r--src/librustc_middle/ty/context.rs17
-rw-r--r--src/librustc_middle/ty/instance.rs2
-rw-r--r--src/librustc_middle/ty/mod.rs40
-rw-r--r--src/librustc_middle/ty/query/mod.rs28
-rw-r--r--src/librustc_middle/ty/query/plumbing.rs29
-rw-r--r--src/librustc_middle/ty/sty.rs58
-rw-r--r--src/librustc_middle/ty/trait_def.rs2
-rw-r--r--src/librustc_mir/borrow_check/type_check/mod.rs2
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs41
-rw-r--r--src/librustc_mir/const_eval/machine.rs51
-rw-r--r--src/librustc_mir/interpret/eval_context.rs34
-rw-r--r--src/librustc_mir/interpret/machine.rs20
-rw-r--r--src/librustc_mir/interpret/memory.rs4
-rw-r--r--src/librustc_mir/interpret/operand.rs11
-rw-r--r--src/librustc_mir/interpret/place.rs2
-rw-r--r--src/librustc_mir/interpret/terminator.rs10
-rw-r--r--src/librustc_mir/shim.rs2
-rw-r--r--src/librustc_mir/transform/add_retag.rs6
-rw-r--r--src/librustc_mir/transform/const_prop.rs22
-rw-r--r--src/librustc_mir/transform/mod.rs6
-rw-r--r--src/librustc_mir/transform/promote_consts.rs6
-rw-r--r--src/librustc_mir_build/build/block.rs2
-rw-r--r--src/librustc_mir_build/build/cfg.rs8
-rw-r--r--src/librustc_mir_build/build/expr/as_rvalue.rs6
-rw-r--r--src/librustc_mir_build/build/expr/into.rs2
-rw-r--r--src/librustc_mir_build/build/misc.rs4
-rw-r--r--src/librustc_mir_build/build/scope.rs2
-rw-r--r--src/librustc_mir_build/hair/cx/expr.rs14
-rw-r--r--src/librustc_mir_build/hair/cx/mod.rs2
-rw-r--r--src/librustc_parse/parser/expr.rs8
-rw-r--r--src/librustc_passes/hir_id_validator.rs10
-rw-r--r--src/librustc_privacy/lib.rs19
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/late/lifetimes.rs10
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs13
-rw-r--r--src/librustc_span/symbol.rs3
-rw-r--r--src/librustc_target/spec/armebv7r_none_eabi.rs1
-rw-r--r--src/librustc_target/spec/armebv7r_none_eabihf.rs1
-rw-r--r--src/librustc_target/spec/armv7r_none_eabi.rs1
-rw-r--r--src/librustc_target/spec/armv7r_none_eabihf.rs1
-rw-r--r--src/librustc_target/spec/dragonfly_base.rs1
-rw-r--r--src/librustc_target/spec/freebsd_base.rs1
-rw-r--r--src/librustc_target/spec/fuchsia_base.rs1
-rw-r--r--src/librustc_target/spec/haiku_base.rs1
-rw-r--r--src/librustc_target/spec/hermit_base.rs1
-rw-r--r--src/librustc_target/spec/hermit_kernel_base.rs1
-rw-r--r--src/librustc_target/spec/i686_pc_windows_gnu.rs2
-rw-r--r--src/librustc_target/spec/i686_pc_windows_msvc.rs24
-rw-r--r--src/librustc_target/spec/i686_unknown_uefi.rs7
-rw-r--r--src/librustc_target/spec/i686_uwp_windows_gnu.rs2
-rw-r--r--src/librustc_target/spec/illumos_base.rs48
-rw-r--r--src/librustc_target/spec/l4re_base.rs1
-rw-r--r--src/librustc_target/spec/linux_base.rs1
-rw-r--r--src/librustc_target/spec/linux_kernel_base.rs1
-rw-r--r--src/librustc_target/spec/mod.rs36
-rw-r--r--src/librustc_target/spec/msvc_base.rs35
-rw-r--r--src/librustc_target/spec/netbsd_base.rs1
-rw-r--r--src/librustc_target/spec/openbsd_base.rs1
-rw-r--r--src/librustc_target/spec/redox_base.rs1
-rw-r--r--src/librustc_target/spec/solaris_base.rs1
-rw-r--r--src/librustc_target/spec/tests/tests_impl.rs43
-rw-r--r--src/librustc_target/spec/thumb_base.rs1
-rw-r--r--src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs9
-rw-r--r--src/librustc_target/spec/uefi_base.rs67
-rw-r--r--src/librustc_target/spec/uefi_msvc_base.rs58
-rw-r--r--src/librustc_target/spec/vxworks_base.rs1
-rw-r--r--src/librustc_target/spec/windows_gnu_base.rs (renamed from src/librustc_target/spec/windows_base.rs)1
-rw-r--r--src/librustc_target/spec/windows_msvc_base.rs32
-rw-r--r--src/librustc_target/spec/windows_uwp_gnu_base.rs (renamed from src/librustc_target/spec/windows_uwp_base.rs)35
-rw-r--r--src/librustc_target/spec/windows_uwp_msvc_base.rs41
-rw-r--r--src/librustc_target/spec/x86_64_pc_windows_gnu.rs2
-rw-r--r--src/librustc_target/spec/x86_64_unknown_illumos.rs24
-rw-r--r--src/librustc_target/spec/x86_64_unknown_uefi.rs7
-rw-r--r--src/librustc_target/spec/x86_64_uwp_windows_gnu.rs2
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs23
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/suggestions.rs246
-rw-r--r--src/librustc_trait_selection/traits/mod.rs2
-rw-r--r--src/librustc_trait_selection/traits/object_safety.rs4
-rw-r--r--src/librustc_trait_selection/traits/query/normalize.rs15
-rw-r--r--src/librustc_trait_selection/traits/util.rs6
-rw-r--r--src/librustc_traits/implied_outlives_bounds.rs2
-rw-r--r--src/librustc_ty/ty.rs10
-rw-r--r--src/librustc_typeck/check/compare_method.rs4
-rw-r--r--src/librustc_typeck/check/demand.rs24
-rw-r--r--src/librustc_typeck/check/expr.rs2
-rw-r--r--src/librustc_typeck/check/method/confirm.rs2
-rw-r--r--src/librustc_typeck/check/method/mod.rs10
-rw-r--r--src/librustc_typeck/check/method/probe.rs41
-rw-r--r--src/librustc_typeck/check/method/suggest.rs17
-rw-r--r--src/librustc_typeck/check/mod.rs60
-rw-r--r--src/librustc_typeck/check/wfcheck.rs6
-rw-r--r--src/librustc_typeck/check/writeback.rs20
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs24
-rw-r--r--src/librustc_typeck/collect.rs22
-rw-r--r--src/librustc_typeck/impl_wf_check.rs2
-rw-r--r--src/librustc_typeck/lib.rs5
-rw-r--r--src/librustdoc/clean/cfg.rs1
-rw-r--r--src/librustdoc/clean/mod.rs22
-rw-r--r--src/librustdoc/clean/utils.rs50
-rw-r--r--src/librustdoc/html/render/cache.rs10
-rw-r--r--src/librustdoc/html/static/rustdoc.css19
-rw-r--r--src/librustdoc/html/static/themes/dark.css22
-rw-r--r--src/librustdoc/html/static/themes/light.css23
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs23
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs2
-rw-r--r--src/librustdoc/test.rs9
-rw-r--r--src/libstd/build.rs8
-rw-r--r--src/libstd/f64.rs2
-rw-r--r--src/libstd/os/illumos/fs.rs118
-rw-r--r--src/libstd/os/illumos/mod.rs6
-rw-r--r--src/libstd/os/illumos/raw.rs74
-rw-r--r--src/libstd/os/mod.rs2
-rw-r--r--src/libstd/sys/unix/alloc.rs14
-rw-r--r--src/libstd/sys/unix/args.rs1
-rw-r--r--src/libstd/sys/unix/env.rs11
-rw-r--r--src/libstd/sys/unix/fd.rs2
-rw-r--r--src/libstd/sys/unix/fs.rs34
-rw-r--r--src/libstd/sys/unix/mod.rs2
-rw-r--r--src/libstd/sys/unix/net.rs8
-rw-r--r--src/libstd/sys/unix/os.rs4
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs5
-rw-r--r--src/libstd/sys/unix/thread.rs4
-rw-r--r--src/libstd/sys/windows/ext/fs.rs2
-rw-r--r--src/libstd/sys_common/net.rs4
-rw-r--r--src/libtest/helpers/concurrency.rs1
-rw-r--r--src/libunwind/build.rs2
m---------src/llvm-project0
-rw-r--r--src/test/compile-fail/issue-52443.rs5
-rw-r--r--src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir8
-rw-r--r--src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir8
-rw-r--r--src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir8
-rw-r--r--src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir8
-rw-r--r--src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir8
-rw-r--r--src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir8
-rw-r--r--src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir8
-rw-r--r--src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir8
-rw-r--r--src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir8
-rw-r--r--src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir8
-rw-r--r--src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir9
-rw-r--r--src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir15
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir15
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff12
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff24
-rw-r--r--src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff8
-rw-r--r--src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff8
-rw-r--r--src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff8
-rw-r--r--src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff8
-rw-r--r--src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir8
-rw-r--r--src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir8
-rw-r--r--src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot2
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place.rs2
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff85
-rw-r--r--src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff (renamed from src/test/mir-opt/inline/inline-into-box-place/rustc.main.Inline.diff)39
-rw-r--r--src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff14
-rw-r--r--src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir24
-rw-r--r--src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir8
-rw-r--r--src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir8
-rw-r--r--src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir24
-rw-r--r--src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir24
-rw-r--r--src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir16
-rw-r--r--src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir8
-rw-r--r--src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir8
-rw-r--r--src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir8
-rw-r--r--src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir8
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir16
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir16
-rw-r--r--src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir8
-rw-r--r--src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir8
-rw-r--r--src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir16
-rw-r--r--src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff11
-rw-r--r--src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff12
-rw-r--r--src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff36
-rw-r--r--src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff24
-rw-r--r--src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff16
-rw-r--r--src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff8
-rw-r--r--src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir16
-rw-r--r--src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir8
-rw-r--r--src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir8
-rw-r--r--src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir11
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir8
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff8
-rw-r--r--src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff24
-rw-r--r--src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff32
-rw-r--r--src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff40
-rw-r--r--src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff20
-rw-r--r--src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir50
-rw-r--r--src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs2
-rw-r--r--src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr13
-rw-r--r--src/test/ui/async-await/async-fn-nonsend.stderr6
-rw-r--r--src/test/ui/async-await/issue-64130-1-sync.stderr2
-rw-r--r--src/test/ui/async-await/issue-64130-2-send.stderr2
-rw-r--r--src/test/ui/async-await/issue-64130-3-other.stderr2
-rw-r--r--src/test/ui/async-await/issue-64130-4-async-move.stderr4
-rw-r--r--src/test/ui/async-await/issue-64130-non-send-future-diags.stderr2
-rw-r--r--src/test/ui/async-await/issue-67252-unnamed-future.stderr4
-rw-r--r--src/test/ui/async-await/issue-68112.rs64
-rw-r--r--src/test/ui/async-await/issue-68112.stderr56
-rw-r--r--src/test/ui/async-await/issue-70594.stderr5
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr5
-rw-r--r--src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr4
-rw-r--r--src/test/ui/const-generics/const-fn-with-const-param.rs4
-rw-r--r--src/test/ui/const-generics/const-fn-with-const-param.stderr17
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.rs3
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.rs3
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.rs3
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.stderr10
-rw-r--r--src/test/ui/consts/const-eval/issue-52442.rs2
-rw-r--r--src/test/ui/consts/const-eval/issue-52442.stderr20
-rw-r--r--src/test/ui/consts/issue-52432.rs1
-rw-r--r--src/test/ui/consts/issue-52432.stderr12
-rw-r--r--src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs15
-rw-r--r--src/test/ui/consts/too_generic_eval_ice.rs7
-rw-r--r--src/test/ui/consts/too_generic_eval_ice.stderr46
-rw-r--r--src/test/ui/error-codes/E0034.stderr4
-rw-r--r--src/test/ui/generator/issue-68112.rs56
-rw-r--r--src/test/ui/generator/issue-68112.stderr40
-rw-r--r--src/test/ui/generator/not-send-sync.rs2
-rw-r--r--src/test/ui/generator/not-send-sync.stderr8
-rw-r--r--src/test/ui/inference/inference_unstable_featured.stderr4
-rw-r--r--src/test/ui/integer-literal-suffix-inference.rs58
-rw-r--r--src/test/ui/integer-literal-suffix-inference.stderr242
-rw-r--r--src/test/ui/issues/issue-18446.stderr4
-rw-r--r--src/test/ui/issues/issue-3702-2.stderr4
-rw-r--r--src/test/ui/issues/issue-39211.rs3
-rw-r--r--src/test/ui/issues/issue-39211.stderr9
-rw-r--r--src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr4
-rw-r--r--src/test/ui/issues/issue-66706.rs13
-rw-r--r--src/test/ui/issues/issue-66706.stderr43
-rw-r--r--src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs1
-rw-r--r--src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr10
-rw-r--r--src/test/ui/issues/issue-69841.rs1
-rw-r--r--src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr62
-rw-r--r--src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr62
-rw-r--r--src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr62
-rw-r--r--src/test/ui/lint/lint-exceeding-bitshifts.rs52
-rw-r--r--src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr4
-rw-r--r--src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr4
-rw-r--r--src/test/ui/methods/method-ambig-two-traits-from-impls.stderr4
-rw-r--r--src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr4
-rw-r--r--src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr4
-rw-r--r--src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr10
-rw-r--r--src/test/ui/numeric/numeric-cast.fixed8
-rw-r--r--src/test/ui/numeric/numeric-cast.stderr40
-rw-r--r--src/test/ui/option-to-result.rs13
-rw-r--r--src/test/ui/option-to-result.stderr29
-rw-r--r--src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs35
-rw-r--r--src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr123
-rw-r--r--src/test/ui/span/issue-37767.stderr12
-rw-r--r--src/test/ui/span/issue-7575.stderr8
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr2
-rw-r--r--src/test/ui/traits/trait-alias-ambiguous.stderr4
-rw-r--r--src/test/ui/try-block/try-block-in-match.rs6
-rw-r--r--src/test/ui/try-block/try-block-in-match.stderr10
-rw-r--r--src/test/ui/try-block/try-block-in-while.rs3
-rw-r--r--src/test/ui/try-block/try-block-in-while.stderr9
-rw-r--r--src/test/ui/try-block/try-block-unused-delims.rs28
-rw-r--r--src/test/ui/try-block/try-block-unused-delims.stderr44
-rw-r--r--src/test/ui/try-on-option.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs17
-rw-r--r--src/tools/build-manifest/src/main.rs1
m---------src/tools/cargo0
m---------src/tools/clippy30
-rw-r--r--src/tools/compiletest/src/runtest.rs31
-rw-r--r--src/tools/compiletest/src/util.rs1
m---------src/tools/miri17
-rwxr-xr-xsrc/tools/publish_toolstate.py2
m---------src/tools/rls0
-rw-r--r--src/tools/rustdoc-js-common/lib.js319
-rw-r--r--src/tools/rustdoc-js-std/tester.js74
-rw-r--r--src/tools/rustdoc-js/tester.js413
m---------src/tools/rustfmt32
346 files changed, 4424 insertions, 1918 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2843944b2e1..051f5af7bc1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -188,7 +188,70 @@ with one another are rolled up.
 Speaking of tests, Rust has a comprehensive test suite. More information about
 it can be found [here][rctd].
 
-### External Dependencies
+### External Dependencies (subtree)
+
+As a developer to this repository, you don't have to treat the following external projects
+differently from other crates that are directly in this repo:
+
+* none so far, see https://github.com/rust-lang/rust/issues/70651 for more info
+
+They are just regular files and directories. This is in contrast to `submodule` dependencies
+(see below for those). Only tool authors will actually use any operations here.
+
+#### Synchronizing a subtree
+
+There are two synchronization directions: `subtree push` and `subtree pull`.
+
+```
+git subtree push -P src/tools/clippy git@github.com:your-github-name/rust-clippy sync-from-rust
+```
+
+takes all the changes that
+happened to the copy in this repo and creates commits on the remote repo that match the local
+changes. Every local commit that touched the subtree causes a commit on the remote repo, but is
+modified to move the files from the specified directory to the tool repo root.
+
+Make sure to not pick the `master` branch on the tool repo, so you can open a normal PR to the tool
+to merge that subrepo push.
+
+```
+git subtree pull -P src/tools/clippy https://github.com/rust-lang/rust-clippy master
+```
+
+takes all changes since the last `subtree pull` from the tool repo
+repo and adds these commits to the rustc repo + a merge commit that moves the tool changes into
+the specified directory in the rust repository.
+
+It is recommended that you always do a push first and get that merged to the tool master branch.
+Then, when you do a pull, the merge works without conflicts.
+While it's definitely possible to resolve conflicts during a pull, you may have to redo the conflict
+resolution if your PR doesn't get merged fast enough and there are new conflicts. Do not try to
+rebase the result of a `git subtree pull`, rebasing merge commits is a bad idea in general.
+
+You always need to specify the `-P` prefix to the subtree directory and the corresponding remote
+repository. If you specify the wrong directory or repository
+you'll get very fun merges that try to push the wrong directory to the wrong remote repository.
+Luckily you can just abort this without any consequences by throwing away either the pulled commits
+in rustc or the pushed branch on the remote and try again. It is usually fairly obvious
+that this is happening because you suddenly get thousands of commits that want to be synchronized.
+
+#### Creating a new subtree dependency
+
+If you want to create a new subtree dependency from an existing repository, call (from this
+repository's root directory!)
+
+```
+git subtree add -P src/tools/clippy https://github.com/rust-lang/rust-clippy.git master
+```
+
+This will create a new commit, which you may not rebase under any circumstances! Delete the commit
+and redo the operation if you need to rebase.
+
+Now you're done, the `src/tools/clippy` directory behaves as if clippy were part of the rustc
+monorepo, so no one but you (or others that synchronize subtrees) actually needs to use `git subtree`.
+
+
+### External Dependencies (submodules)
 
 Currently building Rust will also build the following external projects:
 
@@ -221,7 +284,6 @@ before the PR is merged.
 
 Rust's build system builds a number of tools that make use of the
 internals of the compiler. This includes
-[Clippy](https://github.com/rust-lang/rust-clippy),
 [RLS](https://github.com/rust-lang/rls) and
 [rustfmt](https://github.com/rust-lang/rustfmt). If these tools
 break because of your changes, you may run into a sort of "chicken and egg"
diff --git a/Cargo.lock b/Cargo.lock
index 73d276d1776..cf86f44305e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -310,7 +310,6 @@ dependencies = [
  "env_logger 0.7.1",
  "filetime",
  "flate2",
- "fs2",
  "fwdansi",
  "git2",
  "git2-curl",
@@ -335,7 +334,7 @@ dependencies = [
  "pretty_env_logger",
  "remove_dir_all",
  "rustc-workspace-hack",
- "rustfix 0.5.0",
+ "rustfix",
  "same-file",
  "semver",
  "serde",
@@ -586,7 +585,7 @@ dependencies = [
  "log",
  "miow 0.3.3",
  "regex",
- "rustfix 0.5.0",
+ "rustfix",
  "serde",
  "serde_json",
  "walkdir",
@@ -595,9 +594,9 @@ dependencies = [
 
 [[package]]
 name = "compiletest_rs"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7b678957210a00ba0fbeacc23d38cbfbf29895564da1616564634351e1dac5e"
+checksum = "9f737835bfbbe29ed1ff82d5137520338d7ed5bf1a1d4b9c1c7c58bb45b8fa29"
 dependencies = [
  "diff",
  "filetime",
@@ -606,7 +605,7 @@ dependencies = [
  "log",
  "miow 0.3.3",
  "regex",
- "rustfix 0.4.6",
+ "rustfix",
  "serde",
  "serde_derive",
  "serde_json",
@@ -1084,9 +1083,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 
 [[package]]
 name = "filetime"
-version = "0.2.8"
+version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ff6d4dab0aa0c8e6346d46052e93b13a16cf847b54ed357087c35011048cc7d"
+checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e"
 dependencies = [
  "cfg-if",
  "libc",
@@ -1147,16 +1146,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "fs2"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
-dependencies = [
- "libc",
- "winapi 0.3.8",
-]
-
-[[package]]
 name = "fs_extra"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1262,9 +1251,9 @@ dependencies = [
 
 [[package]]
 name = "git2"
-version = "0.13.0"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7da16ceafe24cedd9ba02c4463a2b506b6493baf4317c79c5acb553134a3c15"
+checksum = "2cfb93ca10f2934069c3aaafb753fbe0663f08ee009a01b6d62e062391447b15"
 dependencies = [
  "bitflags",
  "libc",
@@ -1797,18 +1786,18 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.66"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
+checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
 dependencies = [
  "rustc-std-workspace-core",
 ]
 
 [[package]]
 name = "libgit2-sys"
-version = "0.12.0+0.99.0"
+version = "0.12.3+1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05dff41ac39e7b653f5f1550886cf00ba52f8e7f57210b633cdeedb3de5b236c"
+checksum = "7637dc15e7f05a16011723e0448655081fc01a374bcd368e2c9b9c7f5c5ab3ea"
 dependencies = [
  "cc",
  "libc",
@@ -2715,9 +2704,9 @@ dependencies = [
 
 [[package]]
 name = "racer"
-version = "2.1.32"
+version = "2.1.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e805a6c323d08b26270f0276cef35608456916dc266ef27434edbe666eceeeb5"
+checksum = "54322b696f7df20e0d79d0244a1088f387b7164a5f17987c4ab984dec1a23e42"
 dependencies = [
  "bitflags",
  "clap",
@@ -3157,9 +3146,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-arena"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "632704fb93ca8148957191e5d2d827082f93c4aa20cdd242fb46d8cca57029da"
+checksum = "81dfcfbb0ddfd533abf8c076e3b49d1e5042d1962526a12ce2c66d514b24cca3"
 dependencies = [
  "rustc-ap-rustc_data_structures",
  "smallvec 1.0.0",
@@ -3167,15 +3156,15 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-graphviz"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdd4689b814859c9f1b3e314ed2bde596acac428a256a16894635f600bed46b4"
+checksum = "7490bb07b014a7f9531bde33c905a805e08095dbefdb4c9988a1b19fe6d019fd"
 
 [[package]]
 name = "rustc-ap-rustc_ast"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "101c1517d3fd19d083aaca5b113f9965e6ae353a0bb09c49959b0f62b95b75d9"
+checksum = "189f16dbb8dd11089274c9ced58b0cae9e1ea3e434a58f3db683817eda849e58"
 dependencies = [
  "log",
  "rustc-ap-rustc_data_structures",
@@ -3190,10 +3179,11 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_ast_passes"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ab3f5a7e939b37c99d8ca371f09b10bb5b5c85ad5d5b8d1d736ce8248c71be0"
+checksum = "bbe619609b56a617fa986332b066d53270093c816d8ff8281fc90e1dbe74c1cc"
 dependencies = [
+ "itertools 0.8.0",
  "log",
  "rustc-ap-rustc_ast",
  "rustc-ap-rustc_ast_pretty",
@@ -3208,9 +3198,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_ast_pretty"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05046d3a2b8de22b20bcda9a1c063dc5c1f2f721f042b6c2809df2d23c64a13e"
+checksum = "26ab1495f7b420e937688749c1da5763aaabd6ebe8cacb758665a0b8481da094"
 dependencies = [
  "log",
  "rustc-ap-rustc_ast",
@@ -3220,9 +3210,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_attr"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f00b7ccad6fc3628fb44950435772945a425575f9ea0b3708c536fe75623a6e8"
+checksum = "2e057495724c60729c1d1d9d49374e0b3ebd6d3481cd161b2871f52fe017b7b5"
 dependencies = [
  "rustc-ap-rustc_ast",
  "rustc-ap-rustc_ast_pretty",
@@ -3238,9 +3228,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c6121ab6766644fa76b711f65d4c39f2e335488ab768324567fed0ed191166e"
+checksum = "d2130997667833692f4bec4681d0e73b066d5a01dac1d8a68f22068b82bf173a"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -3249,6 +3239,7 @@ dependencies = [
  "indexmap",
  "jobserver",
  "lazy_static 1.4.0",
+ "libc",
  "log",
  "measureme",
  "parking_lot 0.10.0",
@@ -3265,9 +3256,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adab84c842003ad1c8435fd71b8d0cc19bf0d702a8a2147d5be06e083db2d207"
+checksum = "908e1ea187c6bb368af4ba6db980001e920515e67371ddc4086e749baabe6080"
 dependencies = [
  "annotate-snippets",
  "atty",
@@ -3283,9 +3274,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_expand"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb001df541ea02b65c8e294252530010c6f90e3c6a5716e8e24e58c12dd1cd86"
+checksum = "50066a75bca872ff933b0ee8a582d18ef1876c8054a392f60c39e538446bfb00"
 dependencies = [
  "log",
  "rustc-ap-rustc_ast",
@@ -3305,9 +3296,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_feature"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "446cc60613cc3b05d0bdbcab7feb02305790b5617fa43c532d51ae3223d677a4"
+checksum = "96fb53e1710e6de7c2e371ca56c857b79f9b399aba58aa6b6fbed6e2f677d3f6"
 dependencies = [
  "lazy_static 1.4.0",
  "rustc-ap-rustc_data_structures",
@@ -3316,15 +3307,15 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_fs_util"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ac99d6f67e7db3bb300895630e769ed41bd3e336c0e725870c70e676c1a5ff1"
+checksum = "e3f91357e5e468fc2729211571d769723c728a34e200d90a70164e945f881e09"
 
 [[package]]
 name = "rustc-ap-rustc_index"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5608c1cf50d2251b7e10a138cf6dd388e97f139b21c00b06a22d06f89c6591f6"
+checksum = "32220c3e6cdf226f38e4474b747dca15f3106bb680c74f10b299af3f6cdb1663"
 dependencies = [
  "rustc-ap-serialize",
  "smallvec 1.0.0",
@@ -3332,18 +3323,18 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_lexer"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74e9c1c6f5dc85977b3adb6fb556b2ff23354d1a12021da15eb1d36353458bde"
+checksum = "3b324d2a2bacad344e53e182e5ca04ffb74745b932849aa074f8f7fec8177da5"
 dependencies = [
  "unicode-xid 0.2.0",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_macros"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3226b5ec864312a5d23eb40a5d621ee06bdc0754228d20d6eb76d4ddc4f2d4a1"
+checksum = "59686c56d5f1b3ed47d0f070c257ed35caf24ecf2d744dd11fe44b1014baee0f"
 dependencies = [
  "proc-macro2 1.0.3",
  "quote 1.0.2",
@@ -3353,9 +3344,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_parse"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3b042344c2280b50d5df0058d11379028a8f016a407e575bb3ea8b6c798049"
+checksum = "2dfb0c11c591ec5f87bbadb10819795abc9035ff79a26703c1b6c9487ac51f49"
 dependencies = [
  "bitflags",
  "log",
@@ -3373,10 +3364,11 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_session"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff35ef4b5d9fbcb2fd539c7c908eb3cdd1f68ddbccd042945ef50ae65564f941"
+checksum = "3d1a194b1a81d7233ee492847638dc9ebdb7d084300e5ade8dea0ceaa98f95b9"
 dependencies = [
+ "getopts",
  "log",
  "num_cpus",
  "rustc-ap-rustc_ast",
@@ -3392,26 +3384,28 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_span"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e323b1f4a824039886eed8e33cad20ea4f492a9f9b3c9441009797c91de3e87a"
+checksum = "a648146050fed6b58e681ec22488e728f60e16036bb7497c9815e3debd1e4242"
 dependencies = [
  "cfg-if",
  "log",
+ "md-5",
  "rustc-ap-arena",
  "rustc-ap-rustc_data_structures",
  "rustc-ap-rustc_index",
  "rustc-ap-rustc_macros",
  "rustc-ap-serialize",
  "scoped-tls",
+ "sha-1",
  "unicode-width",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e161eb7b3a5b7993c6b480135296dc61476db80041d49dd446422742426e390b"
+checksum = "28cf28798f0988b808e3616713630e4098d68c6f1f41052a2f7e922e094da744"
 dependencies = [
  "bitflags",
  "log",
@@ -3424,9 +3418,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "651.0.0"
+version = "654.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af510a659098d8c45a7303fb882fa780f4a87ec5f5d7a2053521e7d5d7f332c4"
+checksum = "756e8f526ec7906e132188bf25e3c10a6ee42ab77294ecb3b3602647f0508eef"
 dependencies = [
  "indexmap",
  "smallvec 1.0.0",
@@ -4381,18 +4375,6 @@ dependencies = [
 
 [[package]]
 name = "rustfix"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7150ac777a2931a53489f5a41eb0937b84e3092a20cd0e73ad436b65b507f607"
-dependencies = [
- "failure",
- "log",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "rustfix"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "804b11883a5ce0ad0378fbf95a8dea59ee6b51c331a73b8f471b6bdaa3bd40c1"
@@ -4415,7 +4397,7 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.4.13"
+version = "1.4.14"
 dependencies = [
  "annotate-snippets",
  "bytecount",
@@ -4672,9 +4654,9 @@ checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
 
 [[package]]
 name = "socket2"
-version = "0.3.11"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85"
+checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
 dependencies = [
  "cfg-if",
  "libc",
diff --git a/RELEASES.md b/RELEASES.md
index 9ff0d14b353..36597b1864f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,152 @@
+Version 1.43.0 (2020-04-23)
+==========================
+
+Language
+--------
+- [Fixed using binary operations with `&{number}` (e.g. `&1.0`) not having
+  the type inferred correctly.][68129]
+- [Attributes such as `#[cfg()]` can now be used on `if` expressions.][69201]
+
+**Syntax only changes**
+- [Allow `type Foo: Ord` syntactically.][69361]
+- [Fuse associated and extern items up to defaultness.][69194]
+- [Syntactically allow `self` in all `fn` contexts.][68764]
+- [Merge `fn` syntax + cleanup item parsing.][68728]
+- [`item` macro fragments can be interpolated into `trait`s, `impl`s, and `extern` blocks.][69366]
+  For example, you may now write:
+  ```rust 
+  macro_rules! mac_trait {
+      ($i:item) => {
+          trait T { $i }
+      }
+  }
+  mac_trait! {
+      fn foo() {}
+  }
+  ```
+
+These are still rejected *semantically*, so you will likely receive an error but
+these changes can be seen and parsed by macros and
+conditional compilation.
+
+
+Compiler
+--------
+- [You can now pass multiple lint flags to rustc to override the previous
+  flags.][67885] For example; `rustc -D unused -A unused-variables` denies
+  everything in the `unused` lint group except `unused-variables` which
+  is explicitly allowed. However, passing `rustc -A unused-variables -D unused` denies
+  everything in the `unused` lint group **including** `unused-variables` since
+  the allow flag is specified before the deny flag (and therefore overridden).
+- [rustc will now prefer your system MinGW libraries over its bundled libraries
+  if they are available on `windows-gnu`.][67429]
+- [rustc now buffers errors/warnings printed in JSON.][69227]
+
+Libraries
+---------
+- [`Arc<[T; N]>`, `Box<[T; N]>`, and `Rc<[T; N]>`, now implement
+  `TryFrom<Arc<[T]>>`,`TryFrom<Box<[T]>>`, and `TryFrom<Rc<[T]>>`
+  respectively.][69538] **Note** These conversions are only available when `N`
+  is `0..=32`.
+- [You can now use associated constants on floats and integers directly, rather
+  than having to import the module.][68952] e.g. You can now write `u32::MAX` or
+  `f32::NAN` with no imports.
+- [`u8::is_ascii` is now `const`.][68984]
+- [`String` now implements `AsMut<str>`.][68742]
+- [Added the `primitive` module to `std` and `core`.][67637] This module
+  reexports Rust's primitive types. This is mainly useful in macros
+  where you want avoid these types being shadowed.
+- [Relaxed some of the trait bounds on `HashMap` and `HashSet`.][67642]
+- [`string::FromUtf8Error` now implements `Clone + Eq`.][68738]
+
+Stabilized APIs
+---------------
+- [`Once::is_completed`]
+- [`f32::LOG10_2`]
+- [`f32::LOG2_10`]
+- [`f64::LOG10_2`]
+- [`f64::LOG2_10`]
+- [`iter::once_with`]
+
+Cargo
+-----
+- [You can now set config `[profile]`s in your `.cargo/config`, or through
+  your environment.][cargo/7823]
+- [Cargo will now set `CARGO_BIN_EXE_<name>` pointing to a binary's
+  executable path when running integration tests or benchmarks.][cargo/7697]
+  `<name>` is the name of your binary as-is e.g. If you wanted the executable
+  path for a binary named `my-program`you would use `env!("CARGO_BIN_EXE_my-program")`.
+
+Misc
+----
+- [Certain checks in the `const_err` lint were deemed unrelated to const
+  evaluation][69185], and have been moved to the `unconditional_panic` and
+  `arithmetic_overflow` lints.
+  
+Compatibility Notes
+-------------------
+
+- [Having trailing syntax in the `assert!` macro is now a hard error.][69548] This
+  has been a warning since 1.36.0.
+- [Fixed `Self` not having the correctly inferred type.][69340] This incorrectly
+  led to some instances being accepted, and now correctly emits a hard error.
+
+[69340]: https://github.com/rust-lang/rust/pull/69340
+
+Internal Only
+-------------
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of `rustc` and
+related tools.
+
+- [All components are now built with `opt-level=3` instead of `2`.][67878]
+- [Improved how rustc generates drop code.][67332]
+- [Improved performance from `#[inline]`-ing certain hot functions.][69256]
+- [traits: preallocate 2 Vecs of known initial size][69022]
+- [Avoid exponential behaviour when relating types][68772]
+- [Skip `Drop` terminators for enum variants without drop glue][68943]
+- [Improve performance of coherence checks][68966]
+- [Deduplicate types in the generator witness][68672]
+- [Invert control in struct_lint_level.][68725]
+
+[67332]: https://github.com/rust-lang/rust/pull/67332/
+[67429]: https://github.com/rust-lang/rust/pull/67429/
+[67637]: https://github.com/rust-lang/rust/pull/67637/
+[67642]: https://github.com/rust-lang/rust/pull/67642/
+[67878]: https://github.com/rust-lang/rust/pull/67878/
+[67885]: https://github.com/rust-lang/rust/pull/67885/
+[68129]: https://github.com/rust-lang/rust/pull/68129/
+[68672]: https://github.com/rust-lang/rust/pull/68672/
+[68725]: https://github.com/rust-lang/rust/pull/68725/
+[68728]: https://github.com/rust-lang/rust/pull/68728/
+[68738]: https://github.com/rust-lang/rust/pull/68738/
+[68742]: https://github.com/rust-lang/rust/pull/68742/
+[68764]: https://github.com/rust-lang/rust/pull/68764/
+[68772]: https://github.com/rust-lang/rust/pull/68772/
+[68943]: https://github.com/rust-lang/rust/pull/68943/
+[68952]: https://github.com/rust-lang/rust/pull/68952/
+[68966]: https://github.com/rust-lang/rust/pull/68966/
+[68984]: https://github.com/rust-lang/rust/pull/68984/
+[69022]: https://github.com/rust-lang/rust/pull/69022/
+[69185]: https://github.com/rust-lang/rust/pull/69185/
+[69194]: https://github.com/rust-lang/rust/pull/69194/
+[69201]: https://github.com/rust-lang/rust/pull/69201/
+[69227]: https://github.com/rust-lang/rust/pull/69227/
+[69548]: https://github.com/rust-lang/rust/pull/69548/
+[69256]: https://github.com/rust-lang/rust/pull/69256/
+[69361]: https://github.com/rust-lang/rust/pull/69361/
+[69366]: https://github.com/rust-lang/rust/pull/69366/
+[69538]: https://github.com/rust-lang/rust/pull/69538/
+[cargo/7823]: https://github.com/rust-lang/cargo/pull/7823
+[cargo/7697]: https://github.com/rust-lang/cargo/pull/7697
+[`Once::is_completed`]: https://doc.rust-lang.org/std/sync/struct.Once.html#method.is_completed
+[`f32::LOG10_2`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG10_2.html
+[`f32::LOG2_10`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG2_10.html
+[`f64::LOG10_2`]: https://doc.rust-lang.org/std/f64/consts/constant.LOG10_2.html
+[`f64::LOG2_10`]: https://doc.rust-lang.org/std/f64/consts/constant.LOG2_10.html
+[`iter::once_with`]: https://doc.rust-lang.org/std/iter/fn.once_with.html
+
+
 Version 1.42.0 (2020-03-12)
 ==========================
 
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 0bf507f9ebb..85c5d28bb89 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -627,8 +627,14 @@ impl Step for RustdocJSStd {
         if let Some(ref nodejs) = builder.config.nodejs {
             let mut command = Command::new(nodejs);
             command
-                .arg(builder.src.join("src/tools/rustdoc-js-std/tester.js"))
+                .arg(builder.src.join("src/tools/rustdoc-js/tester.js"))
+                .arg("--crate-name")
+                .arg("std")
+                .arg("--resource-suffix")
+                .arg(crate::channel::CFG_RELEASE_NUM)
+                .arg("--doc-folder")
                 .arg(builder.doc_out(self.target))
+                .arg("--test-folder")
                 .arg(builder.src.join("src/test/rustdoc-js-std"));
             builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage });
             builder.run(&mut command);
diff --git a/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile
index 4b5d5cac516..f70c3de2ece 100644
--- a/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile
+++ b/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile
@@ -2,6 +2,7 @@ FROM ubuntu:18.04
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
   g++ \
+  g++-arm-linux-gnueabi \
   make \
   file \
   curl \
@@ -29,7 +30,23 @@ ENV RUST_CONFIGURE_ARGS \
       --enable-llvm-link-shared \
       --set rust.thin-lto-import-instr-limit=10
 
-ENV SCRIPT python2.7 ../x.py test --exclude src/tools/tidy && python2.7 ../x.py test src/tools/tidy
+ENV SCRIPT python2.7 ../x.py test --exclude src/tools/tidy && \
+           # Run the `mir-opt` tests again but this time for a 32-bit target.
+           # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
+           # both 32-bit and 64-bit outputs updated by the PR author, before
+           # the PR is approved and tested for merging.
+           # It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
+           # despite having different output on 32-bit vs 64-bit targets.
+           #
+           # HACK(eddyb) `armv5te` is used (not `i686`) to support older LLVM than LLVM 9:
+           # https://github.com/rust-lang/compiler-builtins/pull/311#issuecomment-612270089.
+           # This also requires `--pass=build` because we can't execute the tests
+           # on the `x86_64` host when they're built as `armv5te` binaries.
+           # (we're only interested in the MIR output, so this doesn't matter)
+           python2.7 ../x.py test src/test/mir-opt --pass=build \
+                                  --target=armv5te-unknown-linux-gnueabi && \
+           # Run tidy at the very end, after all the other tests.
+           python2.7 ../x.py test src/tools/tidy
 
 # The purpose of this container isn't to test with debug assertions and
 # this is run on all PRs, so let's get speedier builds by disabling these extra
diff --git a/src/doc/book b/src/doc/book
-Subproject c8841f2841a2d26124319ddadd1b6a245f9a185
+Subproject f5db319e0b19c22964398d56bc63103d669e1bb
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 37f9e6848411188a1062ead1bd8ebe4b8aa1689
+Subproject 8204c1d123472cd17f0c1c5c77300ae802eb027
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject d22a9c487c78095afc4584f1d9b4ec43529d713
+Subproject 668fb07b6160b9c468f598e839c1e044db65de3
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 89dd146154474559536d5d4049a03831c501dee
+Subproject 3ce94caed4cf967106c51ae86be5e098f7875f1
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject a6638463efc7631bc0e8dc67ccd256d4e1b61f1
+Subproject c106d1683c3a2b0960f0f0fb01728cbb1980733
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs
index 4bc0c3a079d..e163a166b49 100644
--- a/src/liballoc/macros.rs
+++ b/src/liballoc/macros.rs
@@ -42,10 +42,9 @@ macro_rules! vec {
     ($elem:expr; $n:expr) => (
         $crate::vec::from_elem($elem, $n)
     );
-    ($($x:expr),*) => (
-        <[_]>::into_vec(box [$($x),*])
+    ($($x:expr),+ $(,)?) => (
+        <[_]>::into_vec(box [$($x),+])
     );
-    ($($x:expr,)*) => ($crate::vec![$($x),*])
 }
 
 // HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 4ae7532d992..4171185c970 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -254,7 +254,7 @@ impl<T> [T] {
 
     /// Sorts the slice with a key extraction function.
     ///
-    /// This sort is stable (i.e., does not reorder equal elements) and `O(m n log(m n))`
+    /// This sort is stable (i.e., does not reorder equal elements) and `O(m n log n)`
     /// worst-case, where the key function is `O(m)`.
     ///
     /// For expensive key functions (e.g. functions that are not simple property accesses or
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 1e5fe125c55..80fa8139915 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -482,6 +482,7 @@ impl String {
     /// [`String`]: struct.String.html
     /// [`u8`]: ../../std/primitive.u8.html
     /// [`Vec<u8>`]: ../../std/vec/struct.Vec.html
+    /// [`&str`]: ../../std/primitive.str.html
     /// [`str::from_utf8`]: ../../std/str/fn.from_utf8.html
     /// [`into_bytes`]: struct.String.html#method.into_bytes
     /// [`FromUtf8Error`]: struct.FromUtf8Error.html
@@ -1827,7 +1828,13 @@ impl<'a> Extend<Cow<'a, str>> for String {
     }
 }
 
-/// A convenience impl that delegates to the impl for `&str`
+/// A convenience impl that delegates to the impl for `&str`.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!(String::from("Hello world").find("world"), Some(6));
+/// ```
 #[unstable(
     feature = "pattern",
     reason = "API not fully fleshed out and ready to be stabilized",
diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs
index 8dfda7a4a32..a6b769147d0 100644
--- a/src/libcore/future/mod.rs
+++ b/src/libcore/future/mod.rs
@@ -77,9 +77,6 @@ where
 #[unstable(feature = "gen_future", issue = "50547")]
 #[cfg(not(bootstrap))]
 #[inline]
-pub unsafe fn poll_with_context<F>(f: Pin<&mut F>, mut cx: ResumeTy) -> Poll<F::Output>
-where
-    F: Future,
-{
-    F::poll(f, cx.0.as_mut())
+pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> {
+    &mut *cx.0.as_ptr().cast()
 }
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index e9ec81394e3..622a138abe9 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -617,35 +617,22 @@ pub trait Neg {
     fn neg(self) -> Self::Output;
 }
 
-macro_rules! neg_impl_core {
-    ($id:ident => $body:expr, $($t:ty)*) => ($(
+macro_rules! neg_impl {
+    ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Neg for $t {
             type Output = $t;
 
             #[inline]
             #[rustc_inherit_overflow_checks]
-            fn neg(self) -> $t { let $id = self; $body }
+            fn neg(self) -> $t { -self }
         }
 
         forward_ref_unop! { impl Neg, neg for $t }
     )*)
 }
 
-macro_rules! neg_impl_numeric {
-    ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
-}
-
-#[allow(unused_macros)]
-macro_rules! neg_impl_unsigned {
-    ($($t:ty)*) => {
-        neg_impl_core!{ x => {
-            !x.wrapping_add(1)
-        }, $($t)*} }
-}
-
-// neg_impl_unsigned! { usize u8 u16 u32 u64 }
-neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
+neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
 
 /// The addition assignment operator `+=`.
 ///
diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs
index 52e224d2a02..729e0b897c0 100644
--- a/src/libcore/ptr/const_ptr.rs
+++ b/src/libcore/ptr/const_ptr.rs
@@ -706,6 +706,34 @@ impl<T: ?Sized> *const T {
     }
 }
 
+#[cfg(not(bootstrap))]
+#[lang = "const_slice_ptr"]
+impl<T> *const [T] {
+    /// Returns the length of a raw slice.
+    ///
+    /// The returned value is the number of **elements**, not the number of bytes.
+    ///
+    /// This function is safe, even when the raw slice cannot be cast to a slice
+    /// reference because the pointer is null or unaligned.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// #![feature(slice_ptr_len)]
+    ///
+    /// use std::ptr;
+    ///
+    /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
+    /// assert_eq!(slice.len(), 3);
+    /// ```
+    #[inline]
+    #[unstable(feature = "slice_ptr_len", issue = "71146")]
+    #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust: self }.raw }.len
+    }
+}
+
 // Equality for pointers
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialEq for *const T {
diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs
index 9f85d781d69..3b7e83bf37f 100644
--- a/src/libcore/ptr/mut_ptr.rs
+++ b/src/libcore/ptr/mut_ptr.rs
@@ -894,6 +894,34 @@ impl<T: ?Sized> *mut T {
     }
 }
 
+#[cfg(not(bootstrap))]
+#[lang = "mut_slice_ptr"]
+impl<T> *mut [T] {
+    /// Returns the length of a raw slice.
+    ///
+    /// The returned value is the number of **elements**, not the number of bytes.
+    ///
+    /// This function is safe, even when the raw slice cannot be cast to a slice
+    /// reference because the pointer is null or unaligned.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// #![feature(slice_ptr_len)]
+    ///
+    /// use std::ptr;
+    ///
+    /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3);
+    /// assert_eq!(slice.len(), 3);
+    /// ```
+    #[inline]
+    #[unstable(feature = "slice_ptr_len", issue = "71146")]
+    #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust_mut: self }.raw }.len
+    }
+}
+
 // Equality for pointers
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialEq for *mut T {
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 66aad324618..4d333fbf8ed 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -1697,7 +1697,7 @@ impl<T> [T] {
     /// elements.
     ///
     /// This sort is unstable (i.e., may reorder equal elements), in-place
-    /// (i.e., does not allocate), and `O(m n log(m n))` worst-case, where the key function is
+    /// (i.e., does not allocate), and `O(m n log n)` worst-case, where the key function is
     /// `O(m)`.
     ///
     /// # Current implementation
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 30fd55f7b7f..708e4e5560e 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -451,7 +451,13 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> {
 
 impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {}
 
-/// Searches for chars that are equal to a given char
+/// Searches for chars that are equal to a given `char`.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!("Hello world".find('o'), Some(4));
+/// ```
 impl<'a> Pattern<'a> for char {
     type Searcher = CharSearcher<'a>;
 
@@ -696,7 +702,14 @@ unsafe impl<'a, 'b> ReverseSearcher<'a> for CharSliceSearcher<'a, 'b> {
 
 impl<'a, 'b> DoubleEndedSearcher<'a> for CharSliceSearcher<'a, 'b> {}
 
-/// Searches for chars that are equal to any of the chars in the array
+/// Searches for chars that are equal to any of the chars in the array.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!("Hello world".find(&['l', 'l'] as &[_]), Some(2));
+/// assert_eq!("Hello world".find(&['l', 'l'][..]), Some(2));
+/// ```
 impl<'a, 'b> Pattern<'a> for &'b [char] {
     pattern_methods!(CharSliceSearcher<'a, 'b>, MultiCharEqPattern, CharSliceSearcher);
 }
@@ -738,7 +751,14 @@ where
 
 impl<'a, F> DoubleEndedSearcher<'a> for CharPredicateSearcher<'a, F> where F: FnMut(char) -> bool {}
 
-/// Searches for chars that match the given predicate
+/// Searches for chars that match the given predicate.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!("Hello world".find(char::is_uppercase), Some(0));
+/// assert_eq!("Hello world".find(|c| "aeiou".contains(c)), Some(1));
+/// ```
 impl<'a, F> Pattern<'a> for F
 where
     F: FnMut(char) -> bool,
@@ -763,6 +783,12 @@ impl<'a, 'b, 'c> Pattern<'a> for &'c &'b str {
 ///
 /// Will handle the pattern `""` as returning empty matches at each character
 /// boundary.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!("Hello world".find("world"), Some(6));
+/// ```
 impl<'a, 'b> Pattern<'a> for &'b str {
     type Searcher = StrSearcher<'a, 'b>;
 
@@ -771,7 +797,7 @@ impl<'a, 'b> Pattern<'a> for &'b str {
         StrSearcher::new(haystack, self)
     }
 
-    /// Checks whether the pattern matches at the front of the haystack
+    /// Checks whether the pattern matches at the front of the haystack.
     #[inline]
     fn is_prefix_of(self, haystack: &'a str) -> bool {
         haystack.as_bytes().starts_with(self.as_bytes())
@@ -788,7 +814,7 @@ impl<'a, 'b> Pattern<'a> for &'b str {
         }
     }
 
-    /// Checks whether the pattern matches at the back of the haystack
+    /// Checks whether the pattern matches at the back of the haystack.
     #[inline]
     fn is_suffix_of(self, haystack: &'a str) -> bool {
         haystack.as_bytes().ends_with(self.as_bytes())
diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs
index 9984eb4e282..0eed47050aa 100644
--- a/src/librustc_ast_lowering/expr.rs
+++ b/src/librustc_ast_lowering/expr.rs
@@ -556,9 +556,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
     /// ```rust
     /// match <expr> {
     ///     mut pinned => loop {
-    ///         match unsafe { ::std::future::poll_with_context(
+    ///         match unsafe { ::std::future::Future::poll(
     ///             <::std::pin::Pin>::new_unchecked(&mut pinned),
-    ///             task_context,
+    ///             ::std::future::get_context(task_context),
     ///         ) } {
     ///             ::std::task::Poll::Ready(result) => break result,
     ///             ::std::task::Poll::Pending => {}
@@ -590,6 +590,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             await_span,
             self.allow_gen_future.clone(),
         );
+        let expr = self.lower_expr(expr);
 
         let pinned_ident = Ident::with_dummy_span(sym::pinned);
         let (pinned_pat, pinned_pat_hid) =
@@ -598,9 +599,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let task_context_ident = Ident::with_dummy_span(sym::_task_context);
 
         // unsafe {
-        //     ::std::future::poll_with_context(
+        //     ::std::future::Future::poll(
         //         ::std::pin::Pin::new_unchecked(&mut pinned),
-        //         task_context,
+        //         ::std::future::get_context(task_context),
         //     )
         // }
         let poll_expr = {
@@ -621,10 +622,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 arena_vec![self; ref_mut_pinned],
             );
             let new_unchecked = self.expr(span, new_unchecked_expr_kind, ThinVec::new());
-            let call = self.expr_call_std_path(
+            let get_context = self.expr_call_std_path_mut(
                 gen_future_span,
-                &[sym::future, sym::poll_with_context],
-                arena_vec![self; new_unchecked, task_context],
+                &[sym::future, sym::get_context],
+                arena_vec![self; task_context],
+            );
+            let call = self.expr_call_std_path(
+                span,
+                &[sym::future, sym::Future, sym::poll],
+                arena_vec![self; new_unchecked, get_context],
             );
             self.arena.alloc(self.expr_unsafe(call))
         };
@@ -671,7 +677,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let unit = self.expr_unit(span);
             let yield_expr = self.expr(
                 span,
-                hir::ExprKind::Yield(unit, hir::YieldSource::Await),
+                hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr.hir_id) }),
                 ThinVec::new(),
             );
             let yield_expr = self.arena.alloc(yield_expr);
@@ -704,7 +710,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // match <expr> {
         //     mut pinned => loop { .. }
         // }
-        let expr = self.lower_expr(expr);
         hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar)
     }
 
@@ -1326,25 +1331,43 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new()))
     }
 
+    fn expr_call_mut(
+        &mut self,
+        span: Span,
+        e: &'hir hir::Expr<'hir>,
+        args: &'hir [hir::Expr<'hir>],
+    ) -> hir::Expr<'hir> {
+        self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())
+    }
+
     fn expr_call(
         &mut self,
         span: Span,
         e: &'hir hir::Expr<'hir>,
         args: &'hir [hir::Expr<'hir>],
     ) -> &'hir hir::Expr<'hir> {
-        self.arena.alloc(self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()))
+        self.arena.alloc(self.expr_call_mut(span, e, args))
     }
 
     // Note: associated functions must use `expr_call_std_path`.
-    fn expr_call_std_path(
+    fn expr_call_std_path_mut(
         &mut self,
         span: Span,
         path_components: &[Symbol],
         args: &'hir [hir::Expr<'hir>],
-    ) -> &'hir hir::Expr<'hir> {
+    ) -> hir::Expr<'hir> {
         let path =
             self.arena.alloc(self.expr_std_path(span, path_components, None, ThinVec::new()));
-        self.expr_call(span, path, args)
+        self.expr_call_mut(span, path, args)
+    }
+
+    fn expr_call_std_path(
+        &mut self,
+        span: Span,
+        path_components: &[Symbol],
+        args: &'hir [hir::Expr<'hir>],
+    ) -> &'hir hir::Expr<'hir> {
+        self.arena.alloc(self.expr_call_std_path_mut(span, path_components, args))
     }
 
     // Create an expression calling an associated function of an std type.
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index 9779954d759..c535885e70c 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -796,7 +796,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 (hir::AssocItemKind::Type, default.is_some())
             }
             AssocItemKind::Fn(_, sig, _, default) => {
-                (hir::AssocItemKind::Method { has_self: sig.decl.has_self() }, default.is_some())
+                (hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, default.is_some())
             }
             AssocItemKind::MacCall(..) => unimplemented!(),
         };
@@ -894,7 +894,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     }
                 }
                 AssocItemKind::Fn(_, sig, ..) => {
-                    hir::AssocItemKind::Method { has_self: sig.decl.has_self() }
+                    hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
                 }
                 AssocItemKind::MacCall(..) => unimplemented!(),
             },
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 9bb1f57a524..c2c7de9d21b 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -168,7 +168,7 @@ struct LoweringContext<'a, 'hir: 'a> {
 
     current_hir_id_owner: Vec<(LocalDefId, u32)>,
     item_local_id_counters: NodeMap<u32>,
-    node_id_to_hir_id: IndexVec<NodeId, hir::HirId>,
+    node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
 
     allow_try_trait: Option<Lrc<[Symbol]>>,
     allow_gen_future: Option<Lrc<[Symbol]>>,
@@ -522,7 +522,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
 
         self.lower_node_id(CRATE_NODE_ID);
-        debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID);
+        debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID));
 
         visit::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }, c);
         visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
@@ -530,7 +530,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let module = self.lower_mod(&c.module);
         let attrs = self.lower_attrs(&c.attrs);
         let body_ids = body_ids(&self.bodies);
-        let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id]).collect();
+        let proc_macros =
+            c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
 
         self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
 
@@ -571,26 +572,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         ast_node_id: NodeId,
         alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId,
     ) -> hir::HirId {
-        if ast_node_id == DUMMY_NODE_ID {
-            return hir::DUMMY_HIR_ID;
-        }
+        assert_ne!(ast_node_id, DUMMY_NODE_ID);
 
         let min_size = ast_node_id.as_usize() + 1;
 
         if min_size > self.node_id_to_hir_id.len() {
-            self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
+            self.node_id_to_hir_id.resize(min_size, None);
         }
 
-        let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
-
-        if existing_hir_id == hir::DUMMY_HIR_ID {
+        if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] {
+            existing_hir_id
+        } else {
             // Generate a new `HirId`.
             let hir_id = alloc_hir_id(self);
-            self.node_id_to_hir_id[ast_node_id] = hir_id;
+            self.node_id_to_hir_id[ast_node_id] = Some(hir_id);
 
             hir_id
-        } else {
-            existing_hir_id
         }
     }
 
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index 9563325fe32..395fd746085 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -561,28 +561,6 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    /// We currently do not permit const generics in `const fn`,
-    /// as this is tantamount to allowing compile-time dependent typing.
-    ///
-    /// FIXME(const_generics): Is this really true / necessary? Discuss with @varkor.
-    /// At any rate, the restriction feels too syntactic. Consider moving it to e.g. typeck.
-    fn check_const_fn_const_generic(&self, span: Span, sig: &FnSig, generics: &Generics) {
-        if let Const::Yes(const_span) = sig.header.constness {
-            // Look for const generics and error if we find any.
-            for param in &generics.params {
-                if let GenericParamKind::Const { .. } = param.kind {
-                    self.err_handler()
-                        .struct_span_err(
-                            span,
-                            "const parameters are not permitted in const functions",
-                        )
-                        .span_label(const_span, "`const` because of this")
-                        .emit();
-                }
-            }
-        }
-    }
-
     fn check_item_named(&self, ident: Ident, kind: &str) {
         if ident.name != kw::Underscore {
             return;
@@ -966,9 +944,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         .emit();
                 }
             }
-            ItemKind::Fn(def, ref sig, ref generics, ref body) => {
+            ItemKind::Fn(def, _, _, ref body) => {
                 self.check_defaultness(item.span, def);
-                self.check_const_fn_const_generic(item.span, sig, generics);
 
                 if body.is_none() {
                     let msg = "free function without a body";
diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
index 717e32d4a0d..d9620a21d37 100644
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ b/src/librustc_codegen_ssa/Cargo.toml
@@ -15,7 +15,7 @@ cc = "1.0.1"
 num_cpus = "1.0"
 memmap = "0.7"
 log = "0.4.5"
-libc = "0.2.44"
+libc = "0.2.50"
 jobserver = "0.1.11"
 tempfile = "3.1"
 
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 20e64f0c488..4c66d901e7a 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -12,7 +12,7 @@ use rustc_session::search_paths::PathKind;
 /// need out of the shared crate context before we get rid of it.
 use rustc_session::{filesearch, Session};
 use rustc_span::symbol::Symbol;
-use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel};
+use rustc_target::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelroLevel};
 
 use super::archive::ArchiveBuilder;
 use super::command::Command;
@@ -182,7 +182,9 @@ fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command {
     // To comply with the Windows App Certification Kit,
     // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
     let t = &sess.target.target;
-    if flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" {
+    if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link))
+        && t.target_vendor == "uwp"
+    {
         if let Some(ref tool) = msvc_tool {
             let original_path = tool.path();
             if let Some(ref root_lib_path) = original_path.ancestors().nth(4) {
@@ -759,7 +761,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
                         }
                     }
                     LinkerFlavor::Gcc => {
-                        if cfg!(target_os = "solaris") {
+                        if cfg!(any(target_os = "solaris", target_os = "illumos")) {
                             // On historical Solaris systems, "cc" may have
                             // been Sun Studio, which is not flag-compatible
                             // with "gcc".  This history casts a long shadow,
@@ -1530,13 +1532,8 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
     cmd.debuginfo();
 
     // OBJECT-FILES-NO, AUDIT-ORDER
-    // We want to, by default, prevent the compiler from accidentally leaking in
-    // any system libraries, so we may explicitly ask linkers to not link to any
-    // libraries by default. Note that this does not happen for windows because
-    // windows pulls in some large number of libraries and I couldn't quite
-    // figure out which subset we wanted.
-    //
-    // This is all naturally configurable via the standard methods as well.
+    // We want to prevent the compiler from accidentally leaking in any system libraries,
+    // so by default we tell linkers not to link to any default libraries.
     if !sess.opts.cg.default_linker_libraries.unwrap_or(false)
         && sess.target.target.options.no_default_libraries
     {
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 0baa37ae9f1..d8c5ddf586f 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -631,15 +631,7 @@ impl<'a> Linker for MsvcLinker<'a> {
     }
 
     fn no_default_libraries(&mut self) {
-        // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC
-        // as there's been trouble in the past of linking the C++ standard
-        // library required by LLVM. This likely needs to happen one day, but
-        // in general Windows is also a more controlled environment than
-        // Unix, so it's not necessarily as critical that this be implemented.
-        //
-        // Note that there are also some licensing worries about statically
-        // linking some libraries which require a specific agreement, so it may
-        // not ever be possible for us to pass this flag.
+        self.cmd.arg("/NODEFAULTLIB");
     }
 
     fn include_path(&mut self, path: &Path) {
diff --git a/src/librustc_error_codes/error_codes/E0517.md b/src/librustc_error_codes/error_codes/E0517.md
index f738d33560a..ae802245bd1 100644
--- a/src/librustc_error_codes/error_codes/E0517.md
+++ b/src/librustc_error_codes/error_codes/E0517.md
@@ -1,5 +1,4 @@
-This error indicates that a `#[repr(..)]` attribute was placed on an
-unsupported item.
+A `#[repr(..)]` attribute was placed on an unsupported item.
 
 Examples of erroneous code:
 
diff --git a/src/librustc_error_codes/error_codes/E0518.md b/src/librustc_error_codes/error_codes/E0518.md
index 1af9a3735fe..f04329bc4e6 100644
--- a/src/librustc_error_codes/error_codes/E0518.md
+++ b/src/librustc_error_codes/error_codes/E0518.md
@@ -1,7 +1,7 @@
-This error indicates that an `#[inline(..)]` attribute was incorrectly placed
-on something other than a function or method.
+An `#[inline(..)]` attribute was incorrectly placed on something other than a
+function or method.
 
-Examples of erroneous code:
+Example of erroneous code:
 
 ```compile_fail,E0518
 #[inline(always)]
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index 51208906c2f..7473c890c5a 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -507,9 +507,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 expanded_fragments.push(Vec::new());
             }
             expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
-            if !self.cx.ecfg.single_step {
-                invocations.extend(new_invocations.into_iter().rev());
-            }
+            invocations.extend(new_invocations.into_iter().rev());
         }
 
         self.cx.current_expansion = orig_expansion_data;
@@ -1819,7 +1817,6 @@ pub struct ExpansionConfig<'feat> {
     pub recursion_limit: usize,
     pub trace_mac: bool,
     pub should_test: bool, // If false, strip `#[test]` nodes
-    pub single_step: bool,
     pub keep_macs: bool,
 }
 
@@ -1831,7 +1828,6 @@ impl<'feat> ExpansionConfig<'feat> {
             recursion_limit: 1024,
             trace_mac: false,
             should_test: false,
-            single_step: false,
             keep_macs: false,
         }
     }
diff --git a/src/librustc_hir/definitions.rs b/src/librustc_hir/definitions.rs
index 58f34787613..1ac23677d47 100644
--- a/src/librustc_hir/definitions.rs
+++ b/src/librustc_hir/definitions.rs
@@ -7,7 +7,6 @@
 pub use crate::def_id::DefPathHash;
 use crate::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use crate::hir;
-use crate::hir_id::DUMMY_HIR_ID;
 
 use rustc_ast::ast;
 use rustc_ast::crate_disambiguator::CrateDisambiguator;
@@ -87,7 +86,7 @@ pub struct Definitions {
     node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>,
     def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
 
-    pub(super) node_id_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
+    pub(super) node_id_to_hir_id: IndexVec<ast::NodeId, Option<hir::HirId>>,
     /// The reverse mapping of `node_id_to_hir_id`.
     pub(super) hir_id_to_node_id: FxHashMap<hir::HirId, ast::NodeId>,
 
@@ -345,8 +344,7 @@ impl Definitions {
     #[inline]
     pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> {
         if let Some(def_id) = def_id.as_local() {
-            let hir_id = self.local_def_id_to_hir_id(def_id);
-            if hir_id != DUMMY_HIR_ID { Some(hir_id) } else { None }
+            Some(self.local_def_id_to_hir_id(def_id))
         } else {
             None
         }
@@ -359,12 +357,23 @@ impl Definitions {
 
     #[inline]
     pub fn node_id_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
+        self.node_id_to_hir_id[node_id].unwrap()
+    }
+
+    #[inline]
+    pub fn opt_node_id_to_hir_id(&self, node_id: ast::NodeId) -> Option<hir::HirId> {
         self.node_id_to_hir_id[node_id]
     }
 
     #[inline]
     pub fn local_def_id_to_hir_id(&self, id: LocalDefId) -> hir::HirId {
         let node_id = self.def_id_to_node_id[id];
+        self.node_id_to_hir_id[node_id].unwrap()
+    }
+
+    #[inline]
+    pub fn opt_local_def_id_to_hir_id(&self, id: LocalDefId) -> Option<hir::HirId> {
+        let node_id = self.def_id_to_node_id[id];
         self.node_id_to_hir_id[node_id]
     }
 
@@ -470,7 +479,10 @@ impl Definitions {
 
     /// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during
     /// AST to HIR lowering.
-    pub fn init_node_id_to_hir_id_mapping(&mut self, mapping: IndexVec<ast::NodeId, hir::HirId>) {
+    pub fn init_node_id_to_hir_id_mapping(
+        &mut self,
+        mapping: IndexVec<ast::NodeId, Option<hir::HirId>>,
+    ) {
         assert!(
             self.node_id_to_hir_id.is_empty(),
             "trying to initialize `NodeId` -> `HirId` mapping twice"
@@ -481,7 +493,7 @@ impl Definitions {
         self.hir_id_to_node_id = self
             .node_id_to_hir_id
             .iter_enumerated()
-            .map(|(node_id, &hir_id)| (hir_id, node_id))
+            .filter_map(|(node_id, &hir_id)| hir_id.map(|hir_id| (hir_id, node_id)))
             .collect();
     }
 
diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs
index b719d576d6f..b66e6101b50 100644
--- a/src/librustc_hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -1736,15 +1736,24 @@ pub struct Destination {
 #[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)]
 pub enum YieldSource {
     /// An `<expr>.await`.
-    Await,
+    Await { expr: Option<HirId> },
     /// A plain `yield`.
     Yield,
 }
 
+impl YieldSource {
+    pub fn is_await(&self) -> bool {
+        match self {
+            YieldSource::Await { .. } => true,
+            YieldSource::Yield => false,
+        }
+    }
+}
+
 impl fmt::Display for YieldSource {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(match self {
-            YieldSource::Await => "`await`",
+            YieldSource::Await { .. } => "`await`",
             YieldSource::Yield => "`yield`",
         })
     }
@@ -1755,7 +1764,7 @@ impl From<GeneratorKind> for YieldSource {
         match kind {
             // Guess based on the kind of the current generator.
             GeneratorKind::Gen => Self::Yield,
-            GeneratorKind::Async(_) => Self::Await,
+            GeneratorKind::Async(_) => Self::Await { expr: None },
         }
     }
 }
@@ -2515,7 +2524,7 @@ pub struct ImplItemRef<'hir> {
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum AssocItemKind {
     Const,
-    Method { has_self: bool },
+    Fn { has_self: bool },
     Type,
     OpaqueTy,
 }
diff --git a/src/librustc_hir/hir_id.rs b/src/librustc_hir/hir_id.rs
index 1c7987e965f..d782c3dd70a 100644
--- a/src/librustc_hir/hir_id.rs
+++ b/src/librustc_hir/hir_id.rs
@@ -45,7 +45,4 @@ pub const CRATE_HIR_ID: HirId = HirId {
     local_id: ItemLocalId::from_u32(0),
 };
 
-pub const DUMMY_HIR_ID: HirId =
-    HirId { owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, local_id: DUMMY_ITEM_LOCAL_ID };
-
 pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;
diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs
index 5a3a9cabeb4..53f72804a84 100644
--- a/src/librustc_hir/lang_items.rs
+++ b/src/librustc_hir/lang_items.rs
@@ -135,6 +135,8 @@ language_item_table! {
     SliceU8AllocImplItem,        "slice_u8_alloc",     slice_u8_alloc_impl,     Target::Impl;
     ConstPtrImplItem,            "const_ptr",          const_ptr_impl,          Target::Impl;
     MutPtrImplItem,              "mut_ptr",            mut_ptr_impl,            Target::Impl;
+    ConstSlicePtrImplItem,       "const_slice_ptr",    const_slice_ptr_impl,    Target::Impl;
+    MutSlicePtrImplItem,         "mut_slice_ptr",      mut_slice_ptr_impl,      Target::Impl;
     I8ImplItem,                  "i8",                 i8_impl,                 Target::Impl;
     I16ImplItem,                 "i16",                i16_impl,                Target::Impl;
     I32ImplItem,                 "i32",                i32_impl,                Target::Impl;
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index db81ceea43f..4189570a0da 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -191,7 +191,7 @@ fn msg_span_from_early_bound_and_free_regions(
     let sm = tcx.sess.source_map();
 
     let scope = region.free_region_binding_scope(tcx);
-    let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID);
+    let node = tcx.hir().as_local_hir_id(scope).unwrap();
     let tag = match tcx.hir().find(node) {
         Some(Node::Block(_)) | Some(Node::Expr(_)) => "body",
         Some(Node::Item(it)) => item_scope_tag(&it),
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
index d35a589320b..7bbd2127bcf 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
@@ -118,7 +118,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     // enable E0621 for it.
     pub(super) fn is_self_anon(&self, is_first: bool, scope_def_id: DefId) -> bool {
         is_first
-            && self.tcx().opt_associated_item(scope_def_id).map(|i| i.method_has_self_argument)
+            && self.tcx().opt_associated_item(scope_def_id).map(|i| i.fn_has_self_parameter)
                 == Some(true)
     }
 }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 910d53880f2..627a438c2c3 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1354,7 +1354,7 @@ declare_lint! {
 }
 
 pub struct UnnameableTestItems {
-    boundary: hir::HirId, // HirId of the item under which things are not nameable
+    boundary: Option<hir::HirId>, // HirId of the item under which things are not nameable
     items_nameable: bool,
 }
 
@@ -1362,7 +1362,7 @@ impl_lint_pass!(UnnameableTestItems => [UNNAMEABLE_TEST_ITEMS]);
 
 impl UnnameableTestItems {
     pub fn new() -> Self {
-        Self { boundary: hir::DUMMY_HIR_ID, items_nameable: true }
+        Self { boundary: None, items_nameable: true }
     }
 }
 
@@ -1372,7 +1372,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems {
             if let hir::ItemKind::Mod(..) = it.kind {
             } else {
                 self.items_nameable = false;
-                self.boundary = it.hir_id;
+                self.boundary = Some(it.hir_id);
             }
             return;
         }
@@ -1385,7 +1385,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems {
     }
 
     fn check_item_post(&mut self, _cx: &LateContext<'_, '_>, it: &hir::Item<'_>) {
-        if !self.items_nameable && self.boundary == it.hir_id {
+        if !self.items_nameable && self.boundary == Some(it.hir_id) {
             self.items_nameable = true;
         }
     }
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index aa805a2f2db..ee2ed8826ba 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -43,14 +43,14 @@ declare_lint! {
 #[derive(Copy, Clone)]
 pub struct TypeLimits {
     /// Id of the last visited negated expression
-    negated_expr_id: hir::HirId,
+    negated_expr_id: Option<hir::HirId>,
 }
 
 impl_lint_pass!(TypeLimits => [UNUSED_COMPARISONS, OVERFLOWING_LITERALS]);
 
 impl TypeLimits {
     pub fn new() -> TypeLimits {
-        TypeLimits { negated_expr_id: hir::DUMMY_HIR_ID }
+        TypeLimits { negated_expr_id: None }
     }
 }
 
@@ -244,7 +244,7 @@ fn lint_int_literal<'a, 'tcx>(
     let int_type = t.normalize(cx.sess().target.ptr_width);
     let (min, max) = int_ty_range(int_type);
     let max = max as u128;
-    let negative = type_limits.negated_expr_id == e.hir_id;
+    let negative = type_limits.negated_expr_id == Some(e.hir_id);
 
     // Detect literal value out of range [min, max] inclusive
     // avoiding use of -min to prevent overflow/panic
@@ -397,8 +397,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
         match e.kind {
             hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => {
                 // propagate negation, if the negation itself isn't negated
-                if self.negated_expr_id != e.hir_id {
-                    self.negated_expr_id = expr.hir_id;
+                if self.negated_expr_id != Some(e.hir_id) {
+                    self.negated_expr_id = Some(expr.hir_id);
                 }
             }
             hir::ExprKind::Binary(binop, ref l, ref r) => {
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index aa7c87e9f7b..3e1e9cc70aa 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -384,7 +384,7 @@ trait UnusedDelimLint {
     fn is_expr_delims_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool {
         followed_by_block
             && match inner.kind {
-                ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true,
+                ExprKind::Ret(_) | ExprKind::Break(..) => true,
                 _ => parser::contains_exterior_struct_lit(&inner),
             }
     }
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 078f9251adf..ef6f37c5dab 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -1153,7 +1153,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false),
             EntryKind::AssocFn(data) => {
                 let data = data.decode(self);
-                (ty::AssocKind::Method, data.container, data.has_self)
+                (ty::AssocKind::Fn, data.container, data.has_self)
             }
             EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false),
             EntryKind::AssocOpaqueTy(container) => (ty::AssocKind::OpaqueTy, container, false),
@@ -1167,7 +1167,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             defaultness: container.defaultness(),
             def_id: self.local_def_id(id),
             container: container.with_def_id(parent),
-            method_has_self_argument: has_self,
+            fn_has_self_parameter: has_self,
         }
     }
 
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index d75298fae00..9c9869c8557 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -839,7 +839,7 @@ impl EncodeContext<'tcx> {
                     rendered_const,
                 )
             }
-            ty::AssocKind::Method => {
+            ty::AssocKind::Fn => {
                 let fn_data = if let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind {
                     let param_names = match *m {
                         hir::TraitFn::Required(ref names) => {
@@ -860,7 +860,7 @@ impl EncodeContext<'tcx> {
                 EntryKind::AssocFn(self.lazy(AssocFnData {
                     fn_data,
                     container,
-                    has_self: trait_item.method_has_self_argument,
+                    has_self: trait_item.fn_has_self_parameter,
                 }))
             }
             ty::AssocKind::Type => EntryKind::AssocType(container),
@@ -874,7 +874,7 @@ impl EncodeContext<'tcx> {
         self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         match trait_item.kind {
-            ty::AssocKind::Const | ty::AssocKind::Method => {
+            ty::AssocKind::Const | ty::AssocKind::Fn => {
                 self.encode_item_type(def_id);
             }
             ty::AssocKind::Type => {
@@ -884,7 +884,7 @@ impl EncodeContext<'tcx> {
             }
             ty::AssocKind::OpaqueTy => unreachable!(),
         }
-        if trait_item.kind == ty::AssocKind::Method {
+        if trait_item.kind == ty::AssocKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.encode_variances_of(def_id);
         }
@@ -931,7 +931,7 @@ impl EncodeContext<'tcx> {
                     bug!()
                 }
             }
-            ty::AssocKind::Method => {
+            ty::AssocKind::Fn => {
                 let fn_data = if let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind {
                     FnData {
                         asyncness: sig.header.asyncness,
@@ -944,7 +944,7 @@ impl EncodeContext<'tcx> {
                 EntryKind::AssocFn(self.lazy(AssocFnData {
                     fn_data,
                     container,
-                    has_self: impl_item.method_has_self_argument,
+                    has_self: impl_item.fn_has_self_parameter,
                 }))
             }
             ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container),
@@ -958,7 +958,7 @@ impl EncodeContext<'tcx> {
         self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
-        if impl_item.kind == ty::AssocKind::Method {
+        if impl_item.kind == ty::AssocKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.encode_variances_of(def_id);
         }
diff --git a/src/librustc_middle/hir/map/collector.rs b/src/librustc_middle/hir/map/collector.rs
index 70ea856498d..2906da437ab 100644
--- a/src/librustc_middle/hir/map/collector.rs
+++ b/src/librustc_middle/hir/map/collector.rs
@@ -250,23 +250,16 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
                     None => format!("{:?}", node),
                 };
 
-                let forgot_str = if hir_id == hir::DUMMY_HIR_ID {
-                    format!("\nMaybe you forgot to lower the node id {:?}?", node_id)
-                } else {
-                    String::new()
-                };
-
                 span_bug!(
                     span,
                     "inconsistent DepNode at `{:?}` for `{}`: \
-                     current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}",
+                     current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
                     self.source_map.span_to_string(span),
                     node_str,
                     self.definitions.def_path(self.current_dep_node_owner).to_string_no_crate(),
                     self.current_dep_node_owner,
                     self.definitions.def_path(hir_id.owner).to_string_no_crate(),
                     hir_id.owner,
-                    forgot_str,
                 )
             }
         }
diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs
index 3eaacb54d5b..ead8529fad8 100644
--- a/src/librustc_middle/hir/map/mod.rs
+++ b/src/librustc_middle/hir/map/mod.rs
@@ -215,10 +215,20 @@ impl<'hir> Map<'hir> {
     }
 
     #[inline]
+    pub fn opt_node_id_to_hir_id(&self, node_id: NodeId) -> Option<HirId> {
+        self.tcx.definitions.opt_node_id_to_hir_id(node_id)
+    }
+
+    #[inline]
     pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
         self.tcx.definitions.local_def_id_to_hir_id(def_id)
     }
 
+    #[inline]
+    pub fn opt_local_def_id_to_hir_id(&self, def_id: LocalDefId) -> Option<HirId> {
+        self.tcx.definitions.opt_local_def_id_to_hir_id(def_id)
+    }
+
     pub fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
         let node = self.find(hir_id)?;
 
diff --git a/src/librustc_middle/middle/stability.rs b/src/librustc_middle/middle/stability.rs
index 46525bdedad..1dd14b7c4ff 100644
--- a/src/librustc_middle/middle/stability.rs
+++ b/src/librustc_middle/middle/stability.rs
@@ -215,7 +215,6 @@ fn late_report_deprecation(
     suggestion: Option<Symbol>,
     lint: &'static Lint,
     span: Span,
-    def_id: DefId,
     hir_id: HirId,
 ) {
     if span.in_derive_expansion() {
@@ -229,9 +228,6 @@ fn late_report_deprecation(
         }
         diag.emit()
     });
-    if hir_id == hir::DUMMY_HIR_ID {
-        span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id);
-    }
 }
 
 /// Result of `TyCtxt::eval_stability`.
@@ -296,7 +292,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 if !skip {
                     let (message, lint) =
                         deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
-                    late_report_deprecation(self, &message, None, lint, span, def_id, id);
+                    late_report_deprecation(self, &message, None, lint, span, id);
                 }
             };
         }
@@ -319,15 +315,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 if let Some(depr) = &stability.rustc_depr {
                     let (message, lint) =
                         rustc_deprecation_message(depr, &self.def_path_str(def_id));
-                    late_report_deprecation(
-                        self,
-                        &message,
-                        depr.suggestion,
-                        lint,
-                        span,
-                        def_id,
-                        id,
-                    );
+                    late_report_deprecation(self, &message, depr.suggestion, lint, span, id);
                 }
             }
         }
diff --git a/src/librustc_middle/traits/specialization_graph.rs b/src/librustc_middle/traits/specialization_graph.rs
index a2793f98050..bc743666e4a 100644
--- a/src/librustc_middle/traits/specialization_graph.rs
+++ b/src/librustc_middle/traits/specialization_graph.rs
@@ -107,13 +107,13 @@ impl<'tcx> Node {
             .find(move |impl_item| {
                 match (trait_item_kind, impl_item.kind) {
                 | (Const, Const)
-                | (Method, Method)
+                | (Fn, Fn)
                 | (Type, Type)
                 | (Type, OpaqueTy)  // assoc. types can be made opaque in impls
                 => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
 
                 | (Const, _)
-                | (Method, _)
+                | (Fn, _)
                 | (Type, _)
                 | (OpaqueTy, _)
                 => false,
diff --git a/src/librustc_middle/ty/adjustment.rs b/src/librustc_middle/ty/adjustment.rs
index 851bffc2065..efd5adeba8c 100644
--- a/src/librustc_middle/ty/adjustment.rs
+++ b/src/librustc_middle/ty/adjustment.rs
@@ -123,7 +123,7 @@ impl<'tcx> OverloadedDeref<'tcx> {
         let method_def_id = tcx
             .associated_items(trait_def_id.unwrap())
             .in_definition_order()
-            .find(|m| m.kind == ty::AssocKind::Method)
+            .find(|m| m.kind == ty::AssocKind::Fn)
             .unwrap()
             .def_id;
         (method_def_id, tcx.mk_substs_trait(source, &[]))
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index 9fa25a43637..a49dc105498 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -1126,13 +1126,16 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
         for (k, v) in resolutions.trait_map {
-            let hir_id = definitions.node_id_to_hir_id(k);
-            let map = trait_map.entry(hir_id.owner).or_default();
-            let v = v
-                .into_iter()
-                .map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id)))
-                .collect();
-            map.insert(hir_id.local_id, StableVec::new(v));
+            // FIXME(#71104) Should really be using just `node_id_to_hir_id` but
+            // some `NodeId` do not seem to have a corresponding HirId.
+            if let Some(hir_id) = definitions.opt_node_id_to_hir_id(k) {
+                let map = trait_map.entry(hir_id.owner).or_default();
+                let v = v
+                    .into_iter()
+                    .map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id)))
+                    .collect();
+                map.insert(hir_id.local_id, StableVec::new(v));
+            }
         }
 
         GlobalCtxt {
diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs
index 894f9070ce1..ca76cfb1492 100644
--- a/src/librustc_middle/ty/instance.rs
+++ b/src/librustc_middle/ty/instance.rs
@@ -366,7 +366,7 @@ impl<'tcx> Instance<'tcx> {
         let call_once = tcx
             .associated_items(fn_once)
             .in_definition_order()
-            .find(|it| it.kind == ty::AssocKind::Method)
+            .find(|it| it.kind == ty::AssocKind::Fn)
             .unwrap()
             .def_id;
         let def = ty::InstanceDef::ClosureOnceShim { call_once };
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 0e6c4f26222..430ff67d56b 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 pub use self::fold::{TypeFoldable, TypeVisitor};
 pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
@@ -192,58 +190,50 @@ pub struct AssocItem {
     pub container: AssocItemContainer,
 
     /// Whether this is a method with an explicit self
-    /// as its first argument, allowing method calls.
-    pub method_has_self_argument: bool,
+    /// as its first parameter, allowing method calls.
+    pub fn_has_self_parameter: bool,
 }
 
 #[derive(Copy, Clone, PartialEq, Debug, HashStable)]
 pub enum AssocKind {
     Const,
-    Method,
+    Fn,
     OpaqueTy,
     Type,
 }
 
 impl AssocKind {
-    pub fn suggestion_descr(&self) -> &'static str {
-        match self {
-            ty::AssocKind::Method => "method call",
-            ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "associated type",
-            ty::AssocKind::Const => "associated constant",
-        }
-    }
-
     pub fn namespace(&self) -> Namespace {
         match *self {
             ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::TypeNS,
-            ty::AssocKind::Const | ty::AssocKind::Method => Namespace::ValueNS,
+            ty::AssocKind::Const | ty::AssocKind::Fn => Namespace::ValueNS,
         }
     }
-}
 
-impl AssocItem {
-    pub fn def_kind(&self) -> DefKind {
-        match self.kind {
+    pub fn as_def_kind(&self) -> DefKind {
+        match self {
             AssocKind::Const => DefKind::AssocConst,
-            AssocKind::Method => DefKind::AssocFn,
+            AssocKind::Fn => DefKind::AssocFn,
             AssocKind::Type => DefKind::AssocTy,
             AssocKind::OpaqueTy => DefKind::AssocOpaqueTy,
         }
     }
+}
 
+impl AssocItem {
     /// Tests whether the associated item admits a non-trivial implementation
     /// for !
     pub fn relevant_for_never(&self) -> bool {
         match self.kind {
             AssocKind::OpaqueTy | AssocKind::Const | AssocKind::Type => true,
             // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
-            AssocKind::Method => !self.method_has_self_argument,
+            AssocKind::Fn => !self.fn_has_self_parameter,
         }
     }
 
     pub fn signature(&self, tcx: TyCtxt<'_>) -> String {
         match self.kind {
-            ty::AssocKind::Method => {
+            ty::AssocKind::Fn => {
                 // We skip the binder here because the binder would deanonymize all
                 // late-bound regions, and we don't want method signatures to show up
                 // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
@@ -2409,7 +2399,11 @@ impl<'tcx> AdtDef {
                 None
             }
             Err(ErrorHandled::TooGeneric) => {
-                span_bug!(tcx.def_span(expr_did), "enum discriminant depends on generic arguments",)
+                tcx.sess.delay_span_bug(
+                    tcx.def_span(expr_did),
+                    "enum discriminant depends on generic arguments",
+                );
+                None
             }
         }
     }
@@ -2664,7 +2658,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
         self.associated_items(id)
             .in_definition_order()
-            .filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value())
+            .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value())
     }
 
     pub fn trait_relevant_for_never(self, did: DefId) -> bool {
diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs
index 9986eb88dc3..899479e65a7 100644
--- a/src/librustc_middle/ty/query/mod.rs
+++ b/src/librustc_middle/ty/query/mod.rs
@@ -189,3 +189,31 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool
 pub(crate) fn try_load_from_on_disk_cache<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) {
     rustc_dep_node_try_load_from_on_disk_cache!(dep_node, tcx)
 }
+
+mod sealed {
+    use super::{DefId, LocalDefId};
+
+    /// An analogue of the `Into` trait that's intended only for query paramaters.
+    ///
+    /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
+    /// user call `to_def_id` to convert between them everywhere else.
+    pub trait IntoQueryParam<P> {
+        fn into_query_param(self) -> P;
+    }
+
+    impl<P> IntoQueryParam<P> for P {
+        #[inline(always)]
+        fn into_query_param(self) -> P {
+            self
+        }
+    }
+
+    impl IntoQueryParam<DefId> for LocalDefId {
+        #[inline(always)]
+        fn into_query_param(self) -> DefId {
+            self.to_def_id()
+        }
+    }
+}
+
+use sealed::IntoQueryParam;
diff --git a/src/librustc_middle/ty/query/plumbing.rs b/src/librustc_middle/ty/query/plumbing.rs
index 1bb392f436f..068322b08b7 100644
--- a/src/librustc_middle/ty/query/plumbing.rs
+++ b/src/librustc_middle/ty/query/plumbing.rs
@@ -234,18 +234,23 @@ macro_rules! hash_result {
 
 macro_rules! define_queries {
     (<$tcx:tt> $($category:tt {
-        $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
+        $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($($K:tt)*) -> $V:ty,)*
     },)*) => {
         define_queries_inner! { <$tcx>
-            $($( $(#[$attr])* category<$category> [$($modifiers)*] fn $name: $node($K) -> $V,)*)*
+            $($( $(#[$attr])* category<$category> [$($modifiers)*] fn $name: $node($($K)*) -> $V,)*)*
         }
     }
 }
 
+macro_rules! query_helper_param_ty {
+    (DefId) => { impl IntoQueryParam<DefId> };
+    ($K:ty) => { $K };
+}
+
 macro_rules! define_queries_inner {
     (<$tcx:tt>
      $($(#[$attr:meta])* category<$category:tt>
-        [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {
+        [$($modifiers:tt)*] fn $name:ident: $node:ident($($K:tt)*) -> $V:ty,)*) => {
 
         use std::mem;
         use crate::{
@@ -263,7 +268,7 @@ macro_rules! define_queries_inner {
         #[allow(nonstandard_style)]
         #[derive(Clone, Debug)]
         pub enum Query<$tcx> {
-            $($(#[$attr])* $name($K)),*
+            $($(#[$attr])* $name($($K)*)),*
         }
 
         impl<$tcx> Query<$tcx> {
@@ -321,7 +326,7 @@ macro_rules! define_queries_inner {
         }
 
         $(impl<$tcx> QueryConfig<TyCtxt<$tcx>> for queries::$name<$tcx> {
-            type Key = $K;
+            type Key = $($K)*;
             type Value = $V;
             const NAME: &'static str = stringify!($name);
             const CATEGORY: ProfileCategory = $category;
@@ -332,7 +337,7 @@ macro_rules! define_queries_inner {
             const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
             const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$node;
 
-            type Cache = query_storage!([$($modifiers)*][$K, $V]);
+            type Cache = query_storage!([$($modifiers)*][$($K)*, $V]);
 
             #[inline(always)]
             fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState<TyCtxt<$tcx>, Self::Cache> {
@@ -380,8 +385,8 @@ macro_rules! define_queries_inner {
         impl TyCtxtEnsure<$tcx> {
             $($(#[$attr])*
             #[inline(always)]
-            pub fn $name(self, key: $K) {
-                ensure_query::<queries::$name<'_>, _>(self.tcx, key)
+            pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
+                ensure_query::<queries::$name<'_>, _>(self.tcx, key.into_query_param())
             })*
         }
 
@@ -421,7 +426,7 @@ macro_rules! define_queries_inner {
 
             $($(#[$attr])*
             #[inline(always)]
-            pub fn $name(self, key: $K) -> $V {
+            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
                 self.at(DUMMY_SP).$name(key)
             })*
 
@@ -458,14 +463,14 @@ macro_rules! define_queries_inner {
         impl TyCtxtAt<$tcx> {
             $($(#[$attr])*
             #[inline(always)]
-            pub fn $name(self, key: $K) -> $V {
-                get_query::<queries::$name<'_>, _>(self.tcx, self.span, key)
+            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V {
+                get_query::<queries::$name<'_>, _>(self.tcx, self.span, key.into_query_param())
             })*
         }
 
         define_provider_struct! {
             tcx: $tcx,
-            input: ($(([$($modifiers)*] [$name] [$K] [$V]))*)
+            input: ($(([$($modifiers)*] [$name] [$($K)*] [$V]))*)
         }
 
         impl<$tcx> Copy for Providers<$tcx> {}
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index 081e6f06b33..248a2095d0a 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -2339,43 +2339,41 @@ impl<'tcx> Const<'tcx> {
     /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
     /// unevaluated constant.
     pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
-        let try_const_eval = |did, param_env: ParamEnv<'tcx>, substs, promoted| {
+        if let ConstKind::Unevaluated(did, substs, promoted) = self.val {
             let param_env_and_substs = param_env.with_reveal_all().and(substs);
 
-            // Avoid querying `tcx.const_eval(...)` with any inference vars.
-            if param_env_and_substs.needs_infer() {
-                return None;
-            }
+            // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
+            // also does later, but we want to do it before checking for
+            // inference variables.
+            let param_env_and_substs = tcx.erase_regions(&param_env_and_substs);
+
+            // HACK(eddyb) when the query key would contain inference variables,
+            // attempt using identity substs and `ParamEnv` instead, that will succeed
+            // when the expression doesn't depend on any parameters.
+            // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
+            // we can call `infcx.const_eval_resolve` which handles inference variables.
+            let param_env_and_substs = if param_env_and_substs.needs_infer() {
+                tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did))
+            } else {
+                param_env_and_substs
+            };
 
+            // FIXME(eddyb) maybe the `const_eval_*` methods should take
+            // `ty::ParamEnvAnd<SubstsRef>` instead of having them separate.
             let (param_env, substs) = param_env_and_substs.into_parts();
-
             // try to resolve e.g. associated constants to their definition on an impl, and then
             // evaluate the const.
-            tcx.const_eval_resolve(param_env, did, substs, promoted, None)
-                .ok()
-                .map(|val| Const::from_value(tcx, val, self.ty))
-        };
-
-        match self.val {
-            ConstKind::Unevaluated(did, substs, promoted) => {
-                // HACK(eddyb) when substs contain inference variables,
-                // attempt using identity substs instead, that will succeed
-                // when the expression doesn't depend on any parameters.
-                // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
-                // we can call `infcx.const_eval_resolve` which handles inference variables.
-                if substs.needs_infer() {
-                    let identity_substs = InternalSubsts::identity_for_item(tcx, did);
-                    // The `ParamEnv` needs to match the `identity_substs`.
-                    let identity_param_env = tcx.param_env(did);
-                    match try_const_eval(did, identity_param_env, identity_substs, promoted) {
-                        Some(ct) => ct.subst(tcx, substs),
-                        None => self,
-                    }
-                } else {
-                    try_const_eval(did, param_env, substs, promoted).unwrap_or(self)
-                }
+            match tcx.const_eval_resolve(param_env, did, substs, promoted, None) {
+                // NOTE(eddyb) `val` contains no lifetimes/types/consts,
+                // and we use the original type, so nothing from `substs`
+                // (which may be identity substs, see above),
+                // can leak through `val` into the const we return.
+                Ok(val) => Const::from_value(tcx, val, self.ty),
+
+                Err(_) => self,
             }
-            _ => self,
+        } else {
+            self
         }
     }
 
diff --git a/src/librustc_middle/ty/trait_def.rs b/src/librustc_middle/ty/trait_def.rs
index ed9054fcffd..912f8be1d33 100644
--- a/src/librustc_middle/ty/trait_def.rs
+++ b/src/librustc_middle/ty/trait_def.rs
@@ -193,7 +193,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> &Trai
     let mut impls = TraitImpls::default();
 
     {
-        let mut add_impl = |impl_def_id| {
+        let mut add_impl = |impl_def_id: DefId| {
             let impl_self_ty = tcx.type_of(impl_def_id);
             if impl_def_id.is_local() && impl_self_ty.references_error() {
                 return;
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs
index a118fe2db71..4dc4fb6d8e9 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/mod.rs
@@ -1760,6 +1760,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         }
         for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() {
             let op_arg_ty = op_arg.ty(body, self.tcx());
+            let op_arg_ty = self.normalize(op_arg_ty, term_location);
             let category = if from_hir_call {
                 ConstraintCategory::CallArgument
             } else {
@@ -2402,6 +2403,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
             };
             let operand_ty = operand.ty(body, tcx);
+            let operand_ty = self.normalize(operand_ty, location);
 
             if let Err(terr) = self.sub_types(
                 operand_ty,
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 97cdb32e2cd..3f0774767fd 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -1,7 +1,7 @@
 use super::{error_to_const_error, CompileTimeEvalContext, CompileTimeInterpreter, MemoryExtra};
 use crate::interpret::eval_nullary_intrinsic;
 use crate::interpret::{
-    intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, ImmTy, Immediate, InternKind,
+    intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, Immediate, InternKind,
     InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar,
     ScalarMaybeUndef, StackPopCleanup,
 };
@@ -147,25 +147,28 @@ pub(super) fn op_to_const<'tcx>(
     match immediate {
         Ok(mplace) => to_const_value(mplace),
         // see comment on `let try_as_immediate` above
-        Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x {
-            ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s),
-            ScalarMaybeUndef::Undef => to_const_value(op.assert_mem_place(ecx)),
+        Err(imm) => match *imm {
+            Immediate::Scalar(x) => match x {
+                ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s),
+                ScalarMaybeUndef::Undef => to_const_value(op.assert_mem_place(ecx)),
+            },
+            Immediate::ScalarPair(a, b) => {
+                let (data, start) = match a.not_undef().unwrap() {
+                    Scalar::Ptr(ptr) => {
+                        (ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ptr.offset.bytes())
+                    }
+                    Scalar::Raw { .. } => (
+                        ecx.tcx
+                            .intern_const_alloc(Allocation::from_byte_aligned_bytes(b"" as &[u8])),
+                        0,
+                    ),
+                };
+                let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap();
+                let start = start.try_into().unwrap();
+                let len: usize = len.try_into().unwrap();
+                ConstValue::Slice { data, start, end: start + len }
+            }
         },
-        Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => {
-            let (data, start) = match a.not_undef().unwrap() {
-                Scalar::Ptr(ptr) => {
-                    (ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ptr.offset.bytes())
-                }
-                Scalar::Raw { .. } => (
-                    ecx.tcx.intern_const_alloc(Allocation::from_byte_aligned_bytes(b"" as &[u8])),
-                    0,
-                ),
-            };
-            let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap();
-            let start = start.try_into().unwrap();
-            let len: usize = len.try_into().unwrap();
-            ConstValue::Slice { data, start, end: start + len }
-        }
     }
 }
 
diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs
index e9263471478..e53ca6b31bb 100644
--- a/src/librustc_mir/const_eval/machine.rs
+++ b/src/librustc_mir/const_eval/machine.rs
@@ -13,8 +13,8 @@ use rustc_middle::mir::AssertMessage;
 use rustc_span::symbol::Symbol;
 
 use crate::interpret::{
-    self, AllocId, Allocation, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy,
-    PlaceTy, Pointer, Scalar,
+    self, AllocId, Allocation, Frame, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
+    OpTy, PlaceTy, Pointer, Scalar,
 };
 
 use super::error::*;
@@ -179,9 +179,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
 
     const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory
 
-    // We do not check for alignment to avoid having to carry an `Align`
-    // in `ConstValue::ByRef`.
-    const CHECK_ALIGN: bool = false;
+    #[inline(always)]
+    fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool {
+        // We do not check for alignment to avoid having to carry an `Align`
+        // in `ConstValue::ByRef`.
+        false
+    }
 
     #[inline(always)]
     fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
@@ -339,8 +342,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
     }
 
     #[inline(always)]
-    fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
-        Ok(())
+    fn init_frame_extra(
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        frame: Frame<'mir, 'tcx>,
+    ) -> InterpResult<'tcx, Frame<'mir, 'tcx>> {
+        Ok(frame)
     }
 
     fn before_access_global(
@@ -350,15 +356,30 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
         static_def_id: Option<DefId>,
         is_write: bool,
     ) -> InterpResult<'tcx> {
-        if is_write && allocation.mutability == Mutability::Not {
-            Err(err_ub!(WriteToReadOnly(alloc_id)).into())
-        } else if is_write {
-            Err(ConstEvalErrKind::ModifiedGlobal.into())
-        } else if memory_extra.can_access_statics || static_def_id.is_none() {
-            // `static_def_id.is_none()` indicates this is not a static, but a const or so.
-            Ok(())
+        if is_write {
+            // Write access. These are never allowed, but we give a targeted error message.
+            if allocation.mutability == Mutability::Not {
+                Err(err_ub!(WriteToReadOnly(alloc_id)).into())
+            } else {
+                Err(ConstEvalErrKind::ModifiedGlobal.into())
+            }
         } else {
-            Err(ConstEvalErrKind::ConstAccessesStatic.into())
+            // Read access. These are usually allowed, with some exceptions.
+            if memory_extra.can_access_statics {
+                // Machine configuration allows us read from anything (e.g., `static` initializer).
+                Ok(())
+            } else if static_def_id.is_some() {
+                // Machine configuration does not allow us to read statics
+                // (e.g., `const` initializer).
+                Err(ConstEvalErrKind::ConstAccessesStatic.into())
+            } else {
+                // Immutable global, this read is fine.
+                // But make sure we never accept a read from something mutable, that would be
+                // unsound. The reason is that as the content of this allocation may be different
+                // now and at run-time, so if we permit reading now we might return the wrong value.
+                assert_eq!(allocation.mutability, Mutability::Not);
+                Ok(())
+            }
         }
     }
 }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index e0b5f634bf3..f111eecb945 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -159,6 +159,21 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
     }
 }
 
+impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
+    pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'mir, 'tcx, Tag, Extra> {
+        Frame {
+            body: self.body,
+            instance: self.instance,
+            return_to_block: self.return_to_block,
+            return_place: self.return_place,
+            locals: self.locals,
+            block: self.block,
+            stmt: self.stmt,
+            extra,
+        }
+    }
+}
+
 impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> {
     /// Return the `SourceInfo` of the current instruction.
     pub fn current_source_info(&self) -> Option<mir::SourceInfo> {
@@ -586,8 +601,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         ::log_settings::settings().indentation += 1;
 
         // first push a stack frame so we have access to the local substs
-        let extra = M::stack_push(self)?;
-        self.stack.push(Frame {
+        let pre_frame = Frame {
             body,
             block: Some(mir::START_BLOCK),
             return_to_block,
@@ -597,8 +611,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             locals: IndexVec::new(),
             instance,
             stmt: 0,
-            extra,
-        });
+            extra: (),
+        };
+        let frame = M::init_frame_extra(self, pre_frame)?;
+        self.stack.push(frame);
 
         // don't allocate at all for trivial constants
         if body.local_decls.len() > 1 {
@@ -630,6 +646,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             self.frame_mut().locals = locals;
         }
 
+        M::after_stack_push(self)?;
         info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
 
         if self.stack.len() > *self.tcx.sess.recursion_limit.get() {
@@ -725,16 +742,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
 
         // Cleanup: deallocate all locals that are backed by an allocation.
-        for local in frame.locals {
+        for local in &frame.locals {
             self.deallocate_local(local.value)?;
         }
 
-        if M::stack_pop(self, frame.extra, unwinding)? == StackPopJump::NoJump {
+        let return_place = frame.return_place;
+        if M::after_stack_pop(self, frame, unwinding)? == StackPopJump::NoJump {
             // The hook already did everything.
             // We want to skip the `info!` below, hence early return.
             return Ok(());
         }
-        // Normal return.
+        // Normal return, figure out where to jump.
         if unwinding {
             // Follow the unwind edge.
             let unwind = next_block.expect("Encountered StackPopCleanup::None when unwinding!");
@@ -743,7 +761,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // Follow the normal return edge.
             // Validate the return value. Do this after deallocating so that we catch dangling
             // references.
-            if let Some(return_place) = frame.return_place {
+            if let Some(return_place) = return_place {
                 if M::enforce_validity(self) {
                     // Data got changed, better make sure it matches the type!
                     // It is still possible that the return place held invalid data while
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index fd67b088c93..8bf8d904cb2 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -118,7 +118,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
     const GLOBAL_KIND: Option<Self::MemoryKind>;
 
     /// Whether memory accesses should be alignment-checked.
-    const CHECK_ALIGN: bool;
+    fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool;
 
     /// Whether to enforce the validity invariant
     fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
@@ -279,13 +279,21 @@ pub trait Machine<'mir, 'tcx>: Sized {
         Ok(())
     }
 
-    /// Called immediately before a new stack frame got pushed.
-    fn stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>;
+    /// Called immediately before a new stack frame gets pushed.
+    fn init_frame_extra(
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        frame: Frame<'mir, 'tcx, Self::PointerTag>,
+    ) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>>;
+
+    /// Called immediately after a stack frame got pushed and its locals got initialized.
+    fn after_stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
+        Ok(())
+    }
 
-    /// Called immediately after a stack frame gets popped
-    fn stack_pop(
+    /// Called immediately after a stack frame got popped, but before jumping back to the caller.
+    fn after_stack_pop(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        _extra: Self::FrameExtra,
+        _frame: Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>,
         _unwinding: bool,
     ) -> InterpResult<'tcx, StackPopJump> {
         // By default, we do not support unwinding from panics
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 539537e9de8..bcad7855c37 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -323,12 +323,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         size: Size,
         align: Align,
     ) -> InterpResult<'tcx, Option<Pointer<M::PointerTag>>> {
-        let align = M::CHECK_ALIGN.then_some(align);
+        let align = M::enforce_alignment(&self.extra).then_some(align);
         self.check_ptr_access_align(sptr, size, align, CheckInAllocMsg::MemoryAccessTest)
     }
 
     /// Like `check_ptr_access`, but *definitely* checks alignment when `align`
-    /// is `Some` (overriding `M::CHECK_ALIGN`). Also lets the caller control
+    /// is `Some` (overriding `M::enforce_alignment`). Also lets the caller control
     /// the error message for the out-of-bounds case.
     pub fn check_ptr_access_align(
         &self,
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 3741f31927e..893f4c1db7e 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -87,7 +87,7 @@ impl<'tcx, Tag> Immediate<Tag> {
 // as input for binary and cast operations.
 #[derive(Copy, Clone, Debug)]
 pub struct ImmTy<'tcx, Tag = ()> {
-    pub(crate) imm: Immediate<Tag>,
+    imm: Immediate<Tag>,
     pub layout: TyAndLayout<'tcx>,
 }
 
@@ -184,6 +184,11 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
     }
 
     #[inline]
+    pub fn from_immediate(imm: Immediate<Tag>, layout: TyAndLayout<'tcx>) -> Self {
+        ImmTy { imm, layout }
+    }
+
+    #[inline]
     pub fn try_from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Option<Self> {
         Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout))
     }
@@ -424,7 +429,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         Ok(OpTy { op, layout })
     }
 
-    /// Every place can be read from, so we can turn them into an operand
+    /// Every place can be read from, so we can turn them into an operand.
+    /// This will definitely return `Indirect` if the place is a `Ptr`, i.e., this
+    /// will never actually read from memory.
     #[inline(always)]
     pub fn place_to_op(
         &self,
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 828df9a0930..9ac4b3551fc 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -247,7 +247,7 @@ impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> {
             Operand::Immediate(_) if self.layout.is_zst() => {
                 Ok(MPlaceTy::dangling(self.layout, cx))
             }
-            Operand::Immediate(imm) => Err(ImmTy { imm, layout: self.layout }),
+            Operand::Immediate(imm) => Err(ImmTy::from_immediate(imm, self.layout)),
         }
     }
 
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 2d8551b2bbf..49fee1bddcb 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -407,7 +407,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0)?;
                 // Adjust receiver argument.
                 args[0] =
-                    OpTy::from(ImmTy { layout: this_receiver_ptr, imm: receiver_place.ptr.into() });
+                    OpTy::from(ImmTy::from_immediate(receiver_place.ptr.into(), this_receiver_ptr));
                 trace!("Patched self operand to {:#?}", args[0]);
                 // recurse with concrete function
                 self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind)
@@ -436,10 +436,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             _ => (instance, place),
         };
 
-        let arg = ImmTy {
-            imm: place.to_ref(),
-            layout: self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?,
-        };
+        let arg = ImmTy::from_immediate(
+            place.to_ref(),
+            self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?,
+        );
 
         let ty = self.tcx.mk_unit(); // return type is ()
         let dest = MPlaceTy::dangling(self.layout_of(ty)?, self);
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 67de81ed77b..e1473cbfb63 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -74,7 +74,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
             let call_mut = tcx
                 .associated_items(fn_mut)
                 .in_definition_order()
-                .find(|it| it.kind == ty::AssocKind::Method)
+                .find(|it| it.kind == ty::AssocKind::Fn)
                 .unwrap()
                 .def_id;
 
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index 5c016b0c515..d0de0a09873 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -58,10 +58,14 @@ fn may_be_reference(ty: Ty<'tcx>) -> bool {
 }
 
 impl<'tcx> MirPass<'tcx> for AddRetag {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) {
         if !tcx.sess.opts.debugging_opts.mir_emit_retag {
             return;
         }
+
+        // We need an `AllCallEdges` pass before we can do any work.
+        super::add_call_guards::AllCallEdges.run_pass(tcx, src, body);
+
         let (span, arg_count) = (body.span, body.arg_count);
         let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
         let needs_retag = |place: &Place<'tcx>| {
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 5a00f206a76..cf1c70241bc 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -173,7 +173,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
 
     const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory
 
-    const CHECK_ALIGN: bool = false;
+    #[inline(always)]
+    fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool {
+        false
+    }
 
     #[inline(always)]
     fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
@@ -287,8 +290,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
     }
 
     #[inline(always)]
-    fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
-        Ok(())
+    fn init_frame_extra(
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        frame: Frame<'mir, 'tcx>,
+    ) -> InterpResult<'tcx, Frame<'mir, 'tcx>> {
+        Ok(frame)
     }
 }
 
@@ -575,11 +581,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             return None;
         }
 
-        // FIXME we need to revisit this for #67176
-        if rvalue.needs_subst() {
-            return None;
-        }
-
         // Perform any special handling for specific Rvalue types.
         // Generally, checks here fall into one of two categories:
         //   1. Additional checking to provide useful lints to the user
@@ -620,6 +621,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             _ => {}
         }
 
+        // FIXME we need to revisit this for #67176
+        if rvalue.needs_subst() {
+            return None;
+        }
+
         self.use_ecx(|this| {
             trace!("calling eval_rvalue_into_place(rvalue = {:?}, place = {:?})", rvalue, place);
             this.ecx.eval_rvalue_into_place(rvalue, place)?;
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 81ea57e4c00..8db0b39a497 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -287,10 +287,8 @@ fn run_optimization_passes<'tcx>(
             // AddMovesForPackedDrops needs to run after drop
             // elaboration.
             &add_moves_for_packed_drops::AddMovesForPackedDrops,
-            // AddRetag needs to run after ElaborateDrops, and it needs
-            // an AllCallEdges pass right before it.  Otherwise it should
-            // run fairly late, but before optimizations begin.
-            &add_call_guards::AllCallEdges,
+            // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
+            // but before optimizations begin.
             &add_retag::AddRetag,
             &simplify::SimplifyCfg::new("elaborate-drops"),
             // No lifetime analysis based on borrowing can be done from here on out.
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 9579fe1f405..71c2e3bf060 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -835,7 +835,11 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                     if self.keep_original {
                         rhs.clone()
                     } else {
-                        let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]);
+                        let unit = Rvalue::Use(Operand::Constant(box Constant {
+                            span: statement.source_info.span,
+                            user_ty: None,
+                            literal: ty::Const::zero_sized(self.tcx, self.tcx.types.unit),
+                        }));
                         mem::replace(rhs, unit)
                     },
                     statement.source_info,
diff --git a/src/librustc_mir_build/build/block.rs b/src/librustc_mir_build/build/block.rs
index 8c41554bc85..4e8d5e04a63 100644
--- a/src/librustc_mir_build/build/block.rs
+++ b/src/librustc_mir_build/build/block.rs
@@ -187,7 +187,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             if destination_ty.is_unit() {
                 // We only want to assign an implicit `()` as the return value of the block if the
                 // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
-                this.cfg.push_assign_unit(block, source_info, destination);
+                this.cfg.push_assign_unit(block, source_info, destination, this.hir.tcx());
             }
         }
         // Finally, we pop all the let scopes before exiting out from the scope of block
diff --git a/src/librustc_mir_build/build/cfg.rs b/src/librustc_mir_build/build/cfg.rs
index f5828c4ac1f..42e2b242d77 100644
--- a/src/librustc_mir_build/build/cfg.rs
+++ b/src/librustc_mir_build/build/cfg.rs
@@ -2,6 +2,7 @@
 
 use crate::build::CFG;
 use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 
 impl<'tcx> CFG<'tcx> {
     crate fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
@@ -58,12 +59,17 @@ impl<'tcx> CFG<'tcx> {
         block: BasicBlock,
         source_info: SourceInfo,
         place: Place<'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) {
         self.push_assign(
             block,
             source_info,
             place,
-            Rvalue::Aggregate(box AggregateKind::Tuple, vec![]),
+            Rvalue::Use(Operand::Constant(box Constant {
+                span: source_info.span,
+                user_ty: None,
+                literal: ty::Const::zero_sized(tcx, tcx.types.unit),
+            })),
         );
     }
 
diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs
index 20ef763e90c..b6f46aab416 100644
--- a/src/librustc_mir_build/build/expr/as_rvalue.rs
+++ b/src/librustc_mir_build/build/expr/as_rvalue.rs
@@ -225,7 +225,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
                 block = unpack!(this.stmt_expr(block, expr, None));
-                block.and(this.unit_rvalue())
+                block.and(Rvalue::Use(Operand::Constant(box Constant {
+                    span: expr_span,
+                    user_ty: None,
+                    literal: ty::Const::zero_sized(this.hir.tcx(), this.hir.tcx().types.unit),
+                })))
             }
             ExprKind::Yield { .. }
             | ExprKind::Literal { .. }
diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs
index 6b93755e9da..cd5bb738aed 100644
--- a/src/librustc_mir_build/build/expr/into.rs
+++ b/src/librustc_mir_build/build/expr/into.rs
@@ -331,7 +331,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::LlvmInlineAsm { .. }
             | ExprKind::Return { .. } => {
                 unpack!(block = this.stmt_expr(block, expr, None));
-                this.cfg.push_assign_unit(block, source_info, destination);
+                this.cfg.push_assign_unit(block, source_info, destination, this.hir.tcx());
                 block.unit()
             }
 
diff --git a/src/librustc_mir_build/build/misc.rs b/src/librustc_mir_build/build/misc.rs
index 8f98dd9b70e..578b862b905 100644
--- a/src/librustc_mir_build/build/misc.rs
+++ b/src/librustc_mir_build/build/misc.rs
@@ -32,10 +32,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         Operand::Constant(constant)
     }
 
-    crate fn unit_rvalue(&mut self) -> Rvalue<'tcx> {
-        Rvalue::Aggregate(box AggregateKind::Tuple, vec![])
-    }
-
     // Returns a zero literal operand for the appropriate type, works for
     // bool, char and integers.
     crate fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
diff --git a/src/librustc_mir_build/build/scope.rs b/src/librustc_mir_build/build/scope.rs
index 3689e5cb9d8..d88cbf94513 100644
--- a/src/librustc_mir_build/build/scope.rs
+++ b/src/librustc_mir_build/build/scope.rs
@@ -523,7 +523,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 unpack!(block = self.into(destination, block, value));
                 self.block_context.pop();
             } else {
-                self.cfg.push_assign_unit(block, source_info, destination)
+                self.cfg.push_assign_unit(block, source_info, destination, self.hir.tcx())
             }
         } else {
             assert!(value.is_none(), "`return` and `break` should have a destination");
diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs
index 21d632b9f6b..d2d99cf030d 100644
--- a/src/librustc_mir_build/hair/cx/expr.rs
+++ b/src/librustc_mir_build/hair/cx/expr.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
 };
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
-use rustc_middle::ty::{self, AdtKind, Ty};
+use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable};
 use rustc_span::Span;
 
 impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr<'tcx> {
@@ -718,8 +718,7 @@ fn convert_path_expr<'a, 'tcx>(
 
         Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
             let user_provided_types = cx.tables.user_provided_types();
-            let user_provided_type = user_provided_types.get(expr.hir_id).copied();
-            debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
+            let user_ty = user_provided_types.get(expr.hir_id).copied();
             let ty = cx.tables().node_type(expr.hir_id);
             match ty.kind {
                 // A unit struct/variant which is used as a value.
@@ -728,10 +727,17 @@ fn convert_path_expr<'a, 'tcx>(
                     adt_def,
                     variant_index: adt_def.variant_index_with_ctor_id(def_id),
                     substs,
-                    user_ty: user_provided_type,
+                    user_ty,
                     fields: vec![],
                     base: None,
                 },
+                _ if ty.references_error() => {
+                    // Handle degenerate input without ICE (#67377).
+                    ExprKind::Literal {
+                        literal: ty::Const::zero_sized(cx.tcx, cx.tcx.types.err),
+                        user_ty: None,
+                    }
+                }
                 _ => bug!("unexpected ty: {:?}", ty),
             }
         }
diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs
index 503bd26d51f..18a981dfea1 100644
--- a/src/librustc_mir_build/hair/cx/mod.rs
+++ b/src/librustc_mir_build/hair/cx/mod.rs
@@ -176,7 +176,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
             .tcx
             .associated_items(trait_def_id)
             .filter_by_name_unhygienic(method_name)
-            .find(|item| item.kind == ty::AssocKind::Method)
+            .find(|item| item.kind == ty::AssocKind::Fn)
             .expect("trait method not found");
 
         let method_ty = self.tcx.type_of(item.def_id);
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index cbff99f8da6..4e3c5fa63de 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -1846,11 +1846,9 @@ impl<'a> Parser<'a> {
     }
 
     fn is_try_block(&self) -> bool {
-        self.token.is_keyword(kw::Try) &&
-        self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
-        self.token.uninterpolated_span().rust_2018() &&
-        // Prevent `while try {} {}`, `if try {} {} else {}`, etc.
-        !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
+        self.token.is_keyword(kw::Try)
+            && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
+            && self.token.uninterpolated_span().rust_2018()
     }
 
     /// Parses an `async move? {...}` expression.
diff --git a/src/librustc_passes/hir_id_validator.rs b/src/librustc_passes/hir_id_validator.rs
index f5611654fc0..1e31b7c74b6 100644
--- a/src/librustc_passes/hir_id_validator.rs
+++ b/src/librustc_passes/hir_id_validator.rs
@@ -143,16 +143,6 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
     fn visit_id(&mut self, hir_id: HirId) {
         let owner = self.owner.expect("no owner");
 
-        if hir_id == hir::DUMMY_HIR_ID {
-            self.error(|| {
-                format!(
-                    "HirIdValidator: HirId {:?} is invalid",
-                    self.hir_map.node_to_string(hir_id)
-                )
-            });
-            return;
-        }
-
         if owner != hir_id.owner {
             self.error(|| {
                 format!(
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index a6d880667ad..51e1588c71c 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -928,7 +928,12 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
 
         let macro_module_def_id =
             ty::DefIdTree::parent(self.tcx, self.tcx.hir().local_def_id(md.hir_id)).unwrap();
-        let mut module_id = match self.tcx.hir().as_local_hir_id(macro_module_def_id) {
+        // FIXME(#71104) Should really be using just `as_local_hir_id` but
+        // some `DefId` do not seem to have a corresponding HirId.
+        let hir_id = macro_module_def_id
+            .as_local()
+            .and_then(|def_id| self.tcx.hir().opt_local_def_id_to_hir_id(def_id));
+        let mut module_id = match hir_id {
             Some(module_id) if self.tcx.hir().is_hir_id_module(module_id) => module_id,
             // `module_id` doesn't correspond to a `mod`, return early (#63164, #65252).
             _ => return,
@@ -1012,7 +1017,7 @@ impl DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
 struct NamePrivacyVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
-    current_item: hir::HirId,
+    current_item: Option<hir::HirId>,
     empty_tables: &'a ty::TypeckTables<'tcx>,
 }
 
@@ -1028,7 +1033,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
     ) {
         // definition of the field
         let ident = Ident::new(kw::Invalid, use_ctxt);
-        let current_hir = self.current_item;
+        let current_hir = self.current_item.unwrap();
         let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, current_hir).1;
         if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
             let label = if in_update_syntax {
@@ -1074,7 +1079,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        let orig_current_item = mem::replace(&mut self.current_item, item.hir_id);
+        let orig_current_item = mem::replace(&mut self.current_item, Some(item.hir_id));
         let orig_tables =
             mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables));
         intravisit::walk_item(self, item);
@@ -1648,7 +1653,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                                     found_pub_static = true;
                                     intravisit::walk_impl_item(self, impl_item);
                                 }
-                                AssocItemKind::Method { has_self: false } => {
+                                AssocItemKind::Fn { has_self: false } => {
                                     found_pub_static = true;
                                     intravisit::walk_impl_item(self, impl_item);
                                 }
@@ -1927,7 +1932,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
         let mut check = self.check(hir_id, vis);
 
         let (check_ty, is_assoc_ty) = match assoc_item_kind {
-            AssocItemKind::Const | AssocItemKind::Method { .. } => (true, false),
+            AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
             AssocItemKind::Type => (defaultness.has_value(), true),
             // `ty()` for opaque types is the underlying type,
             // it's not a part of interface, so we skip it.
@@ -2059,7 +2064,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: DefId) {
     let mut visitor = NamePrivacyVisitor {
         tcx,
         tables: &empty_tables,
-        current_item: hir::DUMMY_HIR_ID,
+        current_item: None,
         empty_tables: &empty_tables,
     };
     let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 0ad33f1a120..7e5415d000e 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -921,7 +921,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
             Res::Def(DefKind::AssocFn, def_id) => {
                 if cstore
                     .associated_item_cloned_untracked(def_id, self.r.session)
-                    .method_has_self_argument
+                    .fn_has_self_parameter
                 {
                     self.r.has_self.insert(def_id);
                 }
diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs
index 71ff9e5cbed..5bfb5aa2440 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/src/librustc_resolve/late/lifetimes.rs
@@ -2117,7 +2117,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         };
 
         let has_self = match assoc_item_kind {
-            Some(hir::AssocItemKind::Method { has_self }) => has_self,
+            Some(hir::AssocItemKind::Fn { has_self }) => has_self,
             _ => false,
         };
 
@@ -2704,14 +2704,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
     }
 
     fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
-        if lifetime_ref.hir_id == hir::DUMMY_HIR_ID {
-            span_bug!(
-                lifetime_ref.span,
-                "lifetime reference not renumbered, \
-                 probably a bug in rustc_ast::fold"
-            );
-        }
-
         debug!(
             "insert_lifetime: {} resolved to {:?} span={:?}",
             self.tcx.hir().node_to_string(lifetime_ref.hir_id),
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 5b93c73e07c..ba2541bc6c3 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -225,11 +225,14 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
             collector.visit_pat(&arg.pat);
 
             for (id, ident, ..) in collector.collected_idents {
-                let hir_id = self.tcx.hir().node_id_to_hir_id(id);
-                let typ = match self.save_ctxt.tables.node_type_opt(hir_id) {
-                    Some(s) => s.to_string(),
-                    None => continue,
-                };
+                // FIXME(#71104) Should really be using just `node_id_to_hir_id` but
+                // some `NodeId` do not seem to have a corresponding HirId.
+                let hir_id = self.tcx.hir().opt_node_id_to_hir_id(id);
+                let typ =
+                    match hir_id.and_then(|hir_id| self.save_ctxt.tables.node_type_opt(hir_id)) {
+                        Some(s) => s.to_string(),
+                        None => continue,
+                    };
                 if !self.span.filter_generated(ident.span) {
                     let id = id_from_node_id(id, &self.save_ctxt);
                     let span = self.span_from_span(ident.span);
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index 4c963ac84dc..1575e6fd533 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -348,6 +348,7 @@ symbols! {
         generators,
         generic_associated_types,
         generic_param_attrs,
+        get_context,
         global_allocator,
         global_asm,
         globs,
@@ -547,8 +548,8 @@ symbols! {
         plugin,
         plugin_registrar,
         plugins,
+        poll,
         Poll,
-        poll_with_context,
         powerpc_target_feature,
         precise_pointer_size_matching,
         pref_align_of,
diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/src/librustc_target/spec/armebv7r_none_eabi.rs
index 3a5957892b5..ebe901e4f27 100644
--- a/src/librustc_target/spec/armebv7r_none_eabi.rs
+++ b/src/librustc_target/spec/armebv7r_none_eabi.rs
@@ -1,7 +1,6 @@
 // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R)
 
 use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
-use std::default::Default;
 
 pub fn target() -> TargetResult {
     Ok(Target {
diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/src/librustc_target/spec/armebv7r_none_eabihf.rs
index 9f95a1a6f44..8652d1051ad 100644
--- a/src/librustc_target/spec/armebv7r_none_eabihf.rs
+++ b/src/librustc_target/spec/armebv7r_none_eabihf.rs
@@ -1,7 +1,6 @@
 // Targets the Cortex-R4F/R5F processor (ARMv7-R)
 
 use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
-use std::default::Default;
 
 pub fn target() -> TargetResult {
     Ok(Target {
diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/src/librustc_target/spec/armv7r_none_eabi.rs
index 517368e6a23..b7fcda63db0 100644
--- a/src/librustc_target/spec/armv7r_none_eabi.rs
+++ b/src/librustc_target/spec/armv7r_none_eabi.rs
@@ -1,7 +1,6 @@
 // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R)
 
 use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
-use std::default::Default;
 
 pub fn target() -> TargetResult {
     Ok(Target {
diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/src/librustc_target/spec/armv7r_none_eabihf.rs
index 6363469d929..340090fd43b 100644
--- a/src/librustc_target/spec/armv7r_none_eabihf.rs
+++ b/src/librustc_target/spec/armv7r_none_eabihf.rs
@@ -1,7 +1,6 @@
 // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R)
 
 use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
-use std::default::Default;
 
 pub fn target() -> TargetResult {
     Ok(Target {
diff --git a/src/librustc_target/spec/dragonfly_base.rs b/src/librustc_target/spec/dragonfly_base.rs
index e26d0ae50b2..c7062e1ca51 100644
--- a/src/librustc_target/spec/dragonfly_base.rs
+++ b/src/librustc_target/spec/dragonfly_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut args = LinkArgs::new();
diff --git a/src/librustc_target/spec/freebsd_base.rs b/src/librustc_target/spec/freebsd_base.rs
index fc252b6d43d..d2a087ab62f 100644
--- a/src/librustc_target/spec/freebsd_base.rs
+++ b/src/librustc_target/spec/freebsd_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut args = LinkArgs::new();
diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs
index 046388e9be8..4060b126cdd 100644
--- a/src/librustc_target/spec/fuchsia_base.rs
+++ b/src/librustc_target/spec/fuchsia_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut pre_link_args = LinkArgs::new();
diff --git a/src/librustc_target/spec/haiku_base.rs b/src/librustc_target/spec/haiku_base.rs
index 1ddab7be180..3d7ae6c302d 100644
--- a/src/librustc_target/spec/haiku_base.rs
+++ b/src/librustc_target/spec/haiku_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
diff --git a/src/librustc_target/spec/hermit_base.rs b/src/librustc_target/spec/hermit_base.rs
index 3f9dad689fd..b9f94023e7a 100644
--- a/src/librustc_target/spec/hermit_base.rs
+++ b/src/librustc_target/spec/hermit_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut pre_link_args = LinkArgs::new();
diff --git a/src/librustc_target/spec/hermit_kernel_base.rs b/src/librustc_target/spec/hermit_kernel_base.rs
index 650219c21ac..1f9b195e2e6 100644
--- a/src/librustc_target/spec/hermit_kernel_base.rs
+++ b/src/librustc_target/spec/hermit_kernel_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut pre_link_args = LinkArgs::new();
diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/src/librustc_target/spec/i686_pc_windows_gnu.rs
index 2091902d7ce..d12afe5a40b 100644
--- a/src/librustc_target/spec/i686_pc_windows_gnu.rs
+++ b/src/librustc_target/spec/i686_pc_windows_gnu.rs
@@ -1,7 +1,7 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
-    let mut base = super::windows_base::opts();
+    let mut base = super::windows_gnu_base::opts();
     base.cpu = "pentium4".to_string();
     base.max_atomic_width = Some(64);
     base.eliminate_frame_pointer = false; // Required for backtraces
diff --git a/src/librustc_target/spec/i686_pc_windows_msvc.rs b/src/librustc_target/spec/i686_pc_windows_msvc.rs
index ffb66afc761..9d0922b8ce5 100644
--- a/src/librustc_target/spec/i686_pc_windows_msvc.rs
+++ b/src/librustc_target/spec/i686_pc_windows_msvc.rs
@@ -1,18 +1,24 @@
-use crate::spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_msvc_base::opts();
     base.cpu = "pentium4".to_string();
     base.max_atomic_width = Some(64);
 
-    // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
-    // space available to x86 Windows binaries on x86_64.
-    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/LARGEADDRESSAWARE".to_string());
-
-    // Ensure the linker will only produce an image if it can also produce a table of
-    // the image's safe exception handlers.
-    // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
-    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/SAFESEH".to_string());
+    let pre_link_args_msvc = vec![
+        // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
+        // space available to x86 Windows binaries on x86_64.
+        "/LARGEADDRESSAWARE".to_string(),
+        // Ensure the linker will only produce an image if it can also produce a table of
+        // the image's safe exception handlers.
+        // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers
+        "/SAFESEH".to_string(),
+    ];
+    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone());
+    base.pre_link_args
+        .get_mut(&LinkerFlavor::Lld(LldFlavor::Link))
+        .unwrap()
+        .extend(pre_link_args_msvc);
 
     Ok(Target {
         llvm_target: "i686-pc-windows-msvc".to_string(),
diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/src/librustc_target/spec/i686_unknown_uefi.rs
index e299f92fdeb..221d5f0785c 100644
--- a/src/librustc_target/spec/i686_unknown_uefi.rs
+++ b/src/librustc_target/spec/i686_unknown_uefi.rs
@@ -8,7 +8,7 @@
 use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
-    let mut base = super::uefi_base::opts();
+    let mut base = super::uefi_msvc_base::opts();
     base.cpu = "pentium4".to_string();
     base.max_atomic_width = Some(64);
 
@@ -23,11 +23,6 @@ pub fn target() -> TargetResult {
     // arguments, thus giving you access to full MMX/SSE acceleration.
     base.features = "-mmx,-sse,+soft-float".to_string();
 
-    // UEFI mirrors the calling-conventions used on windows. In case of i686 this means small
-    // structs will be returned as int. This shouldn't matter much, since the restrictions placed
-    // by the UEFI specifications forbid any ABI to return structures.
-    base.abi_return_struct_as_int = true;
-
     // Use -GNU here, because of the reason below:
     // Background and Problem:
     //   If we use i686-unknown-windows, the LLVM IA32 MSVC generates compiler intrinsic
diff --git a/src/librustc_target/spec/i686_uwp_windows_gnu.rs b/src/librustc_target/spec/i686_uwp_windows_gnu.rs
index 93f396de0a0..4e582fb8c63 100644
--- a/src/librustc_target/spec/i686_uwp_windows_gnu.rs
+++ b/src/librustc_target/spec/i686_uwp_windows_gnu.rs
@@ -1,7 +1,7 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
-    let mut base = super::windows_uwp_base::opts();
+    let mut base = super::windows_uwp_gnu_base::opts();
     base.cpu = "pentium4".to_string();
     base.max_atomic_width = Some(64);
     base.eliminate_frame_pointer = false; // Required for backtraces
diff --git a/src/librustc_target/spec/illumos_base.rs b/src/librustc_target/spec/illumos_base.rs
new file mode 100644
index 00000000000..35ac346fb3f
--- /dev/null
+++ b/src/librustc_target/spec/illumos_base.rs
@@ -0,0 +1,48 @@
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut late_link_args = LinkArgs::new();
+    late_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec![
+            // LLVM will insert calls to the stack protector functions
+            // "__stack_chk_fail" and "__stack_chk_guard" into code in native
+            // object files.  Some platforms include these symbols directly in
+            // libc, but at least historically these have been provided in
+            // libssp.so on illumos and Solaris systems.
+            "-lssp".to_string(),
+        ],
+    );
+
+    TargetOptions {
+        dynamic_linking: true,
+        executables: true,
+        has_rpath: true,
+        target_family: Some("unix".to_string()),
+        is_like_solaris: true,
+        limit_rdylib_exports: false, // Linker doesn't support this
+        eliminate_frame_pointer: false,
+        late_link_args,
+
+        // While we support ELF TLS, rust requires a way to register
+        // cleanup handlers (in C, this would be something along the lines of:
+        // void register_callback(void (*fn)(void *), void *arg);
+        // (see src/libstd/sys/unix/fast_thread_local.rs) that is currently
+        // missing in illumos.  For now at least, we must fallback to using
+        // pthread_{get,set}specific.
+        //has_elf_tls: true,
+
+        // FIXME: Currently, rust is invoking cc to link, which ends up
+        // causing these to get included twice.  We should eventually transition
+        // to having rustc invoke ld directly, in which case these will need to
+        // be uncommented.
+        //
+        // We want XPG6 behavior from libc and libm.  See standards(5)
+        //pre_link_objects_exe: vec![
+        //    "/usr/lib/amd64/values-Xc.o".to_string(),
+        //    "/usr/lib/amd64/values-xpg6.o".to_string(),
+        //],
+        ..Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/l4re_base.rs b/src/librustc_target/spec/l4re_base.rs
index b712dcae899..5caad10161d 100644
--- a/src/librustc_target/spec/l4re_base.rs
+++ b/src/librustc_target/spec/l4re_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
-use std::default::Default;
 //use std::process::Command;
 
 // Use GCC to locate code for crt* libraries from the host, not from L4Re. Note
diff --git a/src/librustc_target/spec/linux_base.rs b/src/librustc_target/spec/linux_base.rs
index a5d7f8e07c4..52892fc3592 100644
--- a/src/librustc_target/spec/linux_base.rs
+++ b/src/librustc_target/spec/linux_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut args = LinkArgs::new();
diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/src/librustc_target/spec/linux_kernel_base.rs
index fae44836fa8..4a900d1b02c 100644
--- a/src/librustc_target/spec/linux_kernel_base.rs
+++ b/src/librustc_target/spec/linux_kernel_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut pre_link_args = LinkArgs::new();
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 1bc2bf12fad..8f3097ad423 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -37,7 +37,6 @@
 use crate::spec::abi::{lookup as lookup_abi, Abi};
 use rustc_serialize::json::{Json, ToJson};
 use std::collections::BTreeMap;
-use std::default::Default;
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use std::{fmt, io};
@@ -56,22 +55,24 @@ mod fuchsia_base;
 mod haiku_base;
 mod hermit_base;
 mod hermit_kernel_base;
+mod illumos_base;
 mod l4re_base;
 mod linux_base;
 mod linux_kernel_base;
 mod linux_musl_base;
+mod msvc_base;
 mod netbsd_base;
 mod openbsd_base;
 mod redox_base;
 mod riscv_base;
 mod solaris_base;
 mod thumb_base;
-mod uefi_base;
+mod uefi_msvc_base;
 mod vxworks_base;
 mod wasm32_base;
-mod windows_base;
+mod windows_gnu_base;
 mod windows_msvc_base;
-mod windows_uwp_base;
+mod windows_uwp_gnu_base;
 mod windows_uwp_msvc_base;
 
 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@@ -309,23 +310,14 @@ macro_rules! supported_targets {
         }
 
         #[cfg(test)]
-        mod test_json_encode_decode {
-            use rustc_serialize::json::ToJson;
-            use super::Target;
-            $(use super::$module;)+
+        mod tests {
+            mod tests_impl;
 
+            // Cannot put this into a separate file without duplication, make an exception.
             $(
-                #[test] // `#[test]` - this is hard to put into a separate file, make an exception
+                #[test] // `#[test]`
                 fn $module() {
-                    // Grab the TargetResult struct. If we successfully retrieved
-                    // a Target, then the test JSON encoding/decoding can run for this
-                    // Target on this testing platform (i.e., checking the iOS targets
-                    // only on a Mac test platform).
-                    let _ = $module::target().map(|original| {
-                        let as_json = original.to_json();
-                        let parsed = Target::from_json(as_json).unwrap();
-                        assert_eq!(original, parsed);
-                    });
+                    tests_impl::test_target(super::$module::target());
                 }
             )+
         }
@@ -447,6 +439,8 @@ supported_targets! {
     ("x86_64-sun-solaris", "x86_64-pc-solaris", x86_64_sun_solaris),
     ("sparcv9-sun-solaris", sparcv9_sun_solaris),
 
+    ("x86_64-unknown-illumos", x86_64_unknown_illumos),
+
     ("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu),
     ("i686-pc-windows-gnu", i686_pc_windows_gnu),
     ("i686-uwp-windows-gnu", i686_uwp_windows_gnu),
@@ -538,7 +532,8 @@ pub struct Target {
     pub arch: String,
     /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
     pub data_layout: String,
-    /// Linker flavor
+    /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
+    /// on the command line.
     pub linker_flavor: LinkerFlavor,
     /// Optional settings with defaults.
     pub options: TargetOptions,
@@ -566,7 +561,8 @@ pub struct TargetOptions {
     /// Linker to invoke
     pub linker: Option<String>,
 
-    /// LLD flavor
+    /// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker
+    /// without clarifying its flavor in any way.
     pub lld_flavor: LldFlavor,
 
     /// Linker arguments that are passed *before* any user-defined libraries.
diff --git a/src/librustc_target/spec/msvc_base.rs b/src/librustc_target/spec/msvc_base.rs
new file mode 100644
index 00000000000..817a322a9e4
--- /dev/null
+++ b/src/librustc_target/spec/msvc_base.rs
@@ -0,0 +1,35 @@
+use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
+
+pub fn opts() -> TargetOptions {
+    let pre_link_args_msvc = vec![
+        // Suppress the verbose logo and authorship debugging output, which would needlessly
+        // clog any log files.
+        "/NOLOGO".to_string(),
+        // Tell the compiler that non-code sections can be marked as non-executable,
+        // including stack pages.
+        // UEFI is fully compatible to non-executable data pages.
+        // In fact, firmware might enforce this, so we better let the linker know about this,
+        // so it will fail if the compiler ever tries placing code on the stack
+        // (e.g., trampoline constructs and alike).
+        "/NXCOMPAT".to_string(),
+    ];
+    let mut pre_link_args = LinkArgs::new();
+    pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone());
+    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc);
+
+    TargetOptions {
+        executables: true,
+        is_like_windows: true,
+        is_like_msvc: true,
+        // set VSLANG to 1033 can prevent link.exe from using
+        // language packs, and avoid generating Non-UTF-8 error
+        // messages if a link error occurred.
+        link_env: vec![("VSLANG".to_string(), "1033".to_string())],
+        lld_flavor: LldFlavor::Link,
+        pre_link_args,
+        abi_return_struct_as_int: true,
+        emit_debug_gdb_scripts: false,
+
+        ..Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/netbsd_base.rs b/src/librustc_target/spec/netbsd_base.rs
index eb359b92046..95c4749f9c7 100644
--- a/src/librustc_target/spec/netbsd_base.rs
+++ b/src/librustc_target/spec/netbsd_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut args = LinkArgs::new();
diff --git a/src/librustc_target/spec/openbsd_base.rs b/src/librustc_target/spec/openbsd_base.rs
index b66c56e1a7a..cadd14df693 100644
--- a/src/librustc_target/spec/openbsd_base.rs
+++ b/src/librustc_target/spec/openbsd_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut args = LinkArgs::new();
diff --git a/src/librustc_target/spec/redox_base.rs b/src/librustc_target/spec/redox_base.rs
index 6398fa91f02..18cafe654d1 100644
--- a/src/librustc_target/spec/redox_base.rs
+++ b/src/librustc_target/spec/redox_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut args = LinkArgs::new();
diff --git a/src/librustc_target/spec/solaris_base.rs b/src/librustc_target/spec/solaris_base.rs
index 98a2a0fbc9c..8d3a3563f41 100644
--- a/src/librustc_target/spec/solaris_base.rs
+++ b/src/librustc_target/spec/solaris_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::TargetOptions;
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
diff --git a/src/librustc_target/spec/tests/tests_impl.rs b/src/librustc_target/spec/tests/tests_impl.rs
new file mode 100644
index 00000000000..4cf186bdd7c
--- /dev/null
+++ b/src/librustc_target/spec/tests/tests_impl.rs
@@ -0,0 +1,43 @@
+use super::super::*;
+
+pub(super) fn test_target(target: TargetResult) {
+    // Grab the TargetResult struct. If we successfully retrieved
+    // a Target, then the test JSON encoding/decoding can run for this
+    // Target on this testing platform (i.e., checking the iOS targets
+    // only on a Mac test platform).
+    if let Ok(original) = target {
+        original.check_consistency();
+        let as_json = original.to_json();
+        let parsed = Target::from_json(as_json).unwrap();
+        assert_eq!(original, parsed);
+    }
+}
+
+impl Target {
+    fn check_consistency(&self) {
+        // Check that LLD with the given flavor is treated identically to the linker it emulates.
+        // If you target really needs to deviate from the rules below, whitelist it
+        // and document the reasons.
+        assert_eq!(
+            self.linker_flavor == LinkerFlavor::Msvc
+                || self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link),
+            self.options.lld_flavor == LldFlavor::Link,
+        );
+        for args in &[
+            &self.options.pre_link_args,
+            &self.options.pre_link_args_crt,
+            &self.options.late_link_args,
+            &self.options.late_link_args_dynamic,
+            &self.options.late_link_args_static,
+            &self.options.post_link_args,
+        ] {
+            assert_eq!(
+                args.get(&LinkerFlavor::Msvc),
+                args.get(&LinkerFlavor::Lld(LldFlavor::Link)),
+            );
+            if args.contains_key(&LinkerFlavor::Msvc) {
+                assert_eq!(self.options.lld_flavor, LldFlavor::Link);
+            }
+        }
+    }
+}
diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs
index 99ab996be95..eca095b5942 100644
--- a/src/librustc_target/spec/thumb_base.rs
+++ b/src/librustc_target/spec/thumb_base.rs
@@ -28,7 +28,6 @@
 // build scripts / gcc flags.
 
 use crate::spec::{PanicStrategy, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     // See rust-lang/rfcs#1645 for a discussion about these defaults
diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs
index ab0f7791e2c..21d62d252e0 100644
--- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs
+++ b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_msvc_base::opts();
@@ -10,7 +10,12 @@ pub fn target() -> TargetResult {
     // should be smart enough to insert branch islands only
     // where necessary, but this is not the observed behavior.
     // Disabling the LBR optimization works around the issue.
-    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/OPT:NOLBR".to_string());
+    let pre_link_args_msvc = "/OPT:NOLBR".to_string();
+    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push(pre_link_args_msvc.clone());
+    base.pre_link_args
+        .get_mut(&LinkerFlavor::Lld(LldFlavor::Link))
+        .unwrap()
+        .push(pre_link_args_msvc);
 
     // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is
     // implemented for windows/arm in LLVM
diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs
deleted file mode 100644
index d09da9478fb..00000000000
--- a/src/librustc_target/spec/uefi_base.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// This defines a base target-configuration for native UEFI systems. The UEFI specification has
-// quite detailed sections on the ABI of all the supported target architectures. In almost all
-// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN
-// documentation.
-// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic
-// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated
-// by the loader if the pre-chosen memory location is already in use.
-// UEFI forbids running code on anything but the boot-CPU. No interrupts are allowed other than
-// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
-// code runs in the same environment, no process separation is supported.
-
-use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
-use std::default::Default;
-
-pub fn opts() -> TargetOptions {
-    let mut pre_link_args = LinkArgs::new();
-
-    pre_link_args.insert(
-        LinkerFlavor::Lld(LldFlavor::Link),
-        vec![
-            // Suppress the verbose logo and authorship debugging output, which would needlessly
-            // clog any log files.
-            "/NOLOGO".to_string(),
-            // UEFI is fully compatible to non-executable data pages. Tell the compiler that
-            // non-code sections can be marked as non-executable, including stack pages. In fact,
-            // firmware might enforce this, so we better let the linker know about this, so it
-            // will fail if the compiler ever tries placing code on the stack (e.g., trampoline
-            // constructs and alike).
-            "/NXCOMPAT".to_string(),
-            // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets
-            // must be freestanding.
-            "/nodefaultlib".to_string(),
-            // Non-standard subsystems have no default entry-point in PE+ files. We have to define
-            // one. "efi_main" seems to be a common choice amongst other implementations and the
-            // spec.
-            "/entry:efi_main".to_string(),
-            // COFF images have a "Subsystem" field in their header, which defines what kind of
-            // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
-            // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
-            // which is very likely the most common option. Individual projects can override this
-            // with custom linker flags.
-            // The subsystem-type only has minor effects on the application. It defines the memory
-            // regions the application is loaded into (runtime-drivers need to be put into
-            // reserved areas), as well as whether a return from the entry-point is treated as
-            // exit (default for applications).
-            "/subsystem:efi_application".to_string(),
-        ],
-    );
-
-    TargetOptions {
-        dynamic_linking: false,
-        executables: true,
-        disable_redzone: true,
-        exe_suffix: ".efi".to_string(),
-        allows_weak_linkage: false,
-        panic_strategy: PanicStrategy::Abort,
-        stack_probes: true,
-        singlethread: true,
-        emit_debug_gdb_scripts: false,
-
-        linker: Some("rust-lld".to_string()),
-        lld_flavor: LldFlavor::Link,
-        pre_link_args,
-
-        ..Default::default()
-    }
-}
diff --git a/src/librustc_target/spec/uefi_msvc_base.rs b/src/librustc_target/spec/uefi_msvc_base.rs
new file mode 100644
index 00000000000..3f7c78c8e7d
--- /dev/null
+++ b/src/librustc_target/spec/uefi_msvc_base.rs
@@ -0,0 +1,58 @@
+// This defines a base target-configuration for native UEFI systems. The UEFI specification has
+// quite detailed sections on the ABI of all the supported target architectures. In almost all
+// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN
+// documentation.
+// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic
+// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated
+// by the loader if the pre-chosen memory location is already in use.
+// UEFI forbids running code on anything but the boot-CPU. No interrupts are allowed other than
+// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
+// code runs in the same environment, no process separation is supported.
+
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
+
+pub fn opts() -> TargetOptions {
+    let mut base = super::msvc_base::opts();
+
+    let pre_link_args_msvc = vec![
+        // Non-standard subsystems have no default entry-point in PE+ files. We have to define
+        // one. "efi_main" seems to be a common choice amongst other implementations and the
+        // spec.
+        "/entry:efi_main".to_string(),
+        // COFF images have a "Subsystem" field in their header, which defines what kind of
+        // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
+        // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
+        // which is very likely the most common option. Individual projects can override this
+        // with custom linker flags.
+        // The subsystem-type only has minor effects on the application. It defines the memory
+        // regions the application is loaded into (runtime-drivers need to be put into
+        // reserved areas), as well as whether a return from the entry-point is treated as
+        // exit (default for applications).
+        "/subsystem:efi_application".to_string(),
+    ];
+    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone());
+    base.pre_link_args
+        .get_mut(&LinkerFlavor::Lld(LldFlavor::Link))
+        .unwrap()
+        .extend(pre_link_args_msvc);
+
+    TargetOptions {
+        disable_redzone: true,
+        exe_suffix: ".efi".to_string(),
+        allows_weak_linkage: false,
+        panic_strategy: PanicStrategy::Abort,
+        stack_probes: true,
+        singlethread: true,
+        linker: Some("rust-lld".to_string()),
+        // FIXME: This should likely be `true` inherited from `msvc_base`
+        // because UEFI follows Windows ABI and uses PE/COFF.
+        // The `false` is probably causing ABI bugs right now.
+        is_like_windows: false,
+        // FIXME: This should likely be `true` inherited from `msvc_base`
+        // because UEFI follows Windows ABI and uses PE/COFF.
+        // The `false` is probably causing ABI bugs right now.
+        is_like_msvc: false,
+
+        ..base
+    }
+}
diff --git a/src/librustc_target/spec/vxworks_base.rs b/src/librustc_target/spec/vxworks_base.rs
index 1763c9139b1..1b25c51278d 100644
--- a/src/librustc_target/spec/vxworks_base.rs
+++ b/src/librustc_target/spec/vxworks_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut args_crt = LinkArgs::new();
diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_gnu_base.rs
index 097ee09f1ea..33ecb1d0d48 100644
--- a/src/librustc_target/spec/windows_base.rs
+++ b/src/librustc_target/spec/windows_gnu_base.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
     let mut pre_link_args = LinkArgs::new();
diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs
index 52b166df939..77171f8672e 100644
--- a/src/librustc_target/spec/windows_msvc_base.rs
+++ b/src/librustc_target/spec/windows_msvc_base.rs
@@ -1,36 +1,30 @@
-use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
-use std::default::Default;
+use crate::spec::TargetOptions;
 
 pub fn opts() -> TargetOptions {
-    let pre_args = vec!["/NOLOGO".to_string(), "/NXCOMPAT".to_string()];
-    let mut args = LinkArgs::new();
-    args.insert(LinkerFlavor::Msvc, pre_args.clone());
-    args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_args);
+    let base = super::msvc_base::opts();
 
     TargetOptions {
-        function_sections: true,
         dynamic_linking: true,
-        executables: true,
         dll_prefix: String::new(),
         dll_suffix: ".dll".to_string(),
         exe_suffix: ".exe".to_string(),
         staticlib_prefix: String::new(),
         staticlib_suffix: ".lib".to_string(),
         target_family: Some("windows".to_string()),
-        is_like_windows: true,
-        is_like_msvc: true,
-        // set VSLANG to 1033 can prevent link.exe from using
-        // language packs, and avoid generating Non-UTF-8 error
-        // messages if a link error occurred.
-        link_env: vec![("VSLANG".to_string(), "1033".to_string())],
-        lld_flavor: LldFlavor::Link,
-        pre_link_args: args,
         crt_static_allows_dylibs: true,
         crt_static_respected: true,
-        abi_return_struct_as_int: true,
-        emit_debug_gdb_scripts: false,
         requires_uwtable: true,
+        // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC
+        // as there's been trouble in the past of linking the C++ standard
+        // library required by LLVM. This likely needs to happen one day, but
+        // in general Windows is also a more controlled environment than
+        // Unix, so it's not necessarily as critical that this be implemented.
+        //
+        // Note that there are also some licensing worries about statically
+        // linking some libraries which require a specific agreement, so it may
+        // not ever be possible for us to pass this flag.
+        no_default_libraries: false,
 
-        ..Default::default()
+        ..base
     }
 }
diff --git a/src/librustc_target/spec/windows_uwp_base.rs b/src/librustc_target/spec/windows_uwp_gnu_base.rs
index f19bd10dc0b..dd3b60344be 100644
--- a/src/librustc_target/spec/windows_uwp_base.rs
+++ b/src/librustc_target/spec/windows_uwp_gnu_base.rs
@@ -1,7 +1,9 @@
 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
+    let base = super::windows_gnu_base::opts();
+
+    // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`.
     let mut pre_link_args = LinkArgs::new();
     pre_link_args.insert(
         LinkerFlavor::Gcc,
@@ -14,7 +16,10 @@ pub fn opts() -> TargetOptions {
         ],
     );
 
+    // FIXME: This should be updated for the exception machinery changes from #67502.
     let mut late_link_args = LinkArgs::new();
+    let late_link_args_dynamic = LinkArgs::new();
+    let late_link_args_static = LinkArgs::new();
     late_link_args.insert(
         LinkerFlavor::Gcc,
         vec![
@@ -33,31 +38,17 @@ pub fn opts() -> TargetOptions {
     );
 
     TargetOptions {
-        // FIXME(#13846) this should be enabled for windows
-        function_sections: false,
-        linker: Some("gcc".to_string()),
-        dynamic_linking: true,
         executables: false,
-        dll_prefix: String::new(),
-        dll_suffix: ".dll".to_string(),
-        exe_suffix: ".exe".to_string(),
-        staticlib_prefix: "lib".to_string(),
-        staticlib_suffix: ".a".to_string(),
-        target_family: Some("windows".to_string()),
-        is_like_windows: true,
-        allows_weak_linkage: false,
+        limit_rdylib_exports: false,
         pre_link_args,
-        pre_link_objects_exe: vec![
-            "rsbegin.o".to_string(), // Rust compiler runtime initialization, see rsbegin.rs
-        ],
+        // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`.
+        pre_link_objects_exe: vec!["rsbegin.o".to_string()],
+        // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`.
         pre_link_objects_dll: vec!["rsbegin.o".to_string()],
         late_link_args,
-        post_link_objects: vec!["rsend.o".to_string()],
-        abi_return_struct_as_int: true,
-        emit_debug_gdb_scripts: false,
-        requires_uwtable: true,
-        limit_rdylib_exports: false,
+        late_link_args_dynamic,
+        late_link_args_static,
 
-        ..Default::default()
+        ..base
     }
 }
diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs
index 3d639b6b628..04ffa1a0add 100644
--- a/src/librustc_target/spec/windows_uwp_msvc_base.rs
+++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs
@@ -1,37 +1,14 @@
-use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
-use std::default::Default;
+use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions};
 
 pub fn opts() -> TargetOptions {
-    let mut args = LinkArgs::new();
-    args.insert(
-        LinkerFlavor::Msvc,
-        vec![
-            "/NOLOGO".to_string(),
-            "/NXCOMPAT".to_string(),
-            "/APPCONTAINER".to_string(),
-            "mincore.lib".to_string(),
-        ],
-    );
+    let mut opts = super::windows_msvc_base::opts();
 
-    TargetOptions {
-        function_sections: true,
-        dynamic_linking: true,
-        executables: true,
-        dll_prefix: String::new(),
-        dll_suffix: ".dll".to_string(),
-        exe_suffix: ".exe".to_string(),
-        staticlib_prefix: String::new(),
-        staticlib_suffix: ".lib".to_string(),
-        target_family: Some("windows".to_string()),
-        is_like_windows: true,
-        is_like_msvc: true,
-        pre_link_args: args,
-        crt_static_allows_dylibs: true,
-        crt_static_respected: true,
-        abi_return_struct_as_int: true,
-        emit_debug_gdb_scripts: false,
-        requires_uwtable: true,
+    let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()];
+    opts.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone());
+    opts.pre_link_args
+        .get_mut(&LinkerFlavor::Lld(LldFlavor::Link))
+        .unwrap()
+        .extend(pre_link_args_msvc);
 
-        ..Default::default()
-    }
+    opts
 }
diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs
index 3d3acc682de..eb97fa56814 100644
--- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs
+++ b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs
@@ -1,7 +1,7 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
-    let mut base = super::windows_base::opts();
+    let mut base = super::windows_gnu_base::opts();
     base.cpu = "x86-64".to_string();
     base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
     base.max_atomic_width = Some(64);
diff --git a/src/librustc_target/spec/x86_64_unknown_illumos.rs b/src/librustc_target/spec/x86_64_unknown_illumos.rs
new file mode 100644
index 00000000000..8d461f67397
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_unknown_illumos.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::illumos_base::opts();
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]);
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+
+    Ok(Target {
+        // LLVM does not currently have a separate illumos target,
+        // so we still pass Solaris to it
+        llvm_target: "x86_64-pc-solaris".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-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        arch: "x86_64".to_string(),
+        target_os: "illumos".to_string(),
+        target_env: String::new(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: base,
+    })
+}
diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs
index 7660b68aae6..12edc29330a 100644
--- a/src/librustc_target/spec/x86_64_unknown_uefi.rs
+++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs
@@ -8,7 +8,7 @@
 use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
-    let mut base = super::uefi_base::opts();
+    let mut base = super::uefi_msvc_base::opts();
     base.cpu = "x86-64".to_string();
     base.max_atomic_width = Some(64);
 
@@ -28,11 +28,6 @@ pub fn target() -> TargetResult {
     // places no locality-restrictions, so it fits well here.
     base.code_model = Some("large".to_string());
 
-    // UEFI mirrors the calling-conventions used on windows. In case of x86-64 this means small
-    // structs will be returned as int. This shouldn't matter much, since the restrictions placed
-    // by the UEFI specifications forbid any ABI to return structures.
-    base.abi_return_struct_as_int = true;
-
     Ok(Target {
         llvm_target: "x86_64-unknown-windows".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs
index 48366e24a39..ad6002f6b89 100644
--- a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs
+++ b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs
@@ -1,7 +1,7 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
 
 pub fn target() -> TargetResult {
-    let mut base = super::windows_uwp_base::opts();
+    let mut base = super::windows_uwp_gnu_base::opts();
     base.cpu = "x86-64".to_string();
     base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
     base.max_atomic_width = Some(64);
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index fef7adf0224..904720125d3 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -292,7 +292,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                                 )),
                                 Some(
                                     "the question mark operation (`?`) implicitly performs a \
-                                     conversion on the error value using the `From` trait"
+                                        conversion on the error value using the `From` trait"
                                         .to_owned(),
                                 ),
                             )
@@ -312,6 +312,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             ))
                         );
 
+                        let should_convert_option_to_result =
+                            format!("{}", trait_ref.print_only_trait_path())
+                                .starts_with("std::convert::From<std::option::NoneError");
+                        let should_convert_result_to_option = format!("{}", trait_ref)
+                            .starts_with("<std::option::NoneError as std::convert::From<");
+                        if is_try && is_from && should_convert_option_to_result {
+                            err.span_suggestion_verbose(
+                                span.shrink_to_lo(),
+                                "consider converting the `Option<T>` into a `Result<T, _>` using `Option::ok_or` or `Option::ok_or_else`",
+                                ".ok_or_else(|| /* error value */)".to_string(),
+                                Applicability::HasPlaceholders,
+                            );
+                        } else if is_try && is_from && should_convert_result_to_option {
+                            err.span_suggestion_verbose(
+                                span.shrink_to_lo(),
+                                "consider converting the `Result<T, _>` into an `Option<T>` using `Result::ok`",
+                                ".ok()".to_string(),
+                                Applicability::MachineApplicable,
+                            );
+                        }
+
                         let explanation =
                             if obligation.cause.code == ObligationCauseCode::MainFunctionType {
                                 "consider using `()`, or a `Result`".to_owned()
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index 14029f29151..254db6cb869 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -10,7 +10,7 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
-use rustc_hir::Node;
+use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
 use rustc_middle::ty::TypeckTables;
 use rustc_middle::ty::{
     self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
@@ -127,13 +127,14 @@ pub trait InferCtxtExt<'tcx> {
         scope_span: &Option<Span>,
         expr: Option<hir::HirId>,
         snippet: String,
-        first_generator: DefId,
-        last_generator: Option<DefId>,
+        inner_generator_body: Option<&hir::Body<'_>>,
+        outer_generator: Option<DefId>,
         trait_ref: ty::TraitRef<'_>,
         target_ty: Ty<'tcx>,
         tables: &ty::TypeckTables<'_>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
+        from_awaited_ty: Option<Span>,
     );
 
     fn note_obligation_cause_code<T>(
@@ -1029,7 +1030,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 err.note(&format!(
                     "{}s cannot be accessed directly on a `trait`, they can only be \
                         accessed through a specific `impl`",
-                    assoc_item.kind.suggestion_descr(),
+                    assoc_item.kind.as_def_kind().descr(def_id)
                 ));
                 err.span_suggestion(
                     span,
@@ -1094,6 +1095,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             obligation.predicate, obligation.cause.span
         );
         let source_map = self.tcx.sess.source_map();
+        let hir = self.tcx.hir();
 
         // Attempt to detect an async-await error by looking at the obligation causes, looking
         // for a generator to be present.
@@ -1118,8 +1120,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         // - `BindingObligation` with `impl_send (Send requirement)
         //
         // The first obligation in the chain is the most useful and has the generator that captured
-        // the type. The last generator has information about where the bound was introduced. At
-        // least one generator should be present for this diagnostic to be modified.
+        // the type. The last generator (`outer_generator` below) has information about where the
+        // bound was introduced. At least one generator should be present for this diagnostic to be
+        // modified.
         let (mut trait_ref, mut target_ty) = match obligation.predicate {
             ty::Predicate::Trait(p, _) => {
                 (Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty()))
@@ -1127,7 +1130,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             _ => (None, None),
         };
         let mut generator = None;
-        let mut last_generator = None;
+        let mut outer_generator = None;
         let mut next_code = Some(&obligation.cause.code);
         while let Some(code) = next_code {
             debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code);
@@ -1144,7 +1147,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     match ty.kind {
                         ty::Generator(did, ..) => {
                             generator = generator.or(Some(did));
-                            last_generator = Some(did);
+                            outer_generator = Some(did);
                         }
                         ty::GeneratorWitness(..) => {}
                         _ if generator.is_none() => {
@@ -1176,7 +1179,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         let span = self.tcx.def_span(generator_did);
 
         // Do not ICE on closure typeck (#66868).
-        if self.tcx.hir().as_local_hir_id(generator_did).is_none() {
+        if hir.as_local_hir_id(generator_did).is_none() {
             return false;
         }
 
@@ -1202,37 +1205,63 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             }
         };
 
+        let generator_body = hir
+            .as_local_hir_id(generator_did)
+            .and_then(|hir_id| hir.maybe_body_owned_by(hir_id))
+            .map(|body_id| hir.body(body_id));
+        let mut visitor = AwaitsVisitor::default();
+        if let Some(body) = generator_body {
+            visitor.visit_body(body);
+        }
+        debug!("maybe_note_obligation_cause_for_async_await: awaits = {:?}", visitor.awaits);
+
         // Look for a type inside the generator interior that matches the target type to get
         // a span.
         let target_ty_erased = self.tcx.erase_regions(&target_ty);
+        let ty_matches = |ty| -> bool {
+            // Careful: the regions for types that appear in the
+            // generator interior are not generally known, so we
+            // want to erase them when comparing (and anyway,
+            // `Send` and other bounds are generally unaffected by
+            // the choice of region).  When erasing regions, we
+            // also have to erase late-bound regions. This is
+            // because the types that appear in the generator
+            // interior generally contain "bound regions" to
+            // represent regions that are part of the suspended
+            // generator frame. Bound regions are preserved by
+            // `erase_regions` and so we must also call
+            // `erase_late_bound_regions`.
+            let ty_erased = self.tcx.erase_late_bound_regions(&ty::Binder::bind(ty));
+            let ty_erased = self.tcx.erase_regions(&ty_erased);
+            let eq = ty::TyS::same_type(ty_erased, target_ty_erased);
+            debug!(
+                "maybe_note_obligation_cause_for_async_await: ty_erased={:?} \
+                    target_ty_erased={:?} eq={:?}",
+                ty_erased, target_ty_erased, eq
+            );
+            eq
+        };
         let target_span = tables
             .generator_interior_types
             .iter()
-            .find(|ty::GeneratorInteriorTypeCause { ty, .. }| {
-                // Careful: the regions for types that appear in the
-                // generator interior are not generally known, so we
-                // want to erase them when comparing (and anyway,
-                // `Send` and other bounds are generally unaffected by
-                // the choice of region).  When erasing regions, we
-                // also have to erase late-bound regions. This is
-                // because the types that appear in the generator
-                // interior generally contain "bound regions" to
-                // represent regions that are part of the suspended
-                // generator frame. Bound regions are preserved by
-                // `erase_regions` and so we must also call
-                // `erase_late_bound_regions`.
-                let ty_erased = self.tcx.erase_late_bound_regions(&ty::Binder::bind(*ty));
-                let ty_erased = self.tcx.erase_regions(&ty_erased);
-                let eq = ty::TyS::same_type(ty_erased, target_ty_erased);
-                debug!(
-                    "maybe_note_obligation_cause_for_async_await: ty_erased={:?} \
-                        target_ty_erased={:?} eq={:?}",
-                    ty_erased, target_ty_erased, eq
-                );
-                eq
-            })
-            .map(|ty::GeneratorInteriorTypeCause { span, scope_span, expr, .. }| {
-                (span, source_map.span_to_snippet(*span), scope_span, expr)
+            .find(|ty::GeneratorInteriorTypeCause { ty, .. }| ty_matches(ty))
+            .map(|cause| {
+                // Check to see if any awaited expressions have the target type.
+                let from_awaited_ty = visitor
+                    .awaits
+                    .into_iter()
+                    .map(|id| hir.expect_expr(id))
+                    .find(|await_expr| {
+                        let ty = tables.expr_ty_adjusted(&await_expr);
+                        debug!(
+                            "maybe_note_obligation_cause_for_async_await: await_expr={:?}",
+                            await_expr
+                        );
+                        ty_matches(ty)
+                    })
+                    .map(|expr| expr.span);
+                let ty::GeneratorInteriorTypeCause { span, scope_span, expr, .. } = cause;
+                (span, source_map.span_to_snippet(*span), scope_span, expr, from_awaited_ty)
             });
 
         debug!(
@@ -1240,20 +1269,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 generator_interior_types={:?} target_span={:?}",
             target_ty, tables.generator_interior_types, target_span
         );
-        if let Some((target_span, Ok(snippet), scope_span, expr)) = target_span {
+        if let Some((target_span, Ok(snippet), scope_span, expr, from_awaited_ty)) = target_span {
             self.note_obligation_cause_for_async_await(
                 err,
                 *target_span,
                 scope_span,
                 *expr,
                 snippet,
-                generator_did,
-                last_generator,
+                generator_body,
+                outer_generator,
                 trait_ref,
                 target_ty,
                 tables,
                 obligation,
                 next_code,
+                from_awaited_ty,
             );
             true
         } else {
@@ -1270,35 +1300,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         scope_span: &Option<Span>,
         expr: Option<hir::HirId>,
         snippet: String,
-        first_generator: DefId,
-        last_generator: Option<DefId>,
+        inner_generator_body: Option<&hir::Body<'_>>,
+        outer_generator: Option<DefId>,
         trait_ref: ty::TraitRef<'_>,
         target_ty: Ty<'tcx>,
         tables: &ty::TypeckTables<'_>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
+        from_awaited_ty: Option<Span>,
     ) {
         let source_map = self.tcx.sess.source_map();
 
-        let is_async_fn = self
-            .tcx
-            .parent(first_generator)
-            .map(|parent_did| self.tcx.asyncness(parent_did))
-            .map(|parent_asyncness| parent_asyncness == hir::IsAsync::Async)
-            .unwrap_or(false);
-        let is_async_move = self
-            .tcx
-            .hir()
-            .as_local_hir_id(first_generator)
-            .and_then(|hir_id| self.tcx.hir().maybe_body_owned_by(hir_id))
-            .map(|body_id| self.tcx.hir().body(body_id))
+        let is_async = inner_generator_body
             .and_then(|body| body.generator_kind())
             .map(|generator_kind| match generator_kind {
                 hir::GeneratorKind::Async(..) => true,
                 _ => false,
             })
             .unwrap_or(false);
-        let await_or_yield = if is_async_fn || is_async_move { "await" } else { "yield" };
+        let (await_or_yield, an_await_or_yield) =
+            if is_async { ("await", "an await") } else { ("yield", "a yield") };
+        let future_or_generator = if is_async { "future" } else { "generator" };
 
         // Special case the primary error message when send or sync is the trait that was
         // not implemented.
@@ -1311,22 +1333,34 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
 
             err.clear_code();
             err.set_primary_message(format!(
-                "future cannot be {} between threads safely",
-                trait_verb
+                "{} cannot be {} between threads safely",
+                future_or_generator, trait_verb
             ));
 
             let original_span = err.span.primary_span().unwrap();
             let mut span = MultiSpan::from_span(original_span);
 
-            let message = if let Some(name) = last_generator
-                .and_then(|generator_did| self.tcx.parent(generator_did))
-                .and_then(|parent_did| hir.as_local_hir_id(parent_did))
-                .and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
-            {
-                format!("future returned by `{}` is not {}", name, trait_name)
-            } else {
-                format!("future is not {}", trait_name)
-            };
+            let message = outer_generator
+                .and_then(|generator_did| {
+                    Some(match self.tcx.generator_kind(generator_did).unwrap() {
+                        GeneratorKind::Gen => format!("generator is not {}", trait_name),
+                        GeneratorKind::Async(AsyncGeneratorKind::Fn) => self
+                            .tcx
+                            .parent(generator_did)
+                            .and_then(|parent_did| hir.as_local_hir_id(parent_did))
+                            .and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
+                            .map(|name| {
+                                format!("future returned by `{}` is not {}", name, trait_name)
+                            })?,
+                        GeneratorKind::Async(AsyncGeneratorKind::Block) => {
+                            format!("future created by async block is not {}", trait_name)
+                        }
+                        GeneratorKind::Async(AsyncGeneratorKind::Closure) => {
+                            format!("future created by async closure is not {}", trait_name)
+                        }
+                    })
+                })
+                .unwrap_or_else(|| format!("{} is not {}", future_or_generator, trait_name));
 
             span.push_span_label(original_span, message);
             err.set_span(span);
@@ -1336,31 +1370,56 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             format!("does not implement `{}`", trait_ref.print_only_trait_path())
         };
 
-        // Look at the last interior type to get a span for the `.await`.
-        let await_span = tables.generator_interior_types.iter().map(|t| t.span).last().unwrap();
-        let mut span = MultiSpan::from_span(await_span);
-        span.push_span_label(
-            await_span,
-            format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
-        );
+        if let Some(await_span) = from_awaited_ty {
+            // The type causing this obligation is one being awaited at await_span.
+            let mut span = MultiSpan::from_span(await_span);
 
-        span.push_span_label(target_span, format!("has type `{}`", target_ty));
+            span.push_span_label(
+                await_span,
+                format!("await occurs here on type `{}`, which {}", target_ty, trait_explanation),
+            );
 
-        // If available, use the scope span to annotate the drop location.
-        if let Some(scope_span) = scope_span {
+            err.span_note(
+                span,
+                &format!(
+                    "future {not_trait} as it awaits another future which {not_trait}",
+                    not_trait = trait_explanation
+                ),
+            );
+        } else {
+            // Look at the last interior type to get a span for the `.await`.
+            debug!(
+                "note_obligation_cause_for_async_await generator_interior_types: {:#?}",
+                tables.generator_interior_types
+            );
+            let await_span = tables.generator_interior_types.iter().map(|t| t.span).last().unwrap();
+            let mut span = MultiSpan::from_span(await_span);
             span.push_span_label(
-                source_map.end_point(*scope_span),
-                format!("`{}` is later dropped here", snippet),
+                await_span,
+                format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
             );
-        }
 
-        err.span_note(
-            span,
-            &format!(
-                "future {} as this value is used across an {}",
-                trait_explanation, await_or_yield,
-            ),
-        );
+            span.push_span_label(
+                target_span,
+                format!("has type `{}` which {}", target_ty, trait_explanation),
+            );
+
+            // If available, use the scope span to annotate the drop location.
+            if let Some(scope_span) = scope_span {
+                span.push_span_label(
+                    source_map.end_point(*scope_span),
+                    format!("`{}` is later dropped here", snippet),
+                );
+            }
+
+            err.span_note(
+                span,
+                &format!(
+                    "{} {} as this value is used across {}",
+                    future_or_generator, trait_explanation, an_await_or_yield
+                ),
+            );
+        }
 
         if let Some(expr_id) = expr {
             let expr = hir.expect_expr(expr_id);
@@ -1705,6 +1764,27 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
     }
 }
 
+/// Collect all the awaited expressions within the input expression.
+#[derive(Default)]
+struct AwaitsVisitor {
+    awaits: Vec<hir::HirId>,
+}
+
+impl<'v> Visitor<'v> for AwaitsVisitor {
+    type Map = hir::intravisit::ErasedMap<'v>;
+
+    fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
+        hir::intravisit::NestedVisitorMap::None
+    }
+
+    fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
+        if let hir::ExprKind::Yield(_, hir::YieldSource::Await { expr: Some(id) }) = ex.kind {
+            self.awaits.push(id)
+        }
+        hir::intravisit::walk_expr(self, ex)
+    }
+}
+
 pub trait NextTypeParamName {
     fn next_type_param_name(&self, name: Option<&str>) -> String;
 }
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index f5f4a51eb54..f8fc155f582 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -475,7 +475,7 @@ fn vtable_methods<'tcx>(
         let trait_methods = tcx
             .associated_items(trait_ref.def_id())
             .in_definition_order()
-            .filter(|item| item.kind == ty::AssocKind::Method);
+            .filter(|item| item.kind == ty::AssocKind::Fn);
 
         // Now list each method's DefId and InternalSubsts (for within its trait).
         // If the method can never be called from this object, produce None.
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs
index 2389b36f842..d9fba1fd783 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/src/librustc_trait_selection/traits/object_safety.rs
@@ -86,7 +86,7 @@ fn object_safety_violations_for_trait(
     let mut violations: Vec<_> = tcx
         .associated_items(trait_def_id)
         .in_definition_order()
-        .filter(|item| item.kind == ty::AssocKind::Method)
+        .filter(|item| item.kind == ty::AssocKind::Fn)
         .filter_map(|item| {
             object_safety_violation_for_method(tcx, trait_def_id, &item)
                 .map(|(code, span)| ObjectSafetyViolation::Method(item.ident.name, code, span))
@@ -362,7 +362,7 @@ fn virtual_call_violation_for_method<'tcx>(
     method: &ty::AssocItem,
 ) -> Option<MethodViolationCode> {
     // The method's first parameter must be named `self`
-    if !method.method_has_self_argument {
+    if !method.fn_has_self_parameter {
         // We'll attempt to provide a structured suggestion for `Self: Sized`.
         let sugg =
             tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map(
diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs
index 28d59b41e56..0da26abc330 100644
--- a/src/librustc_trait_selection/traits/query/normalize.rs
+++ b/src/librustc_trait_selection/traits/query/normalize.rs
@@ -59,11 +59,22 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
             anon_depth: 0,
         };
 
-        let value1 = value.fold_with(&mut normalizer);
+        let result = value.fold_with(&mut normalizer);
+        debug!(
+            "normalize::<{}>: result={:?} with {} obligations",
+            ::std::any::type_name::<T>(),
+            result,
+            normalizer.obligations.len(),
+        );
+        debug!(
+            "normalize::<{}>: obligations={:?}",
+            ::std::any::type_name::<T>(),
+            normalizer.obligations,
+        );
         if normalizer.error {
             Err(NoSolution)
         } else {
-            Ok(Normalized { value: value1, obligations: normalizer.obligations })
+            Ok(Normalized { value: result, obligations: normalizer.obligations })
         }
     }
 }
diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs
index 725c41c1e2c..ffece42ec30 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/src/librustc_trait_selection/traits/util.rs
@@ -293,7 +293,7 @@ pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'
     // Count number of methods and add them to the total offset.
     // Skip over associated types and constants.
     for trait_item in tcx.associated_items(trait_ref.def_id()).in_definition_order() {
-        if trait_item.kind == ty::AssocKind::Method {
+        if trait_item.kind == ty::AssocKind::Fn {
             entries += 1;
         }
     }
@@ -315,10 +315,10 @@ pub fn get_vtable_index_of_object_method<N>(
     for trait_item in tcx.associated_items(object.upcast_trait_ref.def_id()).in_definition_order() {
         if trait_item.def_id == method_def_id {
             // The item with the ID we were given really ought to be a method.
-            assert_eq!(trait_item.kind, ty::AssocKind::Method);
+            assert_eq!(trait_item.kind, ty::AssocKind::Fn);
             return entries;
         }
-        if trait_item.kind == ty::AssocKind::Method {
+        if trait_item.kind == ty::AssocKind::Fn {
             entries += 1;
         }
     }
diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs
index 33ecbe72a8c..6db2e557fea 100644
--- a/src/librustc_traits/implied_outlives_bounds.rs
+++ b/src/librustc_traits/implied_outlives_bounds.rs
@@ -62,7 +62,7 @@ fn compute_implied_outlives_bounds<'tcx>(
         // unresolved inference variables here anyway, but there might be
         // during typeck under some circumstances.)
         let obligations =
-            wf::obligations(infcx, param_env, hir::DUMMY_HIR_ID, ty, DUMMY_SP).unwrap_or(vec![]);
+            wf::obligations(infcx, param_env, hir::CRATE_HIR_ID, ty, DUMMY_SP).unwrap_or(vec![]);
 
         // N.B., all of these predicates *ought* to be easily proven
         // true. In fact, their correctness is (mostly) implied by
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index aefe61f60b8..43ff39f92f7 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -85,7 +85,7 @@ fn associated_item_from_trait_item_ref(
     let def_id = tcx.hir().local_def_id(trait_item_ref.id.hir_id);
     let (kind, has_self) = match trait_item_ref.kind {
         hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
-        hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self),
+        hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self),
         hir::AssocItemKind::Type => (ty::AssocKind::Type, false),
         hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"),
     };
@@ -98,7 +98,7 @@ fn associated_item_from_trait_item_ref(
         defaultness: trait_item_ref.defaultness,
         def_id,
         container: ty::TraitContainer(parent_def_id),
-        method_has_self_argument: has_self,
+        fn_has_self_parameter: has_self,
     }
 }
 
@@ -110,7 +110,7 @@ fn associated_item_from_impl_item_ref(
     let def_id = tcx.hir().local_def_id(impl_item_ref.id.hir_id);
     let (kind, has_self) = match impl_item_ref.kind {
         hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
-        hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self),
+        hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self),
         hir::AssocItemKind::Type => (ty::AssocKind::Type, false),
         hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false),
     };
@@ -123,7 +123,7 @@ fn associated_item_from_impl_item_ref(
         defaultness: impl_item_ref.defaultness,
         def_id,
         container: ty::ImplContainer(parent_def_id),
-        method_has_self_argument: has_self,
+        fn_has_self_parameter: has_self,
     }
 }
 
@@ -265,7 +265,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
     let unnormalized_env =
         ty::ParamEnv::new(tcx.intern_predicates(&predicates), traits::Reveal::UserFacing, None);
 
-    let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| {
+    let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::CRATE_HIR_ID, |id| {
         tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id)
     });
     let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 24db25a1f34..82c8a5543eb 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -516,7 +516,7 @@ fn compare_self_type<'tcx>(
         })
     };
 
-    match (trait_m.method_has_self_argument, impl_m.method_has_self_argument) {
+    match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
         (false, false) | (true, true) => {}
 
         (false, true) => {
@@ -1163,7 +1163,7 @@ fn compare_type_predicate_entailment(
 fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {
     match impl_item.kind {
         ty::AssocKind::Const => "const",
-        ty::AssocKind::Method => "method",
+        ty::AssocKind::Fn => "method",
         ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "type",
     }
 }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 369bb183bcd..be45ada866f 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -217,14 +217,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         expected: Ty<'tcx>,
         checked_ty: Ty<'tcx>,
+        hir_id: hir::HirId,
     ) -> Vec<AssocItem> {
-        let mut methods = self.probe_for_return_type(
-            span,
-            probe::Mode::MethodCall,
-            expected,
-            checked_ty,
-            hir::DUMMY_HIR_ID,
-        );
+        let mut methods =
+            self.probe_for_return_type(span, probe::Mode::MethodCall, expected, checked_ty, hir_id);
         methods.retain(|m| {
             self.has_no_input_arg(m)
                 && self
@@ -250,9 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // This function checks if the method isn't static and takes other arguments than `self`.
     fn has_no_input_arg(&self, method: &AssocItem) -> bool {
         match method.kind {
-            ty::AssocKind::Method => {
-                self.tcx.fn_sig(method.def_id).inputs().skip_binder().len() == 1
-            }
+            ty::AssocKind::Fn => self.tcx.fn_sig(method.def_id).inputs().skip_binder().len() == 1,
             _ => false,
         }
     }
@@ -753,8 +747,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             match (&expected_ty.kind, &checked_ty.kind) {
                 (&ty::Int(ref exp), &ty::Int(ref found)) => {
-                    let is_fallible = match (found.bit_width(), exp.bit_width()) {
-                        (Some(found), Some(exp)) if found > exp => true,
+                    let is_fallible = match (exp.bit_width(), found.bit_width()) {
+                        (Some(exp), Some(found)) if exp < found => true,
+                        (None, Some(8 | 16)) => false,
                         (None, _) | (_, None) => true,
                         _ => false,
                     };
@@ -762,8 +757,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     true
                 }
                 (&ty::Uint(ref exp), &ty::Uint(ref found)) => {
-                    let is_fallible = match (found.bit_width(), exp.bit_width()) {
-                        (Some(found), Some(exp)) if found > exp => true,
+                    let is_fallible = match (exp.bit_width(), found.bit_width()) {
+                        (Some(exp), Some(found)) if exp < found => true,
+                        (None, Some(8 | 16)) => false,
                         (None, _) | (_, None) => true,
                         _ => false,
                     };
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 57e2349bb2e..7cb51b4d6d8 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1797,7 +1797,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // we know that the yield type must be `()`; however, the context won't contain this
             // information. Hence, we check the source of the yield expression here and check its
             // value's type against `()` (this check should always hold).
-            None if src == &hir::YieldSource::Await => {
+            None if src.is_await() => {
                 self.check_expr_coercable_to_type(&value, self.tcx.mk_unit());
                 self.tcx.mk_unit()
             }
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 210ba92e811..3f81689cdc9 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -209,7 +209,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                     "impl {:?} is not an inherent impl",
                     impl_def_id
                 );
-                self.impl_self_ty(self.span, impl_def_id).substs
+                self.fresh_substs_for_item(self.span, impl_def_id)
             }
 
             probe::ObjectPick => {
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index deaff19de08..c4f53332cb6 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -171,11 +171,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///
     /// Given a method call like `foo.bar::<T1,...Tn>(...)`:
     ///
-    /// * `fcx`:                   the surrounding `FnCtxt` (!)
-    /// * `span`:                  the span for the method call
-    /// * `method_name`:           the name of the method being called (`bar`)
+    /// * `self`:                  the surrounding `FnCtxt` (!)
     /// * `self_ty`:               the (unadjusted) type of the self expression (`foo`)
-    /// * `supplied_method_types`: the explicit method type parameters, if any (`T1..Tn`)
+    /// * `segment`:               the name and generic arguments of the method (`bar::<T1, ...Tn>`)
+    /// * `span`:                  the span for the method call
+    /// * `call_expr`:             the complete method call: (`foo.bar::<T1,...Tn>(...)`)
     /// * `self_expr`:             the self expression (`foo`)
     pub fn lookup_method(
         &self,
@@ -467,7 +467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        let def_kind = pick.item.def_kind();
+        let def_kind = pick.item.kind.as_def_kind();
         debug!("resolve_ufcs: def_kind={:?}, def_id={:?}", def_kind, pick.item.def_id);
         tcx.check_stability(pick.item.def_id, Some(expr_id), span);
         Ok((def_kind, pick.item.def_id))
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 7e7d84c1996..3f159fe5e30 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -452,7 +452,7 @@ fn method_autoderef_steps<'tcx>(
     tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &goal, |ref infcx, goal, inference_vars| {
         let ParamEnvAnd { param_env, value: self_ty } = goal;
 
-        let mut autoderef = Autoderef::new(infcx, param_env, hir::DUMMY_HIR_ID, DUMMY_SP, self_ty)
+        let mut autoderef = Autoderef::new(infcx, param_env, hir::CRATE_HIR_ID, DUMMY_SP, self_ty)
             .include_raw_pointers()
             .silence_errors();
         let mut reached_raw_pointer = false;
@@ -570,7 +570,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 self.extension_candidates.push(candidate);
             }
         } else if self.private_candidate.is_none() {
-            self.private_candidate = Some((candidate.item.def_kind(), candidate.item.def_id));
+            self.private_candidate =
+                Some((candidate.item.kind.as_def_kind(), candidate.item.def_id));
         }
     }
 
@@ -648,11 +649,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 }
             }
             ty::RawPtr(ty::TypeAndMut { ty: _, mutbl }) => {
-                let lang_def_id = match mutbl {
-                    hir::Mutability::Not => lang_items.const_ptr_impl(),
-                    hir::Mutability::Mut => lang_items.mut_ptr_impl(),
+                let (lang_def_id1, lang_def_id2) = match mutbl {
+                    hir::Mutability::Not => {
+                        (lang_items.const_ptr_impl(), lang_items.const_slice_ptr_impl())
+                    }
+                    hir::Mutability::Mut => {
+                        (lang_items.mut_ptr_impl(), lang_items.mut_slice_ptr_impl())
+                    }
                 };
-                self.assemble_inherent_impl_for_primitive(lang_def_id);
+                self.assemble_inherent_impl_for_primitive(lang_def_id1);
+                self.assemble_inherent_impl_for_primitive(lang_def_id2);
             }
             ty::Int(i) => {
                 let lang_def_id = match i {
@@ -859,9 +865,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         &mut self,
         expr_hir_id: hir::HirId,
     ) -> Result<(), MethodError<'tcx>> {
-        if expr_hir_id == hir::DUMMY_HIR_ID {
-            return Ok(());
-        }
         let mut duplicates = FxHashSet::default();
         let opt_applicable_traits = self.tcx.in_scope_traits(expr_hir_id);
         if let Some(applicable_traits) = opt_applicable_traits {
@@ -896,7 +899,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         expected: Ty<'tcx>,
     ) -> bool {
         match method.kind {
-            ty::AssocKind::Method => {
+            ty::AssocKind::Fn => {
                 let fty = self.tcx.fn_sig(method.def_id);
                 self.probe(|_| {
                     let substs = self.fresh_substs_for_item(self.span, method.def_id);
@@ -1128,8 +1131,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     ) -> Option<PickResult<'tcx>> {
         let tcx = self.tcx;
 
-        // In general, during probing we erase regions. See
-        // `impl_self_ty()` for an explanation.
+        // In general, during probing we erase regions.
         let region = tcx.lifetimes.re_erased;
 
         let autoref_ty = tcx.mk_ref(region, ty::TypeAndMut { ty: self_ty, mutbl });
@@ -1513,7 +1515,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             );
             pcx.allow_similar_names = true;
             pcx.assemble_inherent_candidates();
-            pcx.assemble_extension_candidates_for_traits_in_scope(hir::DUMMY_HIR_ID)?;
 
             let method_names = pcx.candidate_method_names();
             pcx.allow_similar_names = false;
@@ -1523,10 +1524,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     pcx.reset();
                     pcx.method_name = Some(method_name);
                     pcx.assemble_inherent_candidates();
-                    pcx.assemble_extension_candidates_for_traits_in_scope(hir::DUMMY_HIR_ID)
-                        .map_or(None, |_| {
-                            pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item)
-                        })
+                    pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item)
                 })
                 .collect();
 
@@ -1554,10 +1552,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         // In Path mode (i.e., resolving a value like `T::next`), consider any
         // associated value (i.e., methods, constants) but not types.
         match self.mode {
-            Mode::MethodCall => item.method_has_self_argument,
+            Mode::MethodCall => item.fn_has_self_parameter,
             Mode::Path => match item.kind {
                 ty::AssocKind::OpaqueTy | ty::AssocKind::Type => false,
-                ty::AssocKind::Method | ty::AssocKind::Const => true,
+                ty::AssocKind::Fn | ty::AssocKind::Const => true,
             },
         }
         // FIXME -- check for types that deref to `Self`,
@@ -1578,7 +1576,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         impl_ty: Ty<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> (Ty<'tcx>, Option<Ty<'tcx>>) {
-        if item.kind == ty::AssocKind::Method && self.mode == Mode::MethodCall {
+        if item.kind == ty::AssocKind::Fn && self.mode == Mode::MethodCall {
             let sig = self.xform_method_sig(item.def_id, substs);
             (sig.inputs()[0], Some(sig.output()))
         } else {
@@ -1614,8 +1612,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 } else {
                     match param.kind {
                         GenericParamDefKind::Lifetime => {
-                            // In general, during probe we erase regions. See
-                            // `impl_self_ty()` for an explanation.
+                            // In general, during probe we erase regions.
                             self.tcx.lifetimes.re_erased.into()
                         }
                         GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index f075d1e74d4..edde9b1a1a1 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -117,7 +117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             .span_if_local(item.def_id)
                             .or_else(|| self.tcx.hir().span_if_local(impl_did));
 
-                        let impl_ty = self.impl_self_ty(span, impl_did).ty;
+                        let impl_ty = self.tcx.at(span).type_of(impl_did);
 
                         let insertion = match self.tcx.impl_trait_ref(impl_did) {
                             None => String::new(),
@@ -162,7 +162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 ty::AssocKind::Const
                                 | ty::AssocKind::Type
                                 | ty::AssocKind::OpaqueTy => rcvr_ty,
-                                ty::AssocKind::Method => self
+                                ty::AssocKind::Fn => self
                                     .tcx
                                     .fn_sig(item.def_id)
                                     .inputs()
@@ -179,6 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 path,
                                 ty,
                                 item.kind,
+                                item.def_id,
                                 sugg_span,
                                 idx,
                                 self.tcx.sess.source_map(),
@@ -220,6 +221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             path,
                             rcvr_ty,
                             item.kind,
+                            item.def_id,
                             sugg_span,
                             idx,
                             self.tcx.sess.source_map(),
@@ -537,7 +539,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // When the "method" is resolved through dereferencing, we really want the
                         // original type that has the associated function for accurate suggestions.
                         // (#61411)
-                        let ty = self.impl_self_ty(span, *impl_did).ty;
+                        let ty = tcx.at(span).type_of(*impl_did);
                         match (&ty.peel_refs().kind, &actual.peel_refs().kind) {
                             (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => {
                                 // Use `actual` as it will have more `substs` filled in.
@@ -764,7 +766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         err.span_label(span, msg);
                     }
                 } else if let Some(lev_candidate) = lev_candidate {
-                    let def_kind = lev_candidate.def_kind();
+                    let def_kind = lev_candidate.kind.as_def_kind();
                     err.span_suggestion(
                         span,
                         &format!(
@@ -957,7 +959,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     && self
                         .associated_item(info.def_id, item_name, Namespace::ValueNS)
                         .filter(|item| {
-                            if let ty::AssocKind::Method = item.kind {
+                            if let ty::AssocKind::Fn = item.kind {
                                 let id = self.tcx.hir().as_local_hir_id(item.def_id);
                                 if let Some(hir::Node::TraitItem(hir::TraitItem {
                                     kind: hir::TraitItemKind::Fn(fn_sig, method),
@@ -1387,12 +1389,13 @@ fn print_disambiguation_help(
     trait_name: String,
     rcvr_ty: Ty<'_>,
     kind: ty::AssocKind,
+    def_id: DefId,
     span: Span,
     candidate: Option<usize>,
     source_map: &source_map::SourceMap,
 ) {
     let mut applicability = Applicability::MachineApplicable;
-    let sugg_args = if let (ty::AssocKind::Method, Some(args)) = (kind, args) {
+    let sugg_args = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
         format!(
             "({}{})",
             if rcvr_ty.is_region_ptr() {
@@ -1416,7 +1419,7 @@ fn print_disambiguation_help(
         span,
         &format!(
             "disambiguate the {} for {}",
-            kind.suggestion_descr(),
+            kind.as_def_kind().descr(def_id),
             if let Some(candidate) = candidate {
                 format!("candidate #{}", candidate)
             } else {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 4b5953b5e95..ca6bd21fefd 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -154,7 +154,6 @@ use std::slice;
 
 use crate::require_c_abi_if_c_variadic;
 use crate::util::common::indenter;
-use crate::TypeAndSubsts;
 
 use self::autoderef::Autoderef;
 use self::callee::DeferredCallResolution;
@@ -839,7 +838,11 @@ fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         return tcx.has_typeck_tables(outer_def_id);
     }
 
-    if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
+    // FIXME(#71104) Should really be using just `as_local_hir_id` but
+    // some `LocalDefId` do not seem to have a corresponding HirId.
+    if let Some(id) =
+        def_id.as_local().and_then(|def_id| tcx.hir().opt_local_def_id_to_hir_id(def_id))
+    {
         primary_body_of(tcx, id).is_some()
     } else {
         false
@@ -1904,7 +1907,7 @@ fn check_specialization_validity<'tcx>(
 ) {
     let kind = match impl_item.kind {
         hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
-        hir::ImplItemKind::Fn(..) => ty::AssocKind::Method,
+        hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
         hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy,
         hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
     };
@@ -2050,7 +2053,7 @@ fn check_impl_items_against_trait<'tcx>(
                 }
                 hir::ImplItemKind::Fn(..) => {
                     let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
-                    if ty_trait_item.kind == ty::AssocKind::Method {
+                    if ty_trait_item.kind == ty::AssocKind::Fn {
                         compare_impl_method(
                             tcx,
                             &ty_impl_item,
@@ -2296,7 +2299,7 @@ fn fn_sig_suggestion(
 /// structured suggestion.
 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
     match assoc.kind {
-        ty::AssocKind::Method => {
+        ty::AssocKind::Fn => {
             // We skip the binder here because the binder would deanonymize all
             // late-bound regions, and we don't want method signatures to show up
             // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
@@ -3312,8 +3315,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
-        let c = self.tcx.hir().local_def_id(ast_c.hir_id).expect_local();
-        ty::Const::from_anon_const(self.tcx, c)
+        let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id).expect_local();
+        let c = ty::Const::from_anon_const(self.tcx, const_def_id);
+
+        // HACK(eddyb) emulate what a `WellFormedConst` obligation would do.
+        // This code should be replaced with the proper WF handling ASAP.
+        if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
+            assert!(promoted.is_none());
+
+            // HACK(eddyb) let's hope these are always empty.
+            // let obligations = self.nominal_obligations(def_id, substs);
+            // self.out.extend(obligations);
+
+            let cause = traits::ObligationCause::new(
+                self.tcx.def_span(const_def_id.to_def_id()),
+                self.body_id,
+                traits::MiscObligation,
+            );
+            self.register_predicate(traits::Obligation::new(
+                cause,
+                self.param_env,
+                ty::Predicate::ConstEvaluatable(def_id, substs),
+            ));
+        }
+
+        c
     }
 
     // If the type given by the user has free regions, save it for later, since
@@ -4251,24 +4277,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    // Determine the `Self` type, using fresh variables for all variables
-    // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>`
-    // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type
-    // variables.
-    pub fn impl_self_ty(
-        &self,
-        span: Span, // (potential) receiver for this impl
-        did: DefId,
-    ) -> TypeAndSubsts<'tcx> {
-        let ity = self.tcx.type_of(did);
-        debug!("impl_self_ty: ity={:?}", ity);
-
-        let substs = self.fresh_substs_for_item(span, did);
-        let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
-
-        TypeAndSubsts { substs, ty: substd_ty }
-    }
-
     /// Unifies the output type with the expected type early, for more coercions
     /// and forward type information on the input expressions.
     fn expected_inputs_for_expected_output(
@@ -5000,7 +5008,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else if !self.check_for_cast(err, expr, found, expected) {
             let is_struct_pat_shorthand_field =
                 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
-            let methods = self.get_conversion_methods(expr.span, expected, found);
+            let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
             if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
                 let mut suggestions = iter::repeat(&expr_text)
                     .zip(methods.iter())
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 5bfad558b6b..32004744ff9 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -294,7 +294,7 @@ fn check_associated_item(
                 let ty = fcx.normalize_associated_types_in(span, &ty);
                 fcx.register_wf_obligation(ty, span, code.clone());
             }
-            ty::AssocKind::Method => {
+            ty::AssocKind::Fn => {
                 let sig = fcx.tcx.fn_sig(item.def_id);
                 let sig = fcx.normalize_associated_types_in(span, &sig);
                 let hir_sig = sig_if_method.expect("bad signature for method");
@@ -335,7 +335,7 @@ fn for_id(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) -> CheckWfFcxBuilder<'_>
         inherited: Inherited::build(tcx, def_id),
         id,
         span,
-        param_env: tcx.param_env(def_id.to_def_id()),
+        param_env: tcx.param_env(def_id),
     }
 }
 
@@ -985,7 +985,7 @@ fn check_method_receiver<'fcx, 'tcx>(
     // Check that the method has a valid receiver type, given the type `Self`.
     debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
 
-    if !method.method_has_self_argument {
+    if !method.fn_has_self_parameter {
         return;
     }
 
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 146fc04bc27..f9100300e3a 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -75,7 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         wbcx.tables.upvar_list =
             mem::replace(&mut self.tables.borrow_mut().upvar_list, Default::default());
 
-        wbcx.tables.tainted_by_errors = self.is_tainted_by_errors();
+        wbcx.tables.tainted_by_errors |= self.is_tainted_by_errors();
 
         debug!("writeback: tables for {:?} are {:#?}", item_def_id, wbcx.tables);
 
@@ -578,14 +578,21 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
-    fn resolve<T>(&self, x: &T, span: &dyn Locatable) -> T
+    fn resolve<T>(&mut self, x: &T, span: &dyn Locatable) -> T
     where
         T: TypeFoldable<'tcx>,
     {
-        let x = x.fold_with(&mut Resolver::new(self.fcx, span, self.body));
+        let mut resolver = Resolver::new(self.fcx, span, self.body);
+        let x = x.fold_with(&mut resolver);
         if cfg!(debug_assertions) && x.needs_infer() {
             span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x);
         }
+
+        // We may have introduced e.g. `ty::Error`, if inference failed, make sure
+        // to mark the `TypeckTables` as tainted in that case, so that downstream
+        // users of the tables don't produce extra errors, or worse, ICEs.
+        self.tables.tainted_by_errors |= resolver.replaced_with_error;
+
         x
     }
 }
@@ -613,6 +620,9 @@ struct Resolver<'cx, 'tcx> {
     infcx: &'cx InferCtxt<'cx, 'tcx>,
     span: &'cx dyn Locatable,
     body: &'tcx hir::Body<'tcx>,
+
+    /// Set to `true` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
+    replaced_with_error: bool,
 }
 
 impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
@@ -621,7 +631,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
         span: &'cx dyn Locatable,
         body: &'tcx hir::Body<'tcx>,
     ) -> Resolver<'cx, 'tcx> {
-        Resolver { tcx: fcx.tcx, infcx: fcx, span, body }
+        Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false }
     }
 
     fn report_error(&self, t: Ty<'tcx>) {
@@ -644,6 +654,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
             Err(_) => {
                 debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
                 self.report_error(t);
+                self.replaced_with_error = true;
                 self.tcx().types.err
             }
         }
@@ -661,6 +672,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
                 debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
                 // FIXME: we'd like to use `self.report_error`, but it doesn't yet
                 // accept a &'tcx ty::Const.
+                self.replaced_with_error = true;
                 self.tcx().consts.err
             }
         }
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index 9ace9f424b7..2e841734770 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -112,6 +112,30 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
                     item.span,
                 );
             }
+            ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Not })
+                if matches!(inner.kind, ty::Slice(_)) =>
+            {
+                self.check_primitive_impl(
+                    def_id,
+                    lang_items.const_slice_ptr_impl(),
+                    None,
+                    "const_slice_ptr",
+                    "*const [T]",
+                    item.span,
+                );
+            }
+            ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Mut })
+                if matches!(inner.kind, ty::Slice(_)) =>
+            {
+                self.check_primitive_impl(
+                    def_id,
+                    lang_items.mut_slice_ptr_impl(),
+                    None,
+                    "mut_slice_ptr",
+                    "*mut [T]",
+                    item.span,
+                );
+            }
             ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::Mutability::Not }) => {
                 self.check_primitive_impl(
                     def_id,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 8ae779a4783..a327951b3b0 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1170,14 +1170,28 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
         }
         // FIXME(#43408) enable this always when we get lazy normalization.
         Node::AnonConst(_) => {
+            let parent_id = tcx.hir().get_parent_item(hir_id);
+            let parent_def_id = tcx.hir().local_def_id(parent_id);
+
             // HACK(eddyb) this provides the correct generics when
             // `feature(const_generics)` is enabled, so that const expressions
             // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
             if tcx.features().const_generics {
-                let parent_id = tcx.hir().get_parent_item(hir_id);
-                Some(tcx.hir().local_def_id(parent_id))
+                Some(parent_def_id)
             } else {
-                None
+                let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
+                match parent_node {
+                    // HACK(eddyb) this provides the correct generics for repeat
+                    // expressions' count (i.e. `N` in `[x; N]`), as they shouldn't
+                    // be able to cause query cycle errors.
+                    Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
+                        if constant.hir_id == hir_id =>
+                    {
+                        Some(parent_def_id)
+                    }
+
+                    _ => None,
+                }
             }
         }
         Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
@@ -2583,7 +2597,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
                     .associated_items(trait_def_id)
                     .filter_by_name_unhygienic(impl_item.ident.name)
                     .find(move |trait_item| {
-                        trait_item.kind == ty::AssocKind::Method
+                        trait_item.kind == ty::AssocKind::Fn
                             && tcx.hygienic_eq(impl_item.ident, trait_item.ident, trait_def_id)
                     })
                 {
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 0635ad5babc..319f3238513 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -147,7 +147,7 @@ fn enforce_impl_params_are_constrained(
                     let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx);
                     cgp::parameters_for(&predicates, true)
                 }
-                ty::AssocKind::Method | ty::AssocKind::Const => Vec::new(),
+                ty::AssocKind::Fn | ty::AssocKind::Const => Vec::new(),
             }
         })
         .collect();
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 69d0b3723b0..df8290fd018 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -97,7 +97,6 @@ use rustc_infer::infer::{InferOk, TyCtxtInferExt};
 use rustc_infer::traits::TraitEngineExt as _;
 use rustc_middle::middle;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::util;
 use rustc_session::config::EntryFnType;
@@ -111,10 +110,6 @@ use rustc_trait_selection::traits::{
 use std::iter;
 
 use astconv::{AstConv, Bounds};
-pub struct TypeAndSubsts<'tcx> {
-    substs: SubstsRef<'tcx>,
-    ty: Ty<'tcx>,
-}
 
 fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
     if decl.c_variadic && !(abi == Abi::C || abi == Abi::Cdecl) {
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 775d600fc3d..57d499e38a7 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -360,6 +360,7 @@ impl<'a> fmt::Display for Html<'a> {
                         "fuchsia" => "Fuchsia",
                         "haiku" => "Haiku",
                         "hermit" => "HermitCore",
+                        "illumos" => "illumos",
                         "ios" => "iOS",
                         "l4re" => "L4Re",
                         "linux" => "Linux",
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 59297df8e48..6e50264c098 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -375,18 +375,16 @@ impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
 
 impl Clean<Lifetime> for hir::Lifetime {
     fn clean(&self, cx: &DocContext<'_>) -> Lifetime {
-        if self.hir_id != hir::DUMMY_HIR_ID {
-            let def = cx.tcx.named_region(self.hir_id);
-            match def {
-                Some(rl::Region::EarlyBound(_, node_id, _))
-                | Some(rl::Region::LateBound(_, node_id, _))
-                | Some(rl::Region::Free(_, node_id)) => {
-                    if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() {
-                        return lt;
-                    }
+        let def = cx.tcx.named_region(self.hir_id);
+        match def {
+            Some(rl::Region::EarlyBound(_, node_id, _))
+            | Some(rl::Region::LateBound(_, node_id, _))
+            | Some(rl::Region::Free(_, node_id)) => {
+                if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() {
+                    return lt;
                 }
-                _ => {}
             }
+            _ => {}
         }
         Lifetime(self.name.ident().to_string())
     }
@@ -1174,14 +1172,14 @@ impl Clean<Item> for ty::AssocItem {
                 };
                 AssocConstItem(ty.clean(cx), default)
             }
-            ty::AssocKind::Method => {
+            ty::AssocKind::Fn => {
                 let generics =
                     (cx.tcx.generics_of(self.def_id), cx.tcx.explicit_predicates_of(self.def_id))
                         .clean(cx);
                 let sig = cx.tcx.fn_sig(self.def_id);
                 let mut decl = (self.def_id, sig).clean(cx);
 
-                if self.method_has_self_argument {
+                if self.fn_has_self_parameter {
                     let self_ty = match self.container {
                         ty::ImplContainer(def_id) => cx.tcx.type_of(def_id),
                         ty::TraitContainer(_) => cx.tcx.types.self_param,
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 9e96015d306..2626ca638e8 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -208,10 +208,10 @@ pub fn get_real_types(
                             if !adds.is_empty() {
                                 res.extend(adds);
                             } else if !ty.is_full_generic() {
-                                if let Some(did) = ty.def_id() {
-                                    if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
-                                        res.insert((ty, kind));
-                                    }
+                                if let Some(kind) =
+                                    ty.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx))
+                                {
+                                    res.insert((ty, kind));
                                 }
                             }
                         }
@@ -226,20 +226,18 @@ pub fn get_real_types(
                     if !adds.is_empty() {
                         res.extend(adds);
                     } else if !ty.is_full_generic() {
-                        if let Some(did) = ty.def_id() {
-                            if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
-                                res.insert((ty.clone(), kind));
-                            }
+                        if let Some(kind) =
+                            ty.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx))
+                        {
+                            res.insert((ty.clone(), kind));
                         }
                     }
                 }
             }
         }
     } else {
-        if let Some(did) = arg.def_id() {
-            if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
-                res.insert((arg.clone(), kind));
-            }
+        if let Some(kind) = arg.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) {
+            res.insert((arg.clone(), kind));
         }
         if let Some(gens) = arg.generics() {
             for gen in gens.iter() {
@@ -248,10 +246,10 @@ pub fn get_real_types(
                     if !adds.is_empty() {
                         res.extend(adds);
                     }
-                } else if let Some(did) = gen.def_id() {
-                    if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
-                        res.insert((gen.clone(), kind));
-                    }
+                } else if let Some(kind) =
+                    gen.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx))
+                {
+                    res.insert((gen.clone(), kind));
                 }
             }
         }
@@ -277,10 +275,8 @@ pub fn get_all_types(
         if !args.is_empty() {
             all_types.extend(args);
         } else {
-            if let Some(did) = arg.type_.def_id() {
-                if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
-                    all_types.insert((arg.type_.clone(), kind));
-                }
+            if let Some(kind) = arg.type_.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) {
+                all_types.insert((arg.type_.clone(), kind));
             }
         }
     }
@@ -289,10 +285,10 @@ pub fn get_all_types(
         FnRetTy::Return(ref return_type) => {
             let mut ret = get_real_types(generics, &return_type, cx, 0);
             if ret.is_empty() {
-                if let Some(did) = return_type.def_id() {
-                    if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
-                        ret.insert((return_type.clone(), kind));
-                    }
+                if let Some(kind) =
+                    return_type.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx))
+                {
+                    ret.insert((return_type.clone(), kind));
                 }
             }
             ret.into_iter().collect()
@@ -580,11 +576,7 @@ pub fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String {
 
 /// Given a type Path, resolve it to a Type using the TyCtxt
 pub fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
-    if id == hir::DUMMY_HIR_ID {
-        debug!("resolve_type({:?})", path);
-    } else {
-        debug!("resolve_type({:?},{:?})", path, id);
-    }
+    debug!("resolve_type({:?},{:?})", path, id);
 
     let is_generic = match path.res {
         Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)),
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index d9f6f7b466a..a8efb16a1d3 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -697,11 +697,11 @@ fn get_generics(clean_type: &clean::Type) -> Option<Vec<Generic>> {
         let r = types
             .iter()
             .filter_map(|t| {
-                if let Some(name) = get_index_type_name(t, false) {
-                    Some(Generic { name: name.to_ascii_lowercase(), defid: t.def_id(), idx: None })
-                } else {
-                    None
-                }
+                get_index_type_name(t, false).map(|name| Generic {
+                    name: name.to_ascii_lowercase(),
+                    defid: t.def_id(),
+                    idx: None,
+                })
             })
             .collect::<Vec<_>>();
         if r.is_empty() { None } else { Some(r) }
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index d091cc0c096..ab524751723 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -184,6 +184,25 @@ nav.sub {
 	overflow: auto;
 }
 
+/* Improve the scrollbar display on firefox */
+* {
+	scrollbar-width: initial;
+}
+.sidebar {
+	scrollbar-width: thin;
+}
+
+/* Improve the scrollbar display on webkit-based browsers */
+::-webkit-scrollbar {
+	width: 12px;
+}
+.sidebar::-webkit-scrollbar {
+	width: 8px;
+}
+::-webkit-scrollbar-track {
+	-webkit-box-shadow: inset 0;
+}
+
 .sidebar .block > ul > li {
 	margin-right: -10px;
 }
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index ff32a0fa09e..a2986c7b927 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -32,6 +32,28 @@ pre {
 	background-color: #505050;
 }
 
+/* Improve the scrollbar display on firefox */
+* {
+	scrollbar-color: rgb(64, 65, 67) #717171;
+}
+.sidebar {
+	scrollbar-color: rgba(32,34,37,.6) transparent;
+}
+
+/* Improve the scrollbar display on webkit-based browsers */
+::-webkit-scrollbar-track {
+	background-color: #717171;
+}
+::-webkit-scrollbar-thumb {
+	background-color: rgba(32, 34, 37, .6);
+}
+.sidebar::-webkit-scrollbar-track {
+	background-color: #717171;
+}
+.sidebar::-webkit-scrollbar-thumb {
+	background-color: rgba(32, 34, 37, .6);
+}
+
 .sidebar .current {
 	background-color: #333;
 }
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index 2b2819f7126..be173d8eb46 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -34,6 +34,29 @@ pre {
 	background-color: #F1F1F1;
 }
 
+/* Improve the scrollbar display on firefox */
+* {
+	scrollbar-color: rgba(36, 37, 39, 0.6) #e6e6e6;
+}
+
+.sidebar {
+	scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9;
+}
+
+/* Improve the scrollbar display on webkit-based browsers */
+::-webkit-scrollbar-track {
+	background-color: #ecebeb;
+}
+::-webkit-scrollbar-thumb {
+	background-color: rgba(36, 37, 39, 0.6);
+}
+.sidebar::-webkit-scrollbar-track {
+	background-color: #dcdcdc;
+}
+.sidebar::-webkit-scrollbar-thumb {
+	background-color: rgba(36, 37, 39, 0.6);
+}
+
 .sidebar .current {
 	background-color: #fff;
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index a6b24d49a83..1821635bde4 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -209,7 +209,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     .filter_by_name_unhygienic(item_name)
                     .next()
                     .and_then(|item| match item.kind {
-                        ty::AssocKind::Method => Some("method"),
+                        ty::AssocKind::Fn => Some("method"),
                         _ => None,
                     })
                     .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name))))
@@ -238,12 +238,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         .find(|item| item.ident.name == item_name);
                     if let Some(item) = item {
                         let out = match item.kind {
-                            ty::AssocKind::Method if ns == ValueNS => "method",
+                            ty::AssocKind::Fn if ns == ValueNS => "method",
                             ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
                             _ => return self.variant_field(path_str, current_item, module_id),
                         };
                         if extra_fragment.is_some() {
-                            Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Method {
+                            Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Fn {
                                 "methods cannot be followed by anchors"
                             } else {
                                 "associated constants cannot be followed by anchors"
@@ -298,14 +298,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         .map(|item| cx.tcx.associated_item(*item))
                         .find(|item| item.ident.name == item_name);
                     if let Some(item) = item {
-                        let kind = match item.kind {
-                            ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
-                            ty::AssocKind::Type if ns == TypeNS => "associatedtype",
-                            ty::AssocKind::Method if ns == ValueNS => {
-                                if item.defaultness.has_value() { "method" } else { "tymethod" }
-                            }
-                            _ => return self.variant_field(path_str, current_item, module_id),
-                        };
+                        let kind =
+                            match item.kind {
+                                ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
+                                ty::AssocKind::Type if ns == TypeNS => "associatedtype",
+                                ty::AssocKind::Fn if ns == ValueNS => {
+                                    if item.defaultness.has_value() { "method" } else { "tymethod" }
+                                }
+                                _ => return self.variant_field(path_str, current_item, module_id),
+                            };
 
                         if extra_fragment.is_some() {
                             Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Const {
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index da0e97f1075..c80967a4b33 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -62,6 +62,8 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
         lang_items.slice_u8_alloc_impl(),
         lang_items.const_ptr_impl(),
         lang_items.mut_ptr_impl(),
+        lang_items.const_slice_ptr_impl(),
+        lang_items.mut_slice_ptr_impl(),
     ];
 
     for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 7841d5eef58..fbbe172afb8 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -263,7 +263,12 @@ fn run_test(
     if no_run && !compile_fail {
         compiler.arg("--emit=metadata");
     }
-    compiler.arg("--target").arg(target.to_string());
+    compiler.arg("--target").arg(match target {
+        TargetTriple::TargetTriple(s) => s,
+        TargetTriple::TargetPath(path) => {
+            path.to_str().expect("target path must be valid unicode").to_string()
+        }
+    });
 
     compiler.arg("-");
     compiler.stdin(Stdio::piped());
@@ -312,8 +317,8 @@ fn run_test(
 
     if let Some(tool) = runtool {
         cmd = Command::new(tool);
-        cmd.arg(output_file);
         cmd.args(runtool_args);
+        cmd.arg(output_file);
     } else {
         cmd = Command::new(output_file);
     }
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 8db7bc12cd3..743a1778fbd 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -25,6 +25,14 @@ fn main() {
         println!("cargo:rustc-link-lib=posix4");
         println!("cargo:rustc-link-lib=pthread");
         println!("cargo:rustc-link-lib=resolv");
+    } else if target.contains("illumos") {
+        println!("cargo:rustc-link-lib=socket");
+        println!("cargo:rustc-link-lib=posix4");
+        println!("cargo:rustc-link-lib=pthread");
+        println!("cargo:rustc-link-lib=resolv");
+        println!("cargo:rustc-link-lib=nsl");
+        // Use libumem for the (malloc-compatible) allocator
+        println!("cargo:rustc-link-lib=umem");
     } else if target.contains("apple-darwin") {
         println!("cargo:rustc-link-lib=System");
 
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index ff222fc8539..5cf9cb73d4b 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -919,7 +919,7 @@ impl f64 {
     // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
     // of expected NaN).
     fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
-        if !cfg!(target_os = "solaris") {
+        if !cfg!(any(target_os = "solaris", target_os = "illumos")) {
             log_fn(self)
         } else {
             if self.is_finite() {
diff --git a/src/libstd/os/illumos/fs.rs b/src/libstd/os/illumos/fs.rs
new file mode 100644
index 00000000000..2abbf1fa9fa
--- /dev/null
+++ b/src/libstd/os/illumos/fs.rs
@@ -0,0 +1,118 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use libc;
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+#[allow(deprecated)]
+use crate::os::illumos::raw;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Gain a reference to the underlying `stat` structure which contains
+    /// the raw information returned by the OS.
+    ///
+    /// The contents of the returned `stat` are **not** consistent across
+    /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
+    /// cross-Unix abstractions contained within the raw stat.
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    #[rustc_deprecated(
+        since = "1.8.0",
+        reason = "deprecated in favor of the accessor methods of this trait"
+    )]
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat;
+
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat {
+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
+    }
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_atime_nsec as i64
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime_nsec as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime_nsec as i64
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+}
diff --git a/src/libstd/os/illumos/mod.rs b/src/libstd/os/illumos/mod.rs
new file mode 100644
index 00000000000..e61926f8935
--- /dev/null
+++ b/src/libstd/os/illumos/mod.rs
@@ -0,0 +1,6 @@
+//! illumos-specific definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod fs;
+pub mod raw;
diff --git a/src/libstd/os/illumos/raw.rs b/src/libstd/os/illumos/raw.rs
new file mode 100644
index 00000000000..88c832ae7c7
--- /dev/null
+++ b/src/libstd/os/illumos/raw.rs
@@ -0,0 +1,74 @@
+//! illumos-specific raw type definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![rustc_deprecated(
+    since = "1.8.0",
+    reason = "these type aliases are no longer supported by the standard library, the `libc` \
+    crate on crates.io should be used instead for the correct definitions"
+)]
+#![allow(deprecated)]
+
+use crate::os::raw::c_long;
+use crate::os::unix::raw::{gid_t, uid_t};
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blkcnt_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blksize_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type dev_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type fflags_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type ino_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type mode_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type nlink_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type off_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type time_t = i64;
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = u32;
+
+#[repr(C)]
+#[derive(Clone)]
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub struct stat {
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_dev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ino: ino_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mode: mode_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_nlink: nlink_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_uid: uid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gid: gid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_rdev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_size: off_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blksize: blksize_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blocks: blkcnt_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub __unused: [u8; 16],
+}
diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs
index 0fa4a1d2353..fd6ee088e96 100644
--- a/src/libstd/os/mod.rs
+++ b/src/libstd/os/mod.rs
@@ -52,6 +52,8 @@ pub mod freebsd;
 pub mod fuchsia;
 #[cfg(target_os = "haiku")]
 pub mod haiku;
+#[cfg(target_os = "illumos")]
+pub mod illumos;
 #[cfg(target_os = "ios")]
 pub mod ios;
 #[cfg(target_os = "macos")]
diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs
index 77417e41331..8e193935460 100644
--- a/src/libstd/sys/unix/alloc.rs
+++ b/src/libstd/sys/unix/alloc.rs
@@ -52,7 +52,12 @@ unsafe impl GlobalAlloc for System {
     }
 }
 
-#[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))]
+#[cfg(any(
+    target_os = "android",
+    target_os = "illumos",
+    target_os = "redox",
+    target_os = "solaris"
+))]
 #[inline]
 unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     // On android we currently target API level 9 which unfortunately
@@ -75,7 +80,12 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     libc::memalign(layout.align(), layout.size()) as *mut u8
 }
 
-#[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))]
+#[cfg(not(any(
+    target_os = "android",
+    target_os = "illumos",
+    target_os = "redox",
+    target_os = "solaris"
+)))]
 #[inline]
 unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     let mut out = ptr::null_mut();
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index 09acc3f6e3e..4c3e8542d57 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -65,6 +65,7 @@ impl DoubleEndedIterator for Args {
     target_os = "netbsd",
     target_os = "openbsd",
     target_os = "solaris",
+    target_os = "illumos",
     target_os = "emscripten",
     target_os = "haiku",
     target_os = "l4re",
diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs
index 984bcfa4509..7f5e9b04dba 100644
--- a/src/libstd/sys/unix/env.rs
+++ b/src/libstd/sys/unix/env.rs
@@ -97,6 +97,17 @@ pub mod os {
     pub const EXE_EXTENSION: &str = "";
 }
 
+#[cfg(target_os = "illumos")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "illumos";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
+}
+
 #[cfg(target_os = "haiku")]
 pub mod os {
     pub const FAMILY: &str = "unix";
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index 8a99836912a..1bba56e334a 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -153,6 +153,7 @@ impl FileDesc {
     #[cfg(not(any(
         target_env = "newlib",
         target_os = "solaris",
+        target_os = "illumos",
         target_os = "emscripten",
         target_os = "fuchsia",
         target_os = "l4re",
@@ -169,6 +170,7 @@ impl FileDesc {
     #[cfg(any(
         target_env = "newlib",
         target_os = "solaris",
+        target_os = "illumos",
         target_os = "emscripten",
         target_os = "fuchsia",
         target_os = "l4re",
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index ab2a871b92d..a233aa47dff 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -22,6 +22,7 @@ use libc::fstatat64;
     target_os = "linux",
     target_os = "emscripten",
     target_os = "solaris",
+    target_os = "illumos",
     target_os = "l4re",
     target_os = "fuchsia",
     target_os = "redox"
@@ -200,7 +201,12 @@ pub struct DirEntry {
     // on Solaris and Fuchsia because a) it uses a zero-length
     // array to store the name, b) its lifetime between readdir
     // calls is not guaranteed.
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
+    #[cfg(any(
+        target_os = "solaris",
+        target_os = "illumos",
+        target_os = "fuchsia",
+        target_os = "redox"
+    ))]
     name: Box<[u8]>,
 }
 
@@ -403,7 +409,12 @@ impl fmt::Debug for ReadDir {
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
 
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
+    #[cfg(any(
+        target_os = "solaris",
+        target_os = "fuchsia",
+        target_os = "redox",
+        target_os = "illumos"
+    ))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         use crate::slice;
 
@@ -441,7 +452,12 @@ impl Iterator for ReadDir {
         }
     }
 
-    #[cfg(not(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox")))]
+    #[cfg(not(any(
+        target_os = "solaris",
+        target_os = "fuchsia",
+        target_os = "redox",
+        target_os = "illumos"
+    )))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         if self.end_of_stream {
             return None;
@@ -514,12 +530,12 @@ impl DirEntry {
         lstat(&self.path())
     }
 
-    #[cfg(any(target_os = "solaris", target_os = "haiku"))]
+    #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "haiku"))]
     pub fn file_type(&self) -> io::Result<FileType> {
         lstat(&self.path()).map(|m| m.file_type())
     }
 
-    #[cfg(not(any(target_os = "solaris", target_os = "haiku")))]
+    #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "haiku")))]
     pub fn file_type(&self) -> io::Result<FileType> {
         match self.entry.d_type {
             libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }),
@@ -540,6 +556,7 @@ impl DirEntry {
         target_os = "emscripten",
         target_os = "android",
         target_os = "solaris",
+        target_os = "illumos",
         target_os = "haiku",
         target_os = "l4re",
         target_os = "fuchsia",
@@ -586,7 +603,12 @@ impl DirEntry {
     fn name_bytes(&self) -> &[u8] {
         unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() }
     }
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
+    #[cfg(any(
+        target_os = "solaris",
+        target_os = "illumos",
+        target_os = "fuchsia",
+        target_os = "redox"
+    ))]
     fn name_bytes(&self) -> &[u8] {
         &*self.name
     }
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index fbcb006ecdf..0154609d939 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -17,6 +17,8 @@ pub use crate::os::freebsd as platform;
 pub use crate::os::fuchsia as platform;
 #[cfg(all(not(doc), target_os = "haiku"))]
 pub use crate::os::haiku as platform;
+#[cfg(all(not(doc), target_os = "illumos"))]
+pub use crate::os::illumos as platform;
 #[cfg(all(not(doc), target_os = "ios"))]
 pub use crate::os::ios as platform;
 #[cfg(all(not(doc), target_os = "l4re"))]
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index b37675e0a0a..d18c22b0573 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -322,11 +322,19 @@ impl Socket {
         Ok(raw != 0)
     }
 
+    #[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         let mut nonblocking = nonblocking as libc::c_int;
         cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(drop)
     }
 
+    #[cfg(any(target_os = "solaris", target_os = "illumos"))]
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        // FIONBIO is inadequate for sockets on illumos/Solaris, so use the
+        // fcntl(F_[GS]ETFL)-based method provided by FileDesc instead.
+        self.0.set_nonblocking(nonblocking)
+    }
+
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
         if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 91f7d1524cc..a9cd5094997 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -54,7 +54,7 @@ extern "C" {
         ),
         link_name = "__errno"
     )]
-    #[cfg_attr(target_os = "solaris", link_name = "___errno")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
     #[cfg_attr(
         any(target_os = "macos", target_os = "ios", target_os = "freebsd"),
         link_name = "__error"
@@ -357,7 +357,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     }
 }
 
-#[cfg(any(target_os = "solaris"))]
+#[cfg(any(target_os = "solaris", target_os = "illumos"))]
 pub fn current_exe() -> io::Result<PathBuf> {
     extern "C" {
         fn getexecname() -> *const c_char;
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 2626ca37cf8..5e103578350 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -33,6 +33,7 @@ impl Drop for Handler {
     target_os = "dragonfly",
     target_os = "freebsd",
     target_os = "solaris",
+    target_os = "illumos",
     all(target_os = "netbsd", not(target_vendor = "rumprun")),
     target_os = "openbsd"
 ))]
@@ -162,7 +163,8 @@ mod imp {
         target_os = "freebsd",
         target_os = "netbsd",
         target_os = "openbsd",
-        target_os = "solaris"
+        target_os = "solaris",
+        target_os = "illumos"
     ))]
     unsafe fn get_stack() -> libc::stack_t {
         libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
@@ -214,6 +216,7 @@ mod imp {
     target_os = "dragonfly",
     target_os = "freebsd",
     target_os = "solaris",
+    target_os = "illumos",
     all(target_os = "netbsd", not(target_vendor = "rumprun")),
     target_os = "openbsd"
 )))]
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index aab5a92a7ad..895ea48e2b4 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -132,7 +132,7 @@ impl Thread {
         }
     }
 
-    #[cfg(target_os = "solaris")]
+    #[cfg(any(target_os = "solaris", target_os = "illumos"))]
     pub fn set_name(name: &CStr) {
         weak! {
             fn pthread_setname_np(
@@ -155,7 +155,7 @@ impl Thread {
         target_os = "redox"
     ))]
     pub fn set_name(_name: &CStr) {
-        // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
+        // Newlib, Haiku, and Emscripten have no way to set a thread name.
     }
     #[cfg(target_os = "fuchsia")]
     pub fn set_name(_name: &CStr) {
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index d508a333484..f85120d170f 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -224,7 +224,7 @@ pub trait OpenOptionsExt {
     /// opening a named pipe, to control to which degree a server process can
     /// act on behalf of a client process (security impersonation level).
     ///
-    /// When `security_qos_flags` is not set a malicious program can gain the
+    /// When `security_qos_flags` is not set, a malicious program can gain the
     /// elevated privileges of a privileged Rust process when it allows opening
     /// user-specified paths, by tricking it into opening a named pipe. So
     /// arguably `security_qos_flags` should also be set when opening arbitrary
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index 135e8308afa..cdd3d2edf1f 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -17,7 +17,7 @@ cfg_if::cfg_if! {
     if #[cfg(any(
         target_os = "dragonfly", target_os = "freebsd",
         target_os = "ios", target_os = "macos",
-        target_os = "openbsd", target_os = "netbsd",
+        target_os = "openbsd", target_os = "netbsd", target_os = "illumos",
         target_os = "solaris", target_os = "haiku", target_os = "l4re"))] {
         use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
         use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
@@ -43,7 +43,7 @@ cfg_if::cfg_if! {
     if #[cfg(any(
         target_os = "dragonfly", target_os = "freebsd",
         target_os = "openbsd", target_os = "netbsd",
-        target_os = "solaris"))] {
+        target_os = "solaris", target_os = "illumos"))] {
         use libc::c_uchar;
         type IpV4MultiCastType = c_uchar;
     } else {
diff --git a/src/libtest/helpers/concurrency.rs b/src/libtest/helpers/concurrency.rs
index 6b0c8a8af32..e8f3820558a 100644
--- a/src/libtest/helpers/concurrency.rs
+++ b/src/libtest/helpers/concurrency.rs
@@ -77,6 +77,7 @@ pub fn get_concurrency() -> usize {
         target_os = "linux",
         target_os = "macos",
         target_os = "solaris",
+        target_os = "illumos",
     ))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs
index 0628e5d2fc0..c8d2419ab45 100644
--- a/src/libunwind/build.rs
+++ b/src/libunwind/build.rs
@@ -30,6 +30,8 @@ fn main() {
         }
     } else if target.contains("solaris") {
         println!("cargo:rustc-link-lib=gcc_s");
+    } else if target.contains("illumos") {
+        println!("cargo:rustc-link-lib=gcc_s");
     } else if target.contains("dragonfly") {
         println!("cargo:rustc-link-lib=gcc_pic");
     } else if target.contains("pc-windows-gnu") {
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 027e428197f3702599cfbb632883768175f4917
+Subproject 9f9da27fbdb0ba7d887f8d2521e082f12b00941
diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs
index 3a022230b39..ad6f4970367 100644
--- a/src/test/compile-fail/issue-52443.rs
+++ b/src/test/compile-fail/issue-52443.rs
@@ -8,4 +8,9 @@ fn main() {
     //~| WARN denote infinite loops with
     [(); { for _ in 0usize.. {}; 0}];
     //~^ ERROR `for` is not allowed in a `const`
+    //~| ERROR calls in constants are limited to constant functions
+    //~| ERROR references in constants may only refer to immutable values
+    //~| ERROR calls in constants are limited to constant functions
+    //~| ERROR constant contains unimplemented expression type
+    //~| ERROR evaluation of constant value failed
 }
diff --git a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir
index af07da4cfe0..d0b5c401bea 100644
--- a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir
@@ -298,7 +298,13 @@ fn address_of_reborrow() -> () {
         StorageDead(_48);                // bb0[157]: scope 13 at $DIR/address-of.rs:36:25: 36:26
         FakeRead(ForLet, _47);           // bb0[158]: scope 13 at $DIR/address-of.rs:36:9: 36:10
         AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // bb0[159]: scope 13 at $DIR/address-of.rs:36:12: 36:22
-        _0 = ();                         // bb0[160]: scope 0 at $DIR/address-of.rs:3:26: 37:2
+        _0 = const ();                   // bb0[160]: scope 0 at $DIR/address-of.rs:3:26: 37:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/address-of.rs:3:26: 37:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_47);                // bb0[161]: scope 13 at $DIR/address-of.rs:37:1: 37:2
         StorageDead(_45);                // bb0[162]: scope 12 at $DIR/address-of.rs:37:1: 37:2
         StorageDead(_44);                // bb0[163]: scope 11 at $DIR/address-of.rs:37:1: 37:2
diff --git a/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir
index 29ccff49202..0ed76f230fd 100644
--- a/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir
@@ -38,7 +38,13 @@ fn borrow_and_cast(_1: i32) -> () {
         _6 = &raw mut (*_7);             // bb0[15]: scope 2 at $DIR/address-of.rs:44:13: 44:19
         FakeRead(ForLet, _6);            // bb0[16]: scope 2 at $DIR/address-of.rs:44:9: 44:10
         StorageDead(_7);                 // bb0[17]: scope 2 at $DIR/address-of.rs:44:31: 44:32
-        _0 = ();                         // bb0[18]: scope 0 at $DIR/address-of.rs:41:32: 45:2
+        _0 = const ();                   // bb0[18]: scope 0 at $DIR/address-of.rs:41:32: 45:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/address-of.rs:41:32: 45:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_6);                 // bb0[19]: scope 2 at $DIR/address-of.rs:45:1: 45:2
         StorageDead(_4);                 // bb0[20]: scope 1 at $DIR/address-of.rs:45:1: 45:2
         StorageDead(_2);                 // bb0[21]: scope 0 at $DIR/address-of.rs:45:1: 45:2
diff --git a/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
index 0016cebbb4c..217d080be4f 100644
--- a/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
@@ -82,7 +82,13 @@ fn main() -> () {
         _1[_7] = move _5;                // bb2[0]: scope 3 at $DIR/array-index-is-temporary.rs:16:5: 16:29
         StorageDead(_5);                 // bb2[1]: scope 3 at $DIR/array-index-is-temporary.rs:16:28: 16:29
         StorageDead(_7);                 // bb2[2]: scope 3 at $DIR/array-index-is-temporary.rs:16:29: 16:30
-        _0 = ();                         // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2
+        _0 = const ();                   // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/array-index-is-temporary.rs:12:11: 17:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_3);                 // bb2[4]: scope 2 at $DIR/array-index-is-temporary.rs:17:1: 17:2
         StorageDead(_2);                 // bb2[5]: scope 1 at $DIR/array-index-is-temporary.rs:17:1: 17:2
         StorageDead(_1);                 // bb2[6]: scope 0 at $DIR/array-index-is-temporary.rs:17:1: 17:2
diff --git a/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
index a004ab4a06a..c75acef2a27 100644
--- a/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
@@ -82,7 +82,13 @@ fn main() -> () {
         _1[_7] = move _5;                // bb2[0]: scope 3 at $DIR/array-index-is-temporary.rs:16:5: 16:29
         StorageDead(_5);                 // bb2[1]: scope 3 at $DIR/array-index-is-temporary.rs:16:28: 16:29
         StorageDead(_7);                 // bb2[2]: scope 3 at $DIR/array-index-is-temporary.rs:16:29: 16:30
-        _0 = ();                         // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2
+        _0 = const ();                   // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/array-index-is-temporary.rs:12:11: 17:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_3);                 // bb2[4]: scope 2 at $DIR/array-index-is-temporary.rs:17:1: 17:2
         StorageDead(_2);                 // bb2[5]: scope 1 at $DIR/array-index-is-temporary.rs:17:1: 17:2
         StorageDead(_1);                 // bb2[6]: scope 0 at $DIR/array-index-is-temporary.rs:17:1: 17:2
diff --git a/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir
index a3f4573964c..86ee1be6f74 100644
--- a/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir
@@ -72,7 +72,13 @@ fn main() -> () {
 
     bb6: {
         StorageDead(_6);                 // bb6[0]: scope 4 at $DIR/basic_assignment.rs:23:19: 23:20
-        _0 = ();                         // bb6[1]: scope 0 at $DIR/basic_assignment.rs:10:11: 24:2
+        _0 = const ();                   // bb6[1]: scope 0 at $DIR/basic_assignment.rs:10:11: 24:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/basic_assignment.rs:10:11: 24:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         drop(_5) -> [return: bb7, unwind: bb3]; // bb6[2]: scope 3 at $DIR/basic_assignment.rs:24:1: 24:2
     }
 
diff --git a/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir b/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir
index 61986535dd3..aef0da9d6f0 100644
--- a/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir
+++ b/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir
@@ -53,7 +53,13 @@ fn main() -> () {
     bb5: {
         StorageDead(_4);                 // bb5[0]: scope 1 at $DIR/box_expr.rs:8:11: 8:12
         StorageDead(_3);                 // bb5[1]: scope 1 at $DIR/box_expr.rs:8:12: 8:13
-        _0 = ();                         // bb5[2]: scope 0 at $DIR/box_expr.rs:6:11: 9:2
+        _0 = const ();                   // bb5[2]: scope 0 at $DIR/box_expr.rs:6:11: 9:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/box_expr.rs:6:11: 9:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         drop(_1) -> bb8;                 // bb5[3]: scope 0 at $DIR/box_expr.rs:9:1: 9:2
     }
 
diff --git a/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir
index 14be9c990bd..84f4e5bfd63 100644
--- a/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir
@@ -34,7 +34,13 @@ fn main() -> () {
                                          // mir::Constant
                                          // + span: $DIR/byte_slice.rs:6:19: 6:23
                                          // + literal: Const { ty: u8, val: Value(Scalar(0x78)) }
-        _0 = ();                         // bb0[4]: scope 0 at $DIR/byte_slice.rs:4:11: 7:2
+        _0 = const ();                   // bb0[4]: scope 0 at $DIR/byte_slice.rs:4:11: 7:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/byte_slice.rs:4:11: 7:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_2);                 // bb0[5]: scope 1 at $DIR/byte_slice.rs:7:1: 7:2
         StorageDead(_1);                 // bb0[6]: scope 0 at $DIR/byte_slice.rs:7:1: 7:2
         return;                          // bb0[7]: scope 0 at $DIR/byte_slice.rs:7:2: 7:2
diff --git a/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir
index 58806724508..2247b8e155a 100644
--- a/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir
+++ b/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir
@@ -18,7 +18,13 @@ fn main() -> () {
         _1 = (*_2);                      // bb0[3]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         StorageDead(_2);                 // bb0[4]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
         StorageDead(_1);                 // bb0[5]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
-        _0 = ();                         // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2
+        _0 = const ();                   // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/const_allocation.rs:7:11: 9:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb0[7]: scope 0 at $DIR/const_allocation.rs:9:2: 9:2
     }
 }
diff --git a/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir
index b60d23aa3f1..d6cca185ab0 100644
--- a/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir
+++ b/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir
@@ -18,7 +18,13 @@ fn main() -> () {
         _1 = (*_2);                      // bb0[3]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         StorageDead(_2);                 // bb0[4]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
         StorageDead(_1);                 // bb0[5]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
-        _0 = ();                         // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2
+        _0 = const ();                   // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/const_allocation.rs:7:11: 9:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb0[7]: scope 0 at $DIR/const_allocation.rs:9:2: 9:2
     }
 }
diff --git a/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir
index 6caecf1ecea..4105d673218 100644
--- a/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir
+++ b/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir
@@ -18,7 +18,13 @@ fn main() -> () {
         _1 = (*_2);                      // bb0[3]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         StorageDead(_2);                 // bb0[4]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
         StorageDead(_1);                 // bb0[5]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
-        _0 = ();                         // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2
+        _0 = const ();                   // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/const_allocation2.rs:4:11: 6:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb0[7]: scope 0 at $DIR/const_allocation2.rs:6:2: 6:2
     }
 }
diff --git a/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir
index 52e7c2aec2b..e61f0a8b69f 100644
--- a/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir
+++ b/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir
@@ -18,7 +18,13 @@ fn main() -> () {
         _1 = (*_2);                      // bb0[3]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         StorageDead(_2);                 // bb0[4]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
         StorageDead(_1);                 // bb0[5]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
-        _0 = ();                         // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2
+        _0 = const ();                   // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/const_allocation2.rs:4:11: 6:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb0[7]: scope 0 at $DIR/const_allocation2.rs:6:2: 6:2
     }
 }
diff --git a/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir
index 4fc2c4c3fb3..323134553c1 100644
--- a/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir
+++ b/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir
@@ -18,7 +18,13 @@ fn main() -> () {
         _1 = (*_2);                      // bb0[3]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
         StorageDead(_2);                 // bb0[4]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
         StorageDead(_1);                 // bb0[5]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
-        _0 = ();                         // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2
+        _0 = const ();                   // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/const_allocation3.rs:4:11: 6:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb0[7]: scope 0 at $DIR/const_allocation3.rs:6:2: 6:2
     }
 }
diff --git a/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir
index ae5ebe70437..952fe8336cd 100644
--- a/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir
+++ b/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir
@@ -18,7 +18,13 @@ fn main() -> () {
         _1 = (*_2);                      // bb0[3]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
         StorageDead(_2);                 // bb0[4]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
         StorageDead(_1);                 // bb0[5]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
-        _0 = ();                         // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2
+        _0 = const ();                   // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/const_allocation3.rs:4:11: 6:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb0[7]: scope 0 at $DIR/const_allocation3.rs:6:2: 6:2
     }
 }
diff --git a/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff
index d20019287b0..50e6cfc37ee 100644
--- a/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff
@@ -54,7 +54,13 @@
 +                                          // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
           StorageDead(_2);                 // bb0[6]: scope 0 at $DIR/aggregate.rs:5:27: 5:28
           StorageDead(_3);                 // bb0[7]: scope 0 at $DIR/aggregate.rs:5:28: 5:29
-          _0 = ();                         // bb0[8]: scope 0 at $DIR/aggregate.rs:4:11: 6:2
+          _0 = const ();                   // bb0[8]: scope 0 at $DIR/aggregate.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/aggregate.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb0[9]: scope 0 at $DIR/aggregate.rs:6:1: 6:2
           return;                          // bb0[10]: scope 0 at $DIR/aggregate.rs:6:2: 6:2
       }
diff --git a/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff
index 99d79b23e9e..474d50100b0 100644
--- a/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff
@@ -84,7 +84,13 @@
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
           StorageDead(_3);                 // bb1[1]: scope 0 at $DIR/array_index.rs:5:33: 5:34
           StorageDead(_2);                 // bb1[2]: scope 0 at $DIR/array_index.rs:5:33: 5:34
-          _0 = ();                         // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2
+          _0 = const ();                   // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/array_index.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[4]: scope 0 at $DIR/array_index.rs:6:1: 6:2
           return;                          // bb1[5]: scope 0 at $DIR/array_index.rs:6:2: 6:2
       }
diff --git a/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff
index 629ca226f2a..b3d353bd487 100644
--- a/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff
@@ -84,7 +84,13 @@
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
           StorageDead(_3);                 // bb1[1]: scope 0 at $DIR/array_index.rs:5:33: 5:34
           StorageDead(_2);                 // bb1[2]: scope 0 at $DIR/array_index.rs:5:33: 5:34
-          _0 = ();                         // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2
+          _0 = const ();                   // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/array_index.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[4]: scope 0 at $DIR/array_index.rs:6:1: 6:2
           return;                          // bb1[5]: scope 0 at $DIR/array_index.rs:6:2: 6:2
       }
diff --git a/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff
index 50ee2abecfe..bf5aff0cf46 100644
--- a/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff
@@ -44,7 +44,13 @@
   
       bb2: {
           StorageDead(_3);                 // bb2[0]: scope 0 at $DIR/boxes.rs:12:26: 12:27
-          _0 = ();                         // bb2[1]: scope 0 at $DIR/boxes.rs:11:11: 13:2
+          _0 = const ();                   // bb2[1]: scope 0 at $DIR/boxes.rs:11:11: 13:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/boxes.rs:11:11: 13:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb2[2]: scope 0 at $DIR/boxes.rs:13:1: 13:2
           return;                          // bb2[3]: scope 0 at $DIR/boxes.rs:13:2: 13:2
       }
diff --git a/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff
index ee6a0e87b12..ca0a309b1b5 100644
--- a/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff
@@ -39,7 +39,13 @@
 +                                          // mir::Constant
 +                                          // + span: $DIR/cast.rs:6:13: 6:24
 +                                          // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
-          _0 = ();                         // bb0[4]: scope 0 at $DIR/cast.rs:3:11: 7:2
+          _0 = const ();                   // bb0[4]: scope 0 at $DIR/cast.rs:3:11: 7:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/cast.rs:3:11: 7:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_2);                 // bb0[5]: scope 1 at $DIR/cast.rs:7:1: 7:2
           StorageDead(_1);                 // bb0[6]: scope 0 at $DIR/cast.rs:7:1: 7:2
           return;                          // bb0[7]: scope 0 at $DIR/cast.rs:7:2: 7:2
diff --git a/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff
index 0a0a4ff852f..762927575f0 100644
--- a/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff
@@ -51,7 +51,13 @@
 +                                          // mir::Constant
 +                                          // + span: $DIR/checked_add.rs:5:18: 5:23
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
-          _0 = ();                         // bb1[1]: scope 0 at $DIR/checked_add.rs:4:11: 6:2
+          _0 = const ();                   // bb1[1]: scope 0 at $DIR/checked_add.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/checked_add.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[2]: scope 0 at $DIR/checked_add.rs:6:1: 6:2
           return;                          // bb1[3]: scope 0 at $DIR/checked_add.rs:6:2: 6:2
       }
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff
index f4a5b64f0d9..d3a6105a852 100644
--- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff
@@ -42,7 +42,13 @@
       bb1: {
           StorageDead(_5);                 // bb1[0]: scope 1 at $DIR/const_prop_fails_gracefully.rs:8:11: 8:12
           StorageDead(_4);                 // bb1[1]: scope 1 at $DIR/const_prop_fails_gracefully.rs:8:12: 8:13
-          _0 = ();                         // bb1[2]: scope 0 at $DIR/const_prop_fails_gracefully.rs:5:11: 9:2
+          _0 = const ();                   // bb1[2]: scope 0 at $DIR/const_prop_fails_gracefully.rs:5:11: 9:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/const_prop_fails_gracefully.rs:5:11: 9:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[3]: scope 0 at $DIR/const_prop_fails_gracefully.rs:9:1: 9:2
           return;                          // bb1[4]: scope 0 at $DIR/const_prop_fails_gracefully.rs:9:2: 9:2
       }
diff --git a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff
index c551bd77d40..cbda5e4ef86 100644
--- a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff
@@ -29,7 +29,13 @@
       }
   
       bb1: {
-          _0 = ();                         // bb1[0]: scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
+          _0 = const ();                   // bb1[0]: scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/control-flow-simplification.rs:12:5: 14:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[1]: scope 0 at $DIR/control-flow-simplification.rs:15:1: 15:2
           return;                          // bb1[2]: scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2
       }
diff --git a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir
index 53296f8714b..73922b56669 100644
--- a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir
+++ b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir
@@ -4,6 +4,13 @@ fn hello() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/control-flow-simplification.rs:11:14: 11:14
 
     bb0: {
-        return;                          // bb0[0]: scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2
+        _0 = const ();                   // bb0[0]: scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/control-flow-simplification.rs:12:5: 14:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+        return;                          // bb0[1]: scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2
     }
 }
diff --git a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff
index 7423a3cd38d..f89d869cab5 100644
--- a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff
@@ -87,7 +87,13 @@
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
           StorageDead(_2);                 // bb4[1]: scope 0 at $DIR/discriminant.rs:6:67: 6:68
           StorageDead(_3);                 // bb4[2]: scope 0 at $DIR/discriminant.rs:6:68: 6:69
-          _0 = ();                         // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2
+          _0 = const ();                   // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/discriminant.rs:5:11: 7:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb4[4]: scope 0 at $DIR/discriminant.rs:7:1: 7:2
           return;                          // bb4[5]: scope 0 at $DIR/discriminant.rs:7:2: 7:2
       }
diff --git a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff
index 60d18cdc942..06f43db50f4 100644
--- a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff
@@ -87,7 +87,13 @@
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
           StorageDead(_2);                 // bb4[1]: scope 0 at $DIR/discriminant.rs:6:67: 6:68
           StorageDead(_3);                 // bb4[2]: scope 0 at $DIR/discriminant.rs:6:68: 6:69
-          _0 = ();                         // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2
+          _0 = const ();                   // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/discriminant.rs:5:11: 7:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb4[4]: scope 0 at $DIR/discriminant.rs:7:1: 7:2
           return;                          // bb4[5]: scope 0 at $DIR/discriminant.rs:7:2: 7:2
       }
diff --git a/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff
index ca3e3bb5d2d..4c80d0d1278 100644
--- a/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff
@@ -62,7 +62,13 @@
 +                                          // + span: $DIR/indirect.rs:5:13: 5:29
 +                                          // + literal: Const { ty: u8, val: Value(Scalar(0x03)) }
           StorageDead(_2);                 // bb1[1]: scope 0 at $DIR/indirect.rs:5:28: 5:29
-          _0 = ();                         // bb1[2]: scope 0 at $DIR/indirect.rs:4:11: 6:2
+          _0 = const ();                   // bb1[2]: scope 0 at $DIR/indirect.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/indirect.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[3]: scope 0 at $DIR/indirect.rs:6:1: 6:2
           return;                          // bb1[4]: scope 0 at $DIR/indirect.rs:6:2: 6:2
       }
diff --git a/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff
index d3ebaa0a632..76c6759f700 100644
--- a/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff
@@ -45,7 +45,13 @@
       bb1: {
           StorageDead(_2);                 // bb1[0]: scope 0 at $DIR/issue-66971.rs:16:22: 16:23
           StorageDead(_1);                 // bb1[1]: scope 0 at $DIR/issue-66971.rs:16:23: 16:24
-          _0 = ();                         // bb1[2]: scope 0 at $DIR/issue-66971.rs:15:11: 17:2
+          _0 = const ();                   // bb1[2]: scope 0 at $DIR/issue-66971.rs:15:11: 17:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/issue-66971.rs:15:11: 17:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb1[3]: scope 0 at $DIR/issue-66971.rs:17:2: 17:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff
index 96a20edd91a..05e1a615953 100644
--- a/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff
@@ -40,7 +40,13 @@
       bb1: {
           StorageDead(_2);                 // bb1[0]: scope 0 at $DIR/issue-67019.rs:11:19: 11:20
           StorageDead(_1);                 // bb1[1]: scope 0 at $DIR/issue-67019.rs:11:20: 11:21
-          _0 = ();                         // bb1[2]: scope 0 at $DIR/issue-67019.rs:10:11: 12:2
+          _0 = const ();                   // bb1[2]: scope 0 at $DIR/issue-67019.rs:10:11: 12:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/issue-67019.rs:10:11: 12:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb1[3]: scope 0 at $DIR/issue-67019.rs:12:2: 12:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff
index 41ffedf06bc..2868365e9ac 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff
@@ -171,7 +171,13 @@
 +                                          // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
           StorageDead(_9);                 // bb2[7]: scope 2 at $DIR/optimizes_into_variable.rs:14:38: 14:39
-          _0 = ();                         // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
+          _0 = const ();                   // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_8);                 // bb2[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2
           StorageDead(_3);                 // bb2[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2
           StorageDead(_1);                 // bb2[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir
index db4d2d13792..5e2a8af060b 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir
@@ -80,9 +80,16 @@ fn main() -> () {
                                          // mir::Constant
                                          // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
-        StorageDead(_4);                 // bb0[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2
-        StorageDead(_2);                 // bb0[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2
-        StorageDead(_1);                 // bb0[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2
-        return;                          // bb0[12]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2
+        _0 = const ();                   // bb0[9]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+        StorageDead(_4);                 // bb0[10]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2
+        StorageDead(_2);                 // bb0[11]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2
+        StorageDead(_1);                 // bb0[12]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2
+        return;                          // bb0[13]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2
     }
 }
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff
index fd3281f5273..0097d9448c8 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff
@@ -171,7 +171,13 @@
 +                                          // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
           StorageDead(_9);                 // bb2[7]: scope 2 at $DIR/optimizes_into_variable.rs:14:38: 14:39
-          _0 = ();                         // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
+          _0 = const ();                   // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_8);                 // bb2[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2
           StorageDead(_3);                 // bb2[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2
           StorageDead(_1);                 // bb2[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir
index db4d2d13792..5e2a8af060b 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir
@@ -80,9 +80,16 @@ fn main() -> () {
                                          // mir::Constant
                                          // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38
                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) }
-        StorageDead(_4);                 // bb0[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2
-        StorageDead(_2);                 // bb0[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2
-        StorageDead(_1);                 // bb0[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2
-        return;                          // bb0[12]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2
+        _0 = const ();                   // bb0[9]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+        StorageDead(_4);                 // bb0[10]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2
+        StorageDead(_2);                 // bb0[11]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2
+        StorageDead(_1);                 // bb0[12]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2
+        return;                          // bb0[13]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2
     }
 }
diff --git a/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff
index 6183b22a95f..d9852539844 100644
--- a/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff
@@ -60,7 +60,13 @@
           StorageDead(_2);                 // bb0[11]: scope 0 at $DIR/read_immutable_static.rs:7:21: 7:22
           StorageDead(_5);                 // bb0[12]: scope 0 at $DIR/read_immutable_static.rs:7:22: 7:23
           StorageDead(_3);                 // bb0[13]: scope 0 at $DIR/read_immutable_static.rs:7:22: 7:23
-          _0 = ();                         // bb0[14]: scope 0 at $DIR/read_immutable_static.rs:6:11: 8:2
+          _0 = const ();                   // bb0[14]: scope 0 at $DIR/read_immutable_static.rs:6:11: 8:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/read_immutable_static.rs:6:11: 8:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb0[15]: scope 0 at $DIR/read_immutable_static.rs:8:1: 8:2
           return;                          // bb0[16]: scope 0 at $DIR/read_immutable_static.rs:8:2: 8:2
       }
diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff
index 0f8563daba5..591fdaddfcc 100644
--- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff
@@ -29,7 +29,13 @@
 +                                          // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
           StorageDead(_2);                 // bb0[5]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11
           StorageDead(_1);                 // bb0[6]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11
-          _0 = ();                         // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2
+          _0 = const ();                   // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/ref_deref.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb0[8]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff
index ea1baa40f7e..5cd9f43a5c6 100644
--- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff
+++ b/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff
@@ -27,15 +27,21 @@
 -         StorageDead(_3);                 // bb0[6]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11
 -         StorageDead(_2);                 // bb0[7]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11
 -         StorageDead(_1);                 // bb0[8]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11
--         _0 = ();                         // bb0[9]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2
--         return;                          // bb0[10]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2
+-         _0 = const ();                   // bb0[9]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2
 +                                          // + span: $DIR/ref_deref.rs:5:6: 5:10
 +                                          // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) }
 +         _2 = &(*_4);                     // bb0[3]: scope 0 at $DIR/ref_deref.rs:5:6: 5:10
 +         _1 = (*_2);                      // bb0[4]: scope 0 at $DIR/ref_deref.rs:5:5: 5:10
 +         StorageDead(_2);                 // bb0[5]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11
 +         StorageDead(_1);                 // bb0[6]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11
-+         _0 = ();                         // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2
++         _0 = const ();                   // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/ref_deref.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+-         return;                          // bb0[10]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2
 +         return;                          // bb0[8]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff
index c4b3d6b6c27..6393bad2993 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff
@@ -22,7 +22,13 @@
           _1 = (*_2);                      // bb0[4]: scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
           StorageDead(_2);                 // bb0[5]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
           StorageDead(_1);                 // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
-          _0 = ();                         // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2
+          _0 = const ();                   // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/ref_deref_project.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb0[8]: scope 0 at $DIR/ref_deref_project.rs:6:2: 6:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff
index 852436e13b6..020ad7278c0 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff
+++ b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff
@@ -22,7 +22,14 @@
                                            // mir::Constant
 -                                          // + span: $DIR/ref_deref_project.rs:5:9: 5:10
 -                                          // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
--                                          // ty::Const
++                                          // + span: $DIR/ref_deref_project.rs:5:6: 5:17
++                                          // + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) }
++         _2 = &((*_4).1: i32);            // bb0[3]: scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
++         _1 = (*_2);                      // bb0[4]: scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
++         StorageDead(_2);                 // bb0[5]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
++         StorageDead(_1);                 // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
++         _0 = const ();                   // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2
+                                           // ty::Const
 -                                          // + ty: i32
 -                                          // + val: Value(Scalar(0x00000005))
 -                                          // mir::Constant
@@ -33,15 +40,14 @@
 -         StorageDead(_3);                 // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
 -         StorageDead(_2);                 // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
 -         StorageDead(_1);                 // bb0[8]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
--         _0 = ();                         // bb0[9]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2
+-         _0 = const ();                   // bb0[9]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2
+-                                          // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/ref_deref_project.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         return;                          // bb0[10]: scope 0 at $DIR/ref_deref_project.rs:6:2: 6:2
-+                                          // + span: $DIR/ref_deref_project.rs:5:6: 5:17
-+                                          // + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) }
-+         _2 = &((*_4).1: i32);            // bb0[3]: scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
-+         _1 = (*_2);                      // bb0[4]: scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
-+         StorageDead(_2);                 // bb0[5]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
-+         StorageDead(_1);                 // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
-+         _0 = ();                         // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2
 +         return;                          // bb0[8]: scope 0 at $DIR/ref_deref_project.rs:6:2: 6:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff
index 7a41a8ad74e..388ebe08689 100644
--- a/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff
@@ -25,7 +25,13 @@
           _1 = move _2 as *const fn() (Misc); // bb0[6]: scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:41
           StorageDead(_2);                 // bb0[7]: scope 0 at $DIR/reify_fn_ptr.rs:4:40: 4:41
           StorageDead(_1);                 // bb0[8]: scope 0 at $DIR/reify_fn_ptr.rs:4:41: 4:42
-          _0 = ();                         // bb0[9]: scope 0 at $DIR/reify_fn_ptr.rs:3:11: 5:2
+          _0 = const ();                   // bb0[9]: scope 0 at $DIR/reify_fn_ptr.rs:3:11: 5:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/reify_fn_ptr.rs:3:11: 5:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb0[10]: scope 0 at $DIR/reify_fn_ptr.rs:5:2: 5:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff
index 9d62fa31a45..921de794722 100644
--- a/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff
@@ -80,7 +80,13 @@
           StorageDead(_2);                 // bb1[2]: scope 0 at $DIR/repeat.rs:6:31: 6:32
           StorageDead(_4);                 // bb1[3]: scope 0 at $DIR/repeat.rs:6:32: 6:33
           StorageDead(_3);                 // bb1[4]: scope 0 at $DIR/repeat.rs:6:32: 6:33
-          _0 = ();                         // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2
+          _0 = const ();                   // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/repeat.rs:5:11: 7:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[6]: scope 0 at $DIR/repeat.rs:7:1: 7:2
           return;                          // bb1[7]: scope 0 at $DIR/repeat.rs:7:2: 7:2
       }
diff --git a/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff
index cb84ee82cfe..361ee493378 100644
--- a/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff
@@ -80,7 +80,13 @@
           StorageDead(_2);                 // bb1[2]: scope 0 at $DIR/repeat.rs:6:31: 6:32
           StorageDead(_4);                 // bb1[3]: scope 0 at $DIR/repeat.rs:6:32: 6:33
           StorageDead(_3);                 // bb1[4]: scope 0 at $DIR/repeat.rs:6:32: 6:33
-          _0 = ();                         // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2
+          _0 = const ();                   // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/repeat.rs:5:11: 7:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb1[6]: scope 0 at $DIR/repeat.rs:7:1: 7:2
           return;                          // bb1[7]: scope 0 at $DIR/repeat.rs:7:2: 7:2
       }
diff --git a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff
index dbb4171e7f0..01818095455 100644
--- a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff
@@ -76,7 +76,13 @@
           StorageDead(_4);                 // bb1[2]: scope 0 at $DIR/slice_len.rs:5:33: 5:34
           StorageDead(_2);                 // bb1[3]: scope 0 at $DIR/slice_len.rs:5:33: 5:34
           StorageDead(_1);                 // bb1[4]: scope 0 at $DIR/slice_len.rs:5:33: 5:34
-          _0 = ();                         // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2
+          _0 = const ();                   // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/slice_len.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb1[6]: scope 0 at $DIR/slice_len.rs:6:2: 6:2
       }
   }
diff --git a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff
index 3c4415e0558..f1379446d7a 100644
--- a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff
@@ -76,7 +76,13 @@
           StorageDead(_4);                 // bb1[2]: scope 0 at $DIR/slice_len.rs:5:33: 5:34
           StorageDead(_2);                 // bb1[3]: scope 0 at $DIR/slice_len.rs:5:33: 5:34
           StorageDead(_1);                 // bb1[4]: scope 0 at $DIR/slice_len.rs:5:33: 5:34
-          _0 = ();                         // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2
+          _0 = const ();                   // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/slice_len.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb1[6]: scope 0 at $DIR/slice_len.rs:6:2: 6:2
       }
   }
diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff
index 8bdc91109b3..16bdb7d0a99 100644
--- a/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff
+++ b/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff
@@ -30,7 +30,13 @@
                                            // mir::Constant
                                            // + span: $DIR/copy_propagation_arg.rs:17:5: 17:10
                                            // + literal: Const { ty: u8, val: Value(Scalar(0x05)) }
-          nop;                             // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:15:19: 18:2
+          _0 = const ();                   // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:15:19: 18:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/copy_propagation_arg.rs:15:19: 18:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb1[4]: scope 0 at $DIR/copy_propagation_arg.rs:18:2: 18:2
       }
   }
diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff
index 10f2a98b206..7df995c990a 100644
--- a/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff
+++ b/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff
@@ -11,7 +11,13 @@
           _2 = _1;                         // bb0[1]: scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10
           _1 = move _2;                    // bb0[2]: scope 0 at $DIR/copy_propagation_arg.rs:23:5: 23:10
           StorageDead(_2);                 // bb0[3]: scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10
-          nop;                             // bb0[4]: scope 0 at $DIR/copy_propagation_arg.rs:21:20: 24:2
+          _0 = const ();                   // bb0[4]: scope 0 at $DIR/copy_propagation_arg.rs:21:20: 24:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/copy_propagation_arg.rs:21:20: 24:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb0[5]: scope 0 at $DIR/copy_propagation_arg.rs:24:2: 24:2
       }
   }
diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff
index a47880c540e..67b58c30f05 100644
--- a/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff
+++ b/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff
@@ -24,7 +24,13 @@
           StorageDead(_3);                 // bb1[0]: scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17
           _1 = move _2;                    // bb1[1]: scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17
           StorageDead(_2);                 // bb1[2]: scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17
-          nop;                             // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:9:19: 12:2
+          _0 = const ();                   // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:9:19: 12:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/copy_propagation_arg.rs:9:19: 12:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb1[4]: scope 0 at $DIR/copy_propagation_arg.rs:12:2: 12:2
       }
   }
diff --git a/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir b/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir
index cc22982a515..50a48f2eee4 100644
--- a/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir
+++ b/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir
@@ -112,7 +112,13 @@ yields ()
     bb10: {
         StorageDead(_10);                // bb10[0]: scope 2 at $DIR/generator-storage-dead-unwind.rs:27:15: 27:16
         StorageDead(_9);                 // bb10[1]: scope 2 at $DIR/generator-storage-dead-unwind.rs:27:16: 27:17
-        _0 = ();                         // bb10[2]: scope 0 at $DIR/generator-storage-dead-unwind.rs:22:19: 28:6
+        _0 = const ();                   // bb10[2]: scope 0 at $DIR/generator-storage-dead-unwind.rs:22:19: 28:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/generator-storage-dead-unwind.rs:22:19: 28:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_4);                 // bb10[3]: scope 1 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6
         StorageDead(_3);                 // bb10[4]: scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6
         drop(_1) -> [return: bb12, unwind: bb1]; // bb10[5]: scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6
diff --git a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir b/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir
index a79f0d53f3c..2e3354699fb 100644
--- a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir
+++ b/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir
@@ -54,7 +54,13 @@ fn main::{{closure}}#0(_1: std::pin::Pin<&mut [generator@$DIR/generator-tiny.rs:
 
     bb4: {
         StorageDead(_8);                 // bb4[0]: scope 1 at $DIR/generator-tiny.rs:22:21: 22:22
-        _5 = ();                         // bb4[1]: scope 1 at $DIR/generator-tiny.rs:20:14: 23:10
+        _5 = const ();                   // bb4[1]: scope 1 at $DIR/generator-tiny.rs:20:14: 23:10
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/generator-tiny.rs:20:14: 23:10
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb2;                     // bb4[2]: scope 1 at $DIR/generator-tiny.rs:20:9: 23:10
     }
 
diff --git a/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot b/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot
index 2caef3459b8..f5d8b84812a 100644
--- a/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot
+++ b/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot
@@ -3,7 +3,7 @@ digraph Mir_0_3 {
     node [fontname="monospace"];
     edge [fontname="monospace"];
     label=<fn main() -&gt; ()<br align="left"/>>;
-    bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>];
+    bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = const ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>];
     bb1__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table>>];
     bb2__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left">return</td></tr></table>>];
     bb0__0_3 -> bb2__0_3 [label=""];
diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs
index d36d93cd01c..77834e9661c 100644
--- a/src/test/mir-opt/inline/inline-into-box-place.rs
+++ b/src/test/mir-opt/inline/inline-into-box-place.rs
@@ -1,6 +1,6 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -Z mir-opt-level=3
-// only-64bit FIXME: the mir representation of RawVec depends on ptr size
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
 #![feature(box_syntax)]
 
 // EMIT_MIR rustc.main.Inline.diff
diff --git a/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff
new file mode 100644
index 00000000000..6983e94ff8d
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff
@@ -0,0 +1,85 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inline-into-box-place.rs:7:11: 7:11
+      let _1: std::boxed::Box<std::vec::Vec<u32>> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11
+      let mut _2: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _3: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
++     let mut _4: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+      scope 1 {
+          debug _x => _1;                  // in scope 1 at $DIR/inline-into-box-place.rs:8:9: 8:11
+      }
++     scope 2 {
++     }
+  
+      bb0: {
+          StorageLive(_1);                 // bb0[0]: scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11
+          StorageLive(_2);                 // bb0[1]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+          _2 = Box(std::vec::Vec<u32>);    // bb0[2]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+-         (*_2) = const std::vec::Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         _4 = &mut (*_2);                 // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         ((*_4).0: alloc::raw_vec::RawVec<u32>) = const ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }: alloc::raw_vec::RawVec::<u32>; // bb0[4]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL
+                                           // ty::Const
+-                                          // + ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}
+-                                          // + val: Value(Scalar(<ZST>))
++                                          // + ty: alloc::raw_vec::RawVec<u32>
++                                          // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
+                                           // mir::Constant
+-                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
+-                                          // + user_ty: UserType(1)
+-                                          // + literal: Const { ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}, val: Value(Scalar(<ZST>)) }
+-     }
+- 
+-     bb1 (cleanup): {
+-         resume;                          // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
+-     }
+- 
+-     bb2: {
+-         _1 = move _2;                    // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+-         StorageDead(_2);                 // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-         _0 = const ();                   // bb2[2]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
++                                          // + span: $SRC_DIR/liballoc/vec.rs:LL:COL
++                                          // + user_ty: UserType(0)
++                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
++         ((*_4).1: usize) = const 0usize; // bb0[5]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL
+                                           // ty::Const
++                                          // + ty: usize
++                                          // + val: Value(Scalar(0x00000000))
++                                          // mir::Constant
++                                          // + span: $SRC_DIR/liballoc/vec.rs:LL:COL
++                                          // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) }
++         _1 = move _2;                    // bb0[6]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
++         StorageDead(_2);                 // bb0[7]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
++         _0 = const ();                   // bb0[8]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
++                                          // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/inline-into-box-place.rs:7:11: 9:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+-         drop(_1) -> [return: bb3, unwind: bb1]; // bb2[3]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
++         drop(_1) -> [return: bb2, unwind: bb1]; // bb0[9]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
+      }
+  
+-     bb3: {
+-         StorageDead(_1);                 // bb3[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
+-         return;                          // bb3[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2
++     bb1 (cleanup): {
++         resume;                          // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
+      }
+  
+-     bb4 (cleanup): {
+-         _3 = const alloc::alloc::box_free::<std::vec::Vec<u32>>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>)) -> bb1; // bb4[0]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-                                          // ty::Const
+-                                          // + ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>) {alloc::alloc::box_free::<std::vec::Vec<u32>>}
+-                                          // + val: Value(Scalar(<ZST>))
+-                                          // mir::Constant
+-                                          // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
+-                                          // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>) {alloc::alloc::box_free::<std::vec::Vec<u32>>}, val: Value(Scalar(<ZST>)) }
++     bb2: {
++         StorageDead(_1);                 // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
++         return;                          // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/inline/inline-into-box-place/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff
index a0db20cbb74..38ab9ce9926 100644
--- a/src/test/mir-opt/inline/inline-into-box-place/rustc.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff
@@ -29,11 +29,21 @@
 -                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
 -                                          // + user_ty: UserType(1)
 -                                          // + literal: Const { ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}, val: Value(Scalar(<ZST>)) }
+-     }
+- 
+-     bb1 (cleanup): {
+-         resume;                          // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
+-     }
+- 
+-     bb2: {
+-         _1 = move _2;                    // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+-         StorageDead(_2);                 // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-         _0 = const ();                   // bb2[2]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
 +                                          // + span: $SRC_DIR/liballoc/vec.rs:LL:COL
 +                                          // + user_ty: UserType(0)
 +                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [65535], len: Size { raw: 16 } }, size: Size { raw: 16 }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
 +         ((*_4).1: usize) = const 0usize; // bb0[5]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL
-+                                          // ty::Const
+                                           // ty::Const
 +                                          // + ty: usize
 +                                          // + val: Value(Scalar(0x0000000000000000))
 +                                          // mir::Constant
@@ -41,26 +51,24 @@
 +                                          // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
 +         _1 = move _2;                    // bb0[6]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
 +         StorageDead(_2);                 // bb0[7]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
-+         _0 = ();                         // bb0[8]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
++         _0 = const ();                   // bb0[8]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
++                                          // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/inline-into-box-place.rs:7:11: 9:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+-         drop(_1) -> [return: bb3, unwind: bb1]; // bb2[3]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
 +         drop(_1) -> [return: bb2, unwind: bb1]; // bb0[9]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
       }
   
-      bb1 (cleanup): {
-          resume;                          // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
-      }
-  
-      bb2: {
--         _1 = move _2;                    // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
--         StorageDead(_2);                 // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
--         _0 = ();                         // bb2[2]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
--         drop(_1) -> [return: bb3, unwind: bb1]; // bb2[3]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
--     }
-- 
 -     bb3: {
 -         StorageDead(_1);                 // bb3[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
 -         return;                          // bb3[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2
--     }
-- 
++     bb1 (cleanup): {
++         resume;                          // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
+      }
+  
 -     bb4 (cleanup): {
 -         _3 = const alloc::alloc::box_free::<std::vec::Vec<u32>>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>)) -> bb1; // bb4[0]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // ty::Const
@@ -69,6 +77,7 @@
 -                                          // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>) {alloc::alloc::box_free::<std::vec::Vec<u32>>}, val: Value(Scalar(<ZST>)) }
++     bb2: {
 +         StorageDead(_1);                 // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
 +         return;                          // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2
       }
diff --git a/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff
index 98d03b19977..35c400035a6 100644
--- a/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff
@@ -25,12 +25,18 @@
 -     }
 - 
 -     bb1: {
--         _0 = ();                         // bb1[0]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2
--         StorageDead(_1);                 // bb1[1]: scope 0 at $DIR/inline-specialization.rs:6:1: 6:2
--         return;                          // bb1[2]: scope 0 at $DIR/inline-specialization.rs:6:2: 6:2
+-         _0 = const ();                   // bb1[0]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2
 +                                          // + span: $DIR/inline-specialization.rs:14:31: 14:34
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000007b)) }
-+         _0 = ();                         // bb0[2]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2
++         _0 = const ();                   // bb0[2]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/inline-specialization.rs:4:11: 6:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+-         StorageDead(_1);                 // bb1[1]: scope 0 at $DIR/inline-specialization.rs:6:1: 6:2
+-         return;                          // bb1[2]: scope 0 at $DIR/inline-specialization.rs:6:2: 6:2
 +         StorageDead(_1);                 // bb0[3]: scope 0 at $DIR/inline-specialization.rs:6:1: 6:2
 +         return;                          // bb0[4]: scope 0 at $DIR/inline-specialization.rs:6:2: 6:2
       }
diff --git a/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir
index 5144cdd3dab..62d2f8db7a4 100644
--- a/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir
@@ -45,7 +45,13 @@ fn main() -> () {
     }
 
     bb5: {
-        _3 = ();                         // bb5[0]: scope 1 at $DIR/issue-38669.rs:7:9: 9:10
+        _3 = const ();                   // bb5[0]: scope 1 at $DIR/issue-38669.rs:7:9: 9:10
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-38669.rs:7:9: 9:10
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_4);                 // bb5[1]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10
         StorageDead(_3);                 // bb5[2]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10
         _1 = const true;                 // bb5[3]: scope 1 at $DIR/issue-38669.rs:10:9: 10:28
@@ -55,12 +61,24 @@ fn main() -> () {
                                          // mir::Constant
                                          // + span: $DIR/issue-38669.rs:10:24: 10:28
                                          // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-        _2 = ();                         // bb5[4]: scope 1 at $DIR/issue-38669.rs:6:10: 11:6
+        _2 = const ();                   // bb5[4]: scope 1 at $DIR/issue-38669.rs:6:10: 11:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-38669.rs:6:10: 11:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb2;                     // bb5[5]: scope 1 at $DIR/issue-38669.rs:6:5: 11:6
     }
 
     bb6: {
-        _0 = ();                         // bb6[0]: scope 1 at $DIR/issue-38669.rs:8:13: 8:18
+        _0 = const ();                   // bb6[0]: scope 1 at $DIR/issue-38669.rs:8:13: 8:18
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-38669.rs:8:13: 8:18
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_4);                 // bb6[1]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10
         StorageDead(_3);                 // bb6[2]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10
         StorageDead(_1);                 // bb6[3]: scope 0 at $DIR/issue-38669.rs:12:1: 12:2
diff --git a/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir
index 0499054c329..55849b27732 100644
--- a/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir
+++ b/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir
@@ -85,7 +85,13 @@ fn main() -> () {
                                          // + span: $DIR/issue-41110.rs:8:27: 8:28
                                          // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
         StorageDead(_2);                 // bb6[2]: scope 0 at $DIR/issue-41110.rs:8:27: 8:28
-        _0 = ();                         // bb6[3]: scope 0 at $DIR/issue-41110.rs:7:11: 9:2
+        _0 = const ();                   // bb6[3]: scope 0 at $DIR/issue-41110.rs:7:11: 9:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-41110.rs:7:11: 9:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_1);                 // bb6[4]: scope 0 at $DIR/issue-41110.rs:9:1: 9:2
         return;                          // bb6[5]: scope 0 at $DIR/issue-41110.rs:9:2: 9:2
     }
diff --git a/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir
index b6623fcd4d9..cc1a49dd245 100644
--- a/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir
+++ b/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir
@@ -87,7 +87,13 @@ fn test() -> () {
 
     bb8: {
         StorageDead(_5);                 // bb8[0]: scope 2 at $DIR/issue-41110.rs:18:9: 18:10
-        _0 = ();                         // bb8[1]: scope 0 at $DIR/issue-41110.rs:14:15: 19:2
+        _0 = const ();                   // bb8[1]: scope 0 at $DIR/issue-41110.rs:14:15: 19:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-41110.rs:14:15: 19:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         drop(_2) -> [return: bb9, unwind: bb3]; // bb8[2]: scope 1 at $DIR/issue-41110.rs:19:1: 19:2
     }
 
diff --git a/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir
index 6cd3e2dec83..ee05bf48d62 100644
--- a/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir
+++ b/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir
@@ -66,7 +66,13 @@ fn main() -> () {
     }
 
     bb4: {
-        _0 = ();                         // bb4[0]: scope 1 at $DIR/issue-41888.rs:8:5: 14:6
+        _0 = const ();                   // bb4[0]: scope 1 at $DIR/issue-41888.rs:8:5: 14:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-41888.rs:8:5: 14:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb11;                    // bb4[1]: scope 1 at $DIR/issue-41888.rs:8:5: 14:6
     }
 
@@ -94,7 +100,13 @@ fn main() -> () {
     }
 
     bb9: {
-        _0 = ();                         // bb9[0]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10
+        _0 = const ();                   // bb9[0]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-41888.rs:10:9: 13:10
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb11;                    // bb9[1]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10
     }
 
@@ -108,7 +120,13 @@ fn main() -> () {
                                          // + span: $DIR/issue-41888.rs:10:21: 10:23
                                          // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
         _6 = move ((_1 as F).0: K);      // bb10[2]: scope 1 at $DIR/issue-41888.rs:10:21: 10:23
-        _0 = ();                         // bb10[3]: scope 2 at $DIR/issue-41888.rs:10:29: 13:10
+        _0 = const ();                   // bb10[3]: scope 2 at $DIR/issue-41888.rs:10:29: 13:10
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-41888.rs:10:29: 13:10
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_6);                 // bb10[4]: scope 1 at $DIR/issue-41888.rs:13:9: 13:10
         goto -> bb11;                    // bb10[5]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10
     }
diff --git a/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir b/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir
index 03815d58bbc..5440d4488bb 100644
--- a/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir
@@ -47,7 +47,13 @@ fn main() -> () {
     }
 
     bb6: {
-        _0 = ();                         // bb6[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30
+        _0 = const ();                   // bb6[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-49232.rs:10:25: 10:30
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb8;                     // bb6[1]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30
     }
 
@@ -73,7 +79,13 @@ fn main() -> () {
     }
 
     bb10: {
-        _4 = ();                         // bb10[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30
+        _4 = const ();                   // bb10[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-49232.rs:10:25: 10:30
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         unreachable;                     // bb10[1]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30
     }
 
@@ -99,7 +111,13 @@ fn main() -> () {
     bb13: {
         StorageDead(_6);                 // bb13[0]: scope 1 at $DIR/issue-49232.rs:13:21: 13:22
         StorageDead(_5);                 // bb13[1]: scope 1 at $DIR/issue-49232.rs:13:22: 13:23
-        _1 = ();                         // bb13[2]: scope 0 at $DIR/issue-49232.rs:6:10: 14:6
+        _1 = const ();                   // bb13[2]: scope 0 at $DIR/issue-49232.rs:6:10: 14:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/issue-49232.rs:6:10: 14:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_2);                 // bb13[3]: scope 0 at $DIR/issue-49232.rs:14:5: 14:6
         goto -> bb1;                     // bb13[4]: scope 0 at $DIR/issue-49232.rs:6:5: 14:6
     }
diff --git a/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir b/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir
index c458592e920..df05dbabc77 100644
--- a/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir
+++ b/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir
@@ -35,7 +35,13 @@ fn main() -> () {
     }
 
     bb3: {
-        _1 = ();                         // bb3[0]: scope 0 at $DIR/loop_test.rs:10:5: 12:6
+        _1 = const ();                   // bb3[0]: scope 0 at $DIR/loop_test.rs:10:5: 12:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/loop_test.rs:10:5: 12:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_2);                 // bb3[1]: scope 0 at $DIR/loop_test.rs:12:5: 12:6
         StorageDead(_1);                 // bb3[2]: scope 0 at $DIR/loop_test.rs:12:5: 12:6
         StorageLive(_4);                 // bb3[3]: scope 0 at $DIR/loop_test.rs:13:5: 16:6
@@ -43,7 +49,13 @@ fn main() -> () {
     }
 
     bb4: {
-        _0 = ();                         // bb4[0]: scope 0 at $DIR/loop_test.rs:11:9: 11:15
+        _0 = const ();                   // bb4[0]: scope 0 at $DIR/loop_test.rs:11:9: 11:15
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/loop_test.rs:11:9: 11:15
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_2);                 // bb4[1]: scope 0 at $DIR/loop_test.rs:12:5: 12:6
         StorageDead(_1);                 // bb4[2]: scope 0 at $DIR/loop_test.rs:12:5: 12:6
         return;                          // bb4[3]: scope 0 at $DIR/loop_test.rs:17:2: 17:2
diff --git a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir
index acc03cce46e..a296bd05312 100644
--- a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir
+++ b/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir
@@ -143,7 +143,13 @@ fn full_tested_match() -> () {
     bb11: {
         StorageDead(_2);                 // bb11[0]: scope 0 at $DIR/match_false_edges.rs:19:6: 19:7
         StorageDead(_1);                 // bb11[1]: scope 0 at $DIR/match_false_edges.rs:19:6: 19:7
-        _0 = ();                         // bb11[2]: scope 0 at $DIR/match_false_edges.rs:14:28: 20:2
+        _0 = const ();                   // bb11[2]: scope 0 at $DIR/match_false_edges.rs:14:28: 20:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/match_false_edges.rs:14:28: 20:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb11[3]: scope 0 at $DIR/match_false_edges.rs:20:2: 20:2
     }
 }
diff --git a/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir
index cc1fa562645..567e3ebdd93 100644
--- a/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir
+++ b/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir
@@ -135,7 +135,13 @@ fn full_tested_match2() -> () {
     bb11: {
         StorageDead(_2);                 // bb11[0]: scope 0 at $DIR/match_false_edges.rs:30:6: 30:7
         StorageDead(_1);                 // bb11[1]: scope 0 at $DIR/match_false_edges.rs:30:6: 30:7
-        _0 = ();                         // bb11[2]: scope 0 at $DIR/match_false_edges.rs:25:29: 31:2
+        _0 = const ();                   // bb11[2]: scope 0 at $DIR/match_false_edges.rs:25:29: 31:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/match_false_edges.rs:25:29: 31:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb11[3]: scope 0 at $DIR/match_false_edges.rs:31:2: 31:2
     }
 }
diff --git a/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir
index fce497df982..a24fa9dedb3 100644
--- a/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir
+++ b/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir
@@ -182,7 +182,13 @@ fn main() -> () {
     bb15: {
         StorageDead(_2);                 // bb15[0]: scope 0 at $DIR/match_false_edges.rs:40:6: 40:7
         StorageDead(_1);                 // bb15[1]: scope 0 at $DIR/match_false_edges.rs:40:6: 40:7
-        _0 = ();                         // bb15[2]: scope 0 at $DIR/match_false_edges.rs:34:11: 41:2
+        _0 = const ();                   // bb15[2]: scope 0 at $DIR/match_false_edges.rs:34:11: 41:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/match_false_edges.rs:34:11: 41:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb15[3]: scope 0 at $DIR/match_false_edges.rs:41:2: 41:2
     }
 }
diff --git a/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir
index ef5feb79bec..3236b3bcc73 100644
--- a/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir
@@ -158,7 +158,13 @@ fn main() -> () {
 
     bb14: {
         StorageDead(_3);                 // bb14[0]: scope 2 at $DIR/match_test.rs:17:6: 17:7
-        _0 = ();                         // bb14[1]: scope 0 at $DIR/match_test.rs:6:11: 18:2
+        _0 = const ();                   // bb14[1]: scope 0 at $DIR/match_test.rs:6:11: 18:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/match_test.rs:6:11: 18:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_2);                 // bb14[2]: scope 1 at $DIR/match_test.rs:18:1: 18:2
         StorageDead(_1);                 // bb14[3]: scope 0 at $DIR/match_test.rs:18:1: 18:2
         return;                          // bb14[4]: scope 0 at $DIR/match_test.rs:18:2: 18:2
diff --git a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir
index 1f75658aa26..7d396c3f1fb 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir
@@ -137,13 +137,25 @@ fn main() -> () {
     bb6: {
         StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:17: 19:18
         StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:18: 19:19
-        _0 = ();                         // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/region-subtyping-basic.rs:18:13: 20:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
     }
 
     bb7: {
         StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
-        _0 = ();                         // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/region-subtyping-basic.rs:20:12: 22:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
     }
 
diff --git a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
index 8305c3fe7c4..4a285d035be 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir
@@ -137,13 +137,25 @@ fn main() -> () {
     bb6: {
         StorageDead(_9);                 // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:17: 19:18
         StorageDead(_8);                 // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:18: 19:19
-        _0 = ();                         // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/region-subtyping-basic.rs:18:13: 20:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb8;                     // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
     }
 
     bb7: {
         StorageDead(_10);                // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19
-        _0 = ();                         // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6
+        _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/region-subtyping-basic.rs:20:12: 22:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         goto -> bb8;                     // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6
     }
 
diff --git a/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir b/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir
index b65bc760330..e43e37feba7 100644
--- a/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir
+++ b/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir
@@ -48,7 +48,13 @@ fn main() -> () {
         StorageDead(_2);                 // bb3[0]: scope 0 at $DIR/no-spurious-drop-after-call.rs:9:34: 9:35
         StorageDead(_4);                 // bb3[1]: scope 0 at $DIR/no-spurious-drop-after-call.rs:9:35: 9:36
         StorageDead(_1);                 // bb3[2]: scope 0 at $DIR/no-spurious-drop-after-call.rs:9:35: 9:36
-        _0 = ();                         // bb3[3]: scope 0 at $DIR/no-spurious-drop-after-call.rs:8:11: 10:2
+        _0 = const ();                   // bb3[3]: scope 0 at $DIR/no-spurious-drop-after-call.rs:8:11: 10:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/no-spurious-drop-after-call.rs:8:11: 10:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb3[4]: scope 0 at $DIR/no-spurious-drop-after-call.rs:10:2: 10:2
     }
 
diff --git a/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
index 03265c613bc..cea10872942 100644
--- a/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
@@ -61,7 +61,13 @@ fn main() -> () {
         StorageDead(_6);                 // bb4[0]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8
         (_1.0: Aligned) = move _4;       // bb4[1]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8
         StorageDead(_4);                 // bb4[2]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:28: 7:29
-        _0 = ();                         // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2
+        _0 = const ();                   // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/packed-struct-drop-aligned.rs:5:11: 8:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         drop(_1) -> [return: bb2, unwind: bb1]; // bb4[4]: scope 0 at $DIR/packed-struct-drop-aligned.rs:8:1: 8:2
     }
 }
diff --git a/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
index a1424d0bf59..432f91d91e5 100644
--- a/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir
@@ -61,7 +61,13 @@ fn main() -> () {
         StorageDead(_6);                 // bb4[0]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8
         (_1.0: Aligned) = move _4;       // bb4[1]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8
         StorageDead(_4);                 // bb4[2]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:28: 7:29
-        _0 = ();                         // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2
+        _0 = const ();                   // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/packed-struct-drop-aligned.rs:5:11: 8:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         drop(_1) -> [return: bb2, unwind: bb1]; // bb4[4]: scope 0 at $DIR/packed-struct-drop-aligned.rs:8:1: 8:2
     }
 }
diff --git a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir
index 780cb9d4ad5..727c271a478 100644
--- a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir
@@ -125,7 +125,13 @@ fn main() -> () {
         Retag([raw] _12);                // bb4[14]: scope 4 at $DIR/retag.rs:36:18: 36:19
         _11 = _12;                       // bb4[15]: scope 4 at $DIR/retag.rs:36:18: 36:29
         StorageDead(_12);                // bb4[16]: scope 4 at $DIR/retag.rs:36:29: 36:30
-        _2 = ();                         // bb4[17]: scope 1 at $DIR/retag.rs:31:5: 37:6
+        _2 = const ();                   // bb4[17]: scope 1 at $DIR/retag.rs:31:5: 37:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/retag.rs:31:5: 37:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_11);                // bb4[18]: scope 4 at $DIR/retag.rs:37:5: 37:6
         StorageDead(_10);                // bb4[19]: scope 3 at $DIR/retag.rs:37:5: 37:6
         StorageDead(_8);                 // bb4[20]: scope 2 at $DIR/retag.rs:37:5: 37:6
@@ -217,7 +223,13 @@ fn main() -> () {
         Retag([raw] _26);                // bb8[5]: scope 7 at $DIR/retag.rs:50:14: 50:16
         _25 = _26;                       // bb8[6]: scope 7 at $DIR/retag.rs:50:14: 50:28
         StorageDead(_26);                // bb8[7]: scope 7 at $DIR/retag.rs:50:28: 50:29
-        _0 = ();                         // bb8[8]: scope 0 at $DIR/retag.rs:29:11: 51:2
+        _0 = const ();                   // bb8[8]: scope 0 at $DIR/retag.rs:29:11: 51:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/retag.rs:29:11: 51:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_25);                // bb8[9]: scope 7 at $DIR/retag.rs:51:1: 51:2
         StorageDead(_15);                // bb8[10]: scope 6 at $DIR/retag.rs:51:1: 51:2
         StorageDead(_13);                // bb8[11]: scope 1 at $DIR/retag.rs:51:1: 51:2
diff --git a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff
index 32338127923..2caa6235d54 100644
--- a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff
@@ -57,8 +57,15 @@
   
       bb4: {
           StorageDead(_2);                 // bb4[0]: scope 1 at $DIR/simplify-arm-identity.rs:21:6: 21:7
-          StorageDead(_1);                 // bb4[1]: scope 0 at $DIR/simplify-arm-identity.rs:22:1: 22:2
-          return;                          // bb4[2]: scope 0 at $DIR/simplify-arm-identity.rs:22:2: 22:2
+          _0 = const ();                   // bb4[1]: scope 0 at $DIR/simplify-arm-identity.rs:16:11: 22:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify-arm-identity.rs:16:11: 22:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+          StorageDead(_1);                 // bb4[2]: scope 0 at $DIR/simplify-arm-identity.rs:22:1: 22:2
+          return;                          // bb4[3]: scope 0 at $DIR/simplify-arm-identity.rs:22:2: 22:2
       }
   }
   
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff
index 15deb3e31bd..8613a812a83 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff
@@ -124,9 +124,17 @@
       bb2: {
 -         StorageDead(_11);                // bb2[0]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36
 -         StorageDead(_8);                 // bb2[1]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36
--         return;                          // bb2[2]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2
+-         _0 = const ();                   // bb2[2]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:12:11: 17:2
 +         StorageDead(_2);                 // bb2[0]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36
-+         return;                          // bb2[1]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2
++         _0 = const ();                   // bb2[1]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:12:11: 17:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify-locals-removes-unused-consts.rs:12:11: 17:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+-         return;                          // bb2[3]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2
++         return;                          // bb2[2]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2
       }
   }
   
diff --git a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff
index 9225bcd0b65..ecac835fb87 100644
--- a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff
+++ b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff
@@ -33,28 +33,40 @@
 -     bb3: {
 -         nop;                             // bb3[0]: scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17
 -         switchInt(_2) -> [false: bb5, otherwise: bb4]; // bb3[1]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
-+     bb2: {
-+         _1 = ();                         // bb2[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
-+         StorageDead(_2);                 // bb2[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
-+         goto -> bb0;                     // bb2[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6
-      }
-  
+-     }
+- 
 -     bb4: {
 -         goto -> bb6;                     // bb4[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
 -     }
 - 
 -     bb5: {
--         _1 = ();                         // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
+-         _1 = const ();                   // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
++     bb2: {
++         _1 = const ();                   // bb2[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify_cfg.rs:7:9: 9:10
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         StorageDead(_2);                 // bb5[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
 -         goto -> bb0;                     // bb5[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6
--     }
-- 
++         StorageDead(_2);                 // bb2[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
++         goto -> bb0;                     // bb2[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6
+      }
+  
 -     bb6: {
--         _0 = ();                         // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
+-         _0 = const ();                   // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
++     bb3: {
++         _0 = const ();                   // bb3[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify_cfg.rs:8:13: 8:18
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         StorageDead(_2);                 // bb6[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
 -         return;                          // bb6[2]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2
-+     bb3: {
-+         _0 = ();                         // bb3[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
 +         StorageDead(_2);                 // bb3[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
 +         return;                          // bb3[2]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2
       }
diff --git a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff
index 856ee3508cb..7c8bdde5418 100644
--- a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff
+++ b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff
@@ -54,16 +54,30 @@
       }
   
 -     bb7: {
--         _1 = ();                         // bb7[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
--         goto -> bb12;                    // bb7[1]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
+-         _1 = const ();                   // bb7[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
 +     bb5: {
-+         _1 = ();                         // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
++         _1 = const ();                   // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify_cfg.rs:7:9: 9:10
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+-         goto -> bb12;                    // bb7[1]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10
 +         StorageDead(_2);                 // bb5[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
 +         goto -> bb0;                     // bb5[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6
       }
   
 -     bb8: {
--         _0 = ();                         // bb8[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
+-         _0 = const ();                   // bb8[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
++     bb6: {
++         _0 = const ();                   // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify_cfg.rs:8:13: 8:18
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         goto -> bb9;                     // bb8[1]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
 -     }
 - 
@@ -87,8 +101,6 @@
 - 
 -     bb13: {
 -         return;                          // bb13[0]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2
-+     bb6: {
-+         _0 = ();                         // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18
 +         StorageDead(_2);                 // bb6[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6
 +         return;                          // bb6[2]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2
       }
diff --git a/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff b/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff
index 9e53a0f18af..2946eb1cc44 100644
--- a/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff
+++ b/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff
@@ -26,7 +26,13 @@
       }
   
       bb1: {
-          _0 = ();                         // bb1[0]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6
+          _0 = const ();                   // bb1[0]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify_if.rs:6:5: 8:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           goto -> bb4;                     // bb1[1]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6
       }
   
@@ -43,7 +49,13 @@
   
       bb3: {
           StorageDead(_2);                 // bb3[0]: scope 0 at $DIR/simplify_if.rs:7:15: 7:16
-          _0 = ();                         // bb3[1]: scope 0 at $DIR/simplify_if.rs:6:14: 8:6
+          _0 = const ();                   // bb3[1]: scope 0 at $DIR/simplify_if.rs:6:14: 8:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify_if.rs:6:14: 8:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           goto -> bb4;                     // bb3[2]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6
       }
   
diff --git a/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff b/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff
index 5429032b099..1c83bb13425 100644
--- a/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff
+++ b/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff
@@ -26,7 +26,13 @@
       }
   
       bb1: {
-          nop;                             // bb1[0]: scope 0 at $DIR/simplify_match.rs:8:18: 8:20
+          _0 = const ();                   // bb1[0]: scope 0 at $DIR/simplify_match.rs:8:18: 8:20
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/simplify_match.rs:8:18: 8:20
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           goto -> bb3;                     // bb1[1]: scope 0 at $DIR/simplify_match.rs:6:5: 9:6
       }
   
diff --git a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
index 57ec47346e8..e455a27642d 100644
--- a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
+++ b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir
@@ -54,7 +54,13 @@ fn main() -> () {
         StorageDead(_5);                 // bb0[9]: scope 1 at $DIR/storage_ranges.rs:6:24: 6:25
         _3 = &_4;                        // bb0[10]: scope 1 at $DIR/storage_ranges.rs:6:17: 6:25
         FakeRead(ForLet, _3);            // bb0[11]: scope 1 at $DIR/storage_ranges.rs:6:13: 6:14
-        _2 = ();                         // bb0[12]: scope 1 at $DIR/storage_ranges.rs:5:5: 7:6
+        _2 = const ();                   // bb0[12]: scope 1 at $DIR/storage_ranges.rs:5:5: 7:6
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/storage_ranges.rs:5:5: 7:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_4);                 // bb0[13]: scope 1 at $DIR/storage_ranges.rs:7:5: 7:6
         StorageDead(_3);                 // bb0[14]: scope 1 at $DIR/storage_ranges.rs:7:5: 7:6
         StorageDead(_2);                 // bb0[15]: scope 1 at $DIR/storage_ranges.rs:7:5: 7:6
@@ -67,7 +73,13 @@ fn main() -> () {
                                          // + span: $DIR/storage_ranges.rs:8:13: 8:14
                                          // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
         FakeRead(ForLet, _6);            // bb0[18]: scope 1 at $DIR/storage_ranges.rs:8:9: 8:10
-        _0 = ();                         // bb0[19]: scope 0 at $DIR/storage_ranges.rs:3:11: 9:2
+        _0 = const ();                   // bb0[19]: scope 0 at $DIR/storage_ranges.rs:3:11: 9:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/storage_ranges.rs:3:11: 9:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         StorageDead(_6);                 // bb0[20]: scope 1 at $DIR/storage_ranges.rs:9:1: 9:2
         StorageDead(_1);                 // bb0[21]: scope 0 at $DIR/storage_ranges.rs:9:1: 9:2
         return;                          // bb0[22]: scope 0 at $DIR/storage_ranges.rs:9:2: 9:2
diff --git a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir
index 5dbee8f7b3d..b46adadf101 100644
--- a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir
+++ b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir
@@ -83,7 +83,13 @@ fn move_out_by_subslice() -> () {
         FakeRead(ForLet, _1);            // bb9[1]: scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10
         StorageLive(_6);                 // bb9[2]: scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
         _6 = move _1[0..2];              // bb9[3]: scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17
-        _0 = ();                         // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:10:27: 13:2
+        _0 = const ();                   // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:10:27: 13:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/uniform_array_move_out.rs:10:27: 13:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         drop(_6) -> [return: bb12, unwind: bb10]; // bb9[5]: scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2
     }
 
diff --git a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir
index 4a5cd625c9d..851107efe11 100644
--- a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir
+++ b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir
@@ -83,7 +83,13 @@ fn move_out_from_end() -> () {
         FakeRead(ForLet, _1);            // bb9[1]: scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10
         StorageLive(_6);                 // bb9[2]: scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
         _6 = move _1[1 of 2];            // bb9[3]: scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16
-        _0 = ();                         // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:4:24: 7:2
+        _0 = const ();                   // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:4:24: 7:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/uniform_array_move_out.rs:4:24: 7:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         drop(_6) -> [return: bb12, unwind: bb10]; // bb9[5]: scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2
     }
 
diff --git a/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir
index 2eb820bbdc3..1ee2297daac 100644
--- a/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir
+++ b/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir
@@ -13,7 +13,14 @@ fn process_void(_1: *const Void) -> () {
     bb0: {
         StorageLive(_2);                 // bb0[0]: scope 0 at $DIR/uninhabited-enum.rs:14:8: 14:14
         _2 = &(*_1);                     // bb0[1]: scope 2 at $DIR/uninhabited-enum.rs:14:26: 14:33
-        StorageDead(_2);                 // bb0[2]: scope 0 at $DIR/uninhabited-enum.rs:17:1: 17:2
-        return;                          // bb0[3]: scope 0 at $DIR/uninhabited-enum.rs:17:2: 17:2
+        _0 = const ();                   // bb0[2]: scope 0 at $DIR/uninhabited-enum.rs:13:41: 17:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/uninhabited-enum.rs:13:41: 17:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+        StorageDead(_2);                 // bb0[3]: scope 0 at $DIR/uninhabited-enum.rs:17:1: 17:2
+        return;                          // bb0[4]: scope 0 at $DIR/uninhabited-enum.rs:17:2: 17:2
     }
 }
diff --git a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
index c8dde4d360c..fba77dfe239 100644
--- a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
+++ b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -64,7 +64,13 @@ fn main() -> () {
     bb3: {
         StorageDead(_7);                 // bb3[0]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7
         StorageDead(_6);                 // bb3[1]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7
-        _0 = ();                         // bb3[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2
+        _0 = const ();                   // bb3[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/uninhabited_enum_branching.rs:19:11: 30:2
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
         return;                          // bb3[3]: scope 0 at $DIR/uninhabited_enum_branching.rs:30:2: 30:2
     }
 }
diff --git a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff
index cccd6aa3230..35842fdaa4e 100644
--- a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff
+++ b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff
@@ -99,7 +99,13 @@
       bb7: {
           StorageDead(_7);                 // bb7[0]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7
           StorageDead(_6);                 // bb7[1]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7
-          _0 = ();                         // bb7[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2
+          _0 = const ();                   // bb7[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching.rs:19:11: 30:2
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           return;                          // bb7[3]: scope 0 at $DIR/uninhabited_enum_branching.rs:30:2: 30:2
       }
   }
diff --git a/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff
index 3a239c6e3b0..d530a999409 100644
--- a/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff
@@ -35,7 +35,13 @@
       }
   
       bb2: {
-          _0 = ();                         // bb2[0]: scope 0 at $DIR/unreachable.rs:9:5: 19:6
+          _0 = const ();                   // bb2[0]: scope 0 at $DIR/unreachable.rs:9:5: 19:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable.rs:9:5: 19:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb2[1]: scope 0 at $DIR/unreachable.rs:20:1: 20:2
           return;                          // bb2[2]: scope 0 at $DIR/unreachable.rs:20:2: 20:2
 -     }
@@ -64,7 +70,13 @@
 -                                          // mir::Constant
 -                                          // + span: $DIR/unreachable.rs:15:18: 15:20
 -                                          // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
--         _5 = ();                         // bb4[1]: scope 2 at $DIR/unreachable.rs:14:16: 16:10
+-         _5 = const ();                   // bb4[1]: scope 2 at $DIR/unreachable.rs:14:16: 16:10
+-                                          // ty::Const
+-                                          // + ty: ()
+-                                          // + val: Value(Scalar(<ZST>))
+-                                          // mir::Constant
+-                                          // + span: $DIR/unreachable.rs:14:16: 16:10
+-                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         goto -> bb6;                     // bb4[2]: scope 2 at $DIR/unreachable.rs:12:9: 16:10
 -     }
 - 
@@ -76,7 +88,13 @@
 -                                          // mir::Constant
 -                                          // + span: $DIR/unreachable.rs:13:18: 13:20
 -                                          // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) }
--         _5 = ();                         // bb5[1]: scope 2 at $DIR/unreachable.rs:12:17: 14:10
+-         _5 = const ();                   // bb5[1]: scope 2 at $DIR/unreachable.rs:12:17: 14:10
+-                                          // ty::Const
+-                                          // + ty: ()
+-                                          // + val: Value(Scalar(<ZST>))
+-                                          // mir::Constant
+-                                          // + span: $DIR/unreachable.rs:12:17: 14:10
+-                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         goto -> bb6;                     // bb5[2]: scope 2 at $DIR/unreachable.rs:12:9: 16:10
 -     }
 - 
diff --git a/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff
index c32165a3893..2b3ab80fa0f 100644
--- a/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff
@@ -37,7 +37,13 @@
       }
   
       bb2: {
-          _0 = ();                         // bb2[0]: scope 0 at $DIR/unreachable_asm.rs:11:5: 23:6
+          _0 = const ();                   // bb2[0]: scope 0 at $DIR/unreachable_asm.rs:11:5: 23:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm.rs:11:5: 23:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb2[1]: scope 0 at $DIR/unreachable_asm.rs:24:1: 24:2
           return;                          // bb2[2]: scope 0 at $DIR/unreachable_asm.rs:24:2: 24:2
       }
@@ -66,7 +72,13 @@
                                            // mir::Constant
                                            // + span: $DIR/unreachable_asm.rs:17:18: 17:20
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
-          _5 = ();                         // bb4[1]: scope 2 at $DIR/unreachable_asm.rs:16:16: 18:10
+          _5 = const ();                   // bb4[1]: scope 2 at $DIR/unreachable_asm.rs:16:16: 18:10
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm.rs:16:16: 18:10
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           goto -> bb6;                     // bb4[2]: scope 2 at $DIR/unreachable_asm.rs:14:9: 18:10
       }
   
@@ -78,7 +90,13 @@
                                            // mir::Constant
                                            // + span: $DIR/unreachable_asm.rs:15:18: 15:20
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) }
-          _5 = ();                         // bb5[1]: scope 2 at $DIR/unreachable_asm.rs:14:17: 16:10
+          _5 = const ();                   // bb5[1]: scope 2 at $DIR/unreachable_asm.rs:14:17: 16:10
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm.rs:14:17: 16:10
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           goto -> bb6;                     // bb5[2]: scope 2 at $DIR/unreachable_asm.rs:14:9: 18:10
       }
   
@@ -87,7 +105,13 @@
           StorageDead(_5);                 // bb6[1]: scope 2 at $DIR/unreachable_asm.rs:18:9: 18:10
           StorageLive(_7);                 // bb6[2]: scope 2 at $DIR/unreachable_asm.rs:21:9: 21:37
           llvm_asm!(LlvmInlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); // bb6[3]: scope 3 at $DIR/unreachable_asm.rs:21:18: 21:35
-          _7 = ();                         // bb6[4]: scope 3 at $DIR/unreachable_asm.rs:21:9: 21:37
+          _7 = const ();                   // bb6[4]: scope 3 at $DIR/unreachable_asm.rs:21:9: 21:37
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm.rs:21:9: 21:37
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_7);                 // bb6[5]: scope 2 at $DIR/unreachable_asm.rs:21:36: 21:37
           StorageLive(_8);                 // bb6[6]: scope 2 at $DIR/unreachable_asm.rs:22:9: 22:21
           unreachable;                     // bb6[7]: scope 2 at $DIR/unreachable_asm.rs:22:15: 22:17
diff --git a/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff
index a3741787566..c3760f6a7fc 100644
--- a/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff
@@ -40,7 +40,13 @@
       }
   
       bb2: {
-          _0 = ();                         // bb2[0]: scope 0 at $DIR/unreachable_asm_2.rs:11:5: 25:6
+          _0 = const ();                   // bb2[0]: scope 0 at $DIR/unreachable_asm_2.rs:11:5: 25:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm_2.rs:11:5: 25:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb2[1]: scope 0 at $DIR/unreachable_asm_2.rs:26:1: 26:2
           return;                          // bb2[2]: scope 0 at $DIR/unreachable_asm_2.rs:26:2: 26:2
       }
@@ -64,7 +70,13 @@
       bb4: {
           StorageLive(_8);                 // bb4[0]: scope 2 at $DIR/unreachable_asm_2.rs:20:13: 20:41
           llvm_asm!(LlvmInlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); // bb4[1]: scope 4 at $DIR/unreachable_asm_2.rs:20:22: 20:39
-          _8 = ();                         // bb4[2]: scope 4 at $DIR/unreachable_asm_2.rs:20:13: 20:41
+          _8 = const ();                   // bb4[2]: scope 4 at $DIR/unreachable_asm_2.rs:20:13: 20:41
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm_2.rs:20:13: 20:41
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_8);                 // bb4[3]: scope 2 at $DIR/unreachable_asm_2.rs:20:40: 20:41
           _4 = const 42i32;                // bb4[4]: scope 2 at $DIR/unreachable_asm_2.rs:21:13: 21:20
                                            // ty::Const
@@ -73,7 +85,13 @@
                                            // mir::Constant
                                            // + span: $DIR/unreachable_asm_2.rs:21:18: 21:20
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
-          _5 = ();                         // bb4[5]: scope 2 at $DIR/unreachable_asm_2.rs:18:16: 22:10
+          _5 = const ();                   // bb4[5]: scope 2 at $DIR/unreachable_asm_2.rs:18:16: 22:10
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm_2.rs:18:16: 22:10
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         goto -> bb6;                     // bb4[6]: scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10
 +         unreachable;                     // bb4[6]: scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10
       }
@@ -81,7 +99,13 @@
       bb5: {
           StorageLive(_7);                 // bb5[0]: scope 2 at $DIR/unreachable_asm_2.rs:16:13: 16:41
           llvm_asm!(LlvmInlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); // bb5[1]: scope 3 at $DIR/unreachable_asm_2.rs:16:22: 16:39
-          _7 = ();                         // bb5[2]: scope 3 at $DIR/unreachable_asm_2.rs:16:13: 16:41
+          _7 = const ();                   // bb5[2]: scope 3 at $DIR/unreachable_asm_2.rs:16:13: 16:41
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm_2.rs:16:13: 16:41
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_7);                 // bb5[3]: scope 2 at $DIR/unreachable_asm_2.rs:16:40: 16:41
           _4 = const 21i32;                // bb5[4]: scope 2 at $DIR/unreachable_asm_2.rs:17:13: 17:20
                                            // ty::Const
@@ -90,7 +114,13 @@
                                            // mir::Constant
                                            // + span: $DIR/unreachable_asm_2.rs:17:18: 17:20
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) }
-          _5 = ();                         // bb5[5]: scope 2 at $DIR/unreachable_asm_2.rs:14:17: 18:10
+          _5 = const ();                   // bb5[5]: scope 2 at $DIR/unreachable_asm_2.rs:14:17: 18:10
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_asm_2.rs:14:17: 18:10
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         goto -> bb6;                     // bb5[6]: scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10
 -     }
 - 
diff --git a/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff
index 8d1d137f192..2fe0c8dc1e7 100644
--- a/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff
@@ -42,7 +42,13 @@
       }
   
       bb2: {
-          _0 = ();                         // bb2[0]: scope 1 at $DIR/unreachable_diverging.rs:14:5: 19:6
+          _0 = const ();                   // bb2[0]: scope 1 at $DIR/unreachable_diverging.rs:14:5: 19:6
+                                           // ty::Const
+                                           // + ty: ()
+                                           // + val: Value(Scalar(<ZST>))
+                                           // mir::Constant
+                                           // + span: $DIR/unreachable_diverging.rs:14:5: 19:6
+                                           // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
           StorageDead(_1);                 // bb2[1]: scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2
           StorageDead(_2);                 // bb2[2]: scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2
           return;                          // bb2[3]: scope 0 at $DIR/unreachable_diverging.rs:20:2: 20:2
@@ -59,14 +65,20 @@
       }
   
       bb4: {
--         _5 = ();                         // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10
+-         _5 = const ();                   // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10
++         _5 = const loop_forever() -> bb5; // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27
+                                           // ty::Const
+-                                          // + ty: ()
+-                                          // + val: Value(Scalar(<ZST>))
+-                                          // mir::Constant
+-                                          // + span: $DIR/unreachable_diverging.rs:15:9: 17:10
+-                                          // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
 -         goto -> bb6;                     // bb4[1]: scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10
 -     }
 - 
 -     bb5: {
 -         _5 = const loop_forever() -> bb6; // bb5[0]: scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27
-+         _5 = const loop_forever() -> bb5; // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27
-                                           // ty::Const
+-                                          // ty::Const
                                            // + ty: fn() {loop_forever}
                                            // + val: Value(Scalar(<ZST>))
                                            // mir::Constant
diff --git a/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir
index 8fadcb8c12f..0ac7989166e 100644
--- a/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir
+++ b/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir
@@ -23,40 +23,58 @@ fn while_loop(_1: bool) -> () {
 
     bb1: {
         StorageDead(_3);                 // bb1[0]: scope 0 at $DIR/while-storage.rs:10:21: 10:22
-        switchInt(_2) -> [false: bb6, otherwise: bb2]; // bb1[1]: scope 0 at $DIR/while-storage.rs:10:5: 14:6
+        switchInt(_2) -> [false: bb2, otherwise: bb3]; // bb1[1]: scope 0 at $DIR/while-storage.rs:10:5: 14:6
     }
 
     bb2: {
-        StorageLive(_4);                 // bb2[0]: scope 0 at $DIR/while-storage.rs:11:12: 11:23
-        StorageLive(_5);                 // bb2[1]: scope 0 at $DIR/while-storage.rs:11:21: 11:22
-        _5 = _1;                         // bb2[2]: scope 0 at $DIR/while-storage.rs:11:21: 11:22
-        _4 = const get_bool(move _5) -> bb3; // bb2[3]: scope 0 at $DIR/while-storage.rs:11:12: 11:23
+        _0 = const ();                   // bb2[0]: scope 0 at $DIR/while-storage.rs:10:5: 14:6
                                          // ty::Const
-                                         // + ty: fn(bool) -> bool {get_bool}
+                                         // + ty: ()
                                          // + val: Value(Scalar(<ZST>))
                                          // mir::Constant
-                                         // + span: $DIR/while-storage.rs:11:12: 11:20
-                                         // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(Scalar(<ZST>)) }
+                                         // + span: $DIR/while-storage.rs:10:5: 14:6
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+        goto -> bb7;                     // bb2[1]: scope 0 at $DIR/while-storage.rs:10:5: 14:6
     }
 
     bb3: {
-        StorageDead(_5);                 // bb3[0]: scope 0 at $DIR/while-storage.rs:11:22: 11:23
-        switchInt(_4) -> [false: bb4, otherwise: bb5]; // bb3[1]: scope 0 at $DIR/while-storage.rs:11:9: 13:10
+        StorageLive(_4);                 // bb3[0]: scope 0 at $DIR/while-storage.rs:11:12: 11:23
+        StorageLive(_5);                 // bb3[1]: scope 0 at $DIR/while-storage.rs:11:21: 11:22
+        _5 = _1;                         // bb3[2]: scope 0 at $DIR/while-storage.rs:11:21: 11:22
+        _4 = const get_bool(move _5) -> bb4; // bb3[3]: scope 0 at $DIR/while-storage.rs:11:12: 11:23
+                                         // ty::Const
+                                         // + ty: fn(bool) -> bool {get_bool}
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/while-storage.rs:11:12: 11:20
+                                         // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(Scalar(<ZST>)) }
     }
 
     bb4: {
-        StorageDead(_4);                 // bb4[0]: scope 0 at $DIR/while-storage.rs:14:5: 14:6
-        StorageDead(_2);                 // bb4[1]: scope 0 at $DIR/while-storage.rs:10:21: 10:22
-        goto -> bb0;                     // bb4[2]: scope 0 at $DIR/while-storage.rs:10:5: 14:6
+        StorageDead(_5);                 // bb4[0]: scope 0 at $DIR/while-storage.rs:11:22: 11:23
+        switchInt(_4) -> [false: bb5, otherwise: bb6]; // bb4[1]: scope 0 at $DIR/while-storage.rs:11:9: 13:10
     }
 
     bb5: {
         StorageDead(_4);                 // bb5[0]: scope 0 at $DIR/while-storage.rs:14:5: 14:6
-        goto -> bb6;                     // bb5[1]: scope 0 at $DIR/while-storage.rs:12:13: 12:18
+        StorageDead(_2);                 // bb5[1]: scope 0 at $DIR/while-storage.rs:10:21: 10:22
+        goto -> bb0;                     // bb5[2]: scope 0 at $DIR/while-storage.rs:10:5: 14:6
     }
 
     bb6: {
-        StorageDead(_2);                 // bb6[0]: scope 0 at $DIR/while-storage.rs:10:21: 10:22
-        return;                          // bb6[1]: scope 0 at $DIR/while-storage.rs:15:2: 15:2
+        _0 = const ();                   // bb6[0]: scope 0 at $DIR/while-storage.rs:12:13: 12:18
+                                         // ty::Const
+                                         // + ty: ()
+                                         // + val: Value(Scalar(<ZST>))
+                                         // mir::Constant
+                                         // + span: $DIR/while-storage.rs:12:13: 12:18
+                                         // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
+        StorageDead(_4);                 // bb6[1]: scope 0 at $DIR/while-storage.rs:14:5: 14:6
+        goto -> bb7;                     // bb6[2]: scope 0 at $DIR/while-storage.rs:12:13: 12:18
+    }
+
+    bb7: {
+        StorageDead(_2);                 // bb7[0]: scope 0 at $DIR/while-storage.rs:10:21: 10:22
+        return;                          // bb7[1]: scope 0 at $DIR/while-storage.rs:15:2: 15:2
     }
 }
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs
index f1f82caf7d4..8fe79b97d9b 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs
@@ -14,7 +14,7 @@ impl Foo for Def {
 
 pub fn test<A: Foo, B: Foo>() {
     let _array = [4; <A as Foo>::Y];
-    //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
+    //~^ ERROR constant expression depends on a generic parameter
 }
 
 fn main() {
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
index 946a1f1a07a..0bc019b2dc8 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
@@ -1,17 +1,10 @@
-error[E0277]: the trait bound `A: Foo` is not satisfied
+error: constant expression depends on a generic parameter
   --> $DIR/associated-const-type-parameter-arrays-2.rs:16:22
    |
-LL |     const Y: usize;
-   |     --------------- required by `Foo::Y`
-...
 LL |     let _array = [4; <A as Foo>::Y];
-   |                      ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
+   |                      ^^^^^^^^^^^^^
    |
-help: consider further restricting this bound
-   |
-LL | pub fn test<A: Foo + Foo, B: Foo>() {
-   |                    ^^^^^
+   = note: this may fail depending on what value the parameter takes
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 04df6203e43..d36d59f1f68 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:24:5
    |
 LL |     let x = non_send();
-   |         - has type `impl std::fmt::Debug`
+   |         - has type `impl std::fmt::Debug` which is not `Send`
 LL |     drop(x);
 LL |     fut().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
@@ -33,7 +33,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:33:20
    |
 LL |     match Some(non_send()) {
-   |                ---------- has type `impl std::fmt::Debug`
+   |                ---------- has type `impl std::fmt::Debug` which is not `Send`
 LL |         Some(_) => fut().await,
    |                    ^^^^^^^^^^^ await occurs here, with `non_send()` maybe used later
 ...
@@ -54,7 +54,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:42:9
    |
 LL |     let f: &mut std::fmt::Formatter = panic!();
-   |         - has type `&mut std::fmt::Formatter<'_>`
+   |         - has type `&mut std::fmt::Formatter<'_>` which is not `Send`
 LL |     if non_sync().fmt(f).unwrap() == () {
 LL |         fut().await;
    |         ^^^^^^^^^^^ await occurs here, with `f` maybe used later
diff --git a/src/test/ui/async-await/issue-64130-1-sync.stderr b/src/test/ui/async-await/issue-64130-1-sync.stderr
index b7a88c10e74..42e9e4642ce 100644
--- a/src/test/ui/async-await/issue-64130-1-sync.stderr
+++ b/src/test/ui/async-await/issue-64130-1-sync.stderr
@@ -12,7 +12,7 @@ note: future is not `Sync` as this value is used across an await
   --> $DIR/issue-64130-1-sync.rs:15:5
    |
 LL |     let x = Foo;
-   |         - has type `Foo`
+   |         - has type `Foo` which is not `Sync`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-64130-2-send.stderr b/src/test/ui/async-await/issue-64130-2-send.stderr
index ec183088771..f6f834618d3 100644
--- a/src/test/ui/async-await/issue-64130-2-send.stderr
+++ b/src/test/ui/async-await/issue-64130-2-send.stderr
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-2-send.rs:15:5
    |
 LL |     let x = Foo;
-   |         - has type `Foo`
+   |         - has type `Foo` which is not `Send`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-64130-3-other.stderr b/src/test/ui/async-await/issue-64130-3-other.stderr
index 6b40cc9184d..3475b66b375 100644
--- a/src/test/ui/async-await/issue-64130-3-other.stderr
+++ b/src/test/ui/async-await/issue-64130-3-other.stderr
@@ -16,7 +16,7 @@ note: future does not implement `Qux` as this value is used across an await
   --> $DIR/issue-64130-3-other.rs:18:5
    |
 LL |     let x = Foo;
-   |         - has type `Foo`
+   |         - has type `Foo` which does not implement `Qux`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `x` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr
index 1e52d74f155..fc231d394c1 100644
--- a/src/test/ui/async-await/issue-64130-4-async-move.stderr
+++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr
@@ -2,7 +2,7 @@ error: future cannot be sent between threads safely
   --> $DIR/issue-64130-4-async-move.rs:15:17
    |
 LL |   pub fn foo() -> impl Future + Send {
-   |                   ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
+   |                   ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
 ...
 LL | /     async move {
 LL | |         match client.status() {
@@ -18,7 +18,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-4-async-move.rs:21:26
    |
 LL |         match client.status() {
-   |               ------ has type `&Client`
+   |               ------ has type `&Client` which is not `Send`
 LL |             200 => {
 LL |                 let _x = get().await;
    |                          ^^^^^^^^^^^ await occurs here, with `client` maybe used later
diff --git a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
index 0f4441edb13..f72757339cc 100644
--- a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
+++ b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr
@@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-non-send-future-diags.rs:15:5
    |
 LL |     let g = x.lock().unwrap();
-   |         - has type `std::sync::MutexGuard<'_, u32>`
+   |         - has type `std::sync::MutexGuard<'_, u32>` which is not `Send`
 LL |     baz().await;
    |     ^^^^^^^^^^^ await occurs here, with `g` maybe used later
 LL | }
diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
index cbcc3cf5d78..b43478ee207 100644
--- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr
+++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
@@ -5,14 +5,14 @@ LL | fn spawn<T: Send>(_: T) {}
    |             ---- required by this bound in `spawn`
 ...
 LL |     spawn(async {
-   |     ^^^^^ future is not `Send`
+   |     ^^^^^ future created by async block is not `Send`
    |
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*mut ()`
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-67252-unnamed-future.rs:20:9
    |
 LL |         let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
-   |             -- has type `*mut ()`
+   |             -- has type `*mut ()` which is not `Send`
 LL |         AFuture.await;
    |         ^^^^^^^^^^^^^ await occurs here, with `_a` maybe used later
 LL |     });
diff --git a/src/test/ui/async-await/issue-68112.rs b/src/test/ui/async-await/issue-68112.rs
new file mode 100644
index 00000000000..11b17836808
--- /dev/null
+++ b/src/test/ui/async-await/issue-68112.rs
@@ -0,0 +1,64 @@
+// edition:2018
+
+use std::{
+    future::Future,
+    cell::RefCell,
+    sync::Arc,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+fn require_send(_: impl Send) {}
+
+struct Ready<T>(Option<T>);
+impl<T> Future for Ready<T> {
+    type Output = T;
+    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
+        Poll::Ready(self.0.take().unwrap())
+    }
+}
+fn ready<T>(t: T) -> Ready<T> {
+    Ready(Some(t))
+}
+
+fn make_non_send_future1() -> impl Future<Output = Arc<RefCell<i32>>> {
+    ready(Arc::new(RefCell::new(0)))
+}
+
+fn test1() {
+    let send_fut = async {
+        let non_send_fut = make_non_send_future1();
+        let _ = non_send_fut.await;
+        ready(0).await;
+    };
+    require_send(send_fut);
+    //~^ ERROR future cannot be sent between threads
+}
+
+fn test1_no_let() {
+    let send_fut = async {
+        let _ = make_non_send_future1().await;
+        ready(0).await;
+    };
+    require_send(send_fut);
+    //~^ ERROR future cannot be sent between threads
+}
+
+async fn ready2<T>(t: T) -> T { t }
+fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
+    ready2(Arc::new(RefCell::new(0)))
+}
+
+// Ideally this test would have diagnostics similar to the test above, but right
+// now it doesn't.
+fn test2() {
+    let send_fut = async {
+        let non_send_fut = make_non_send_future2();
+        let _ = non_send_fut.await;
+        ready(0).await;
+    };
+    require_send(send_fut);
+    //~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr
new file mode 100644
index 00000000000..6ded3e475bc
--- /dev/null
+++ b/src/test/ui/async-await/issue-68112.stderr
@@ -0,0 +1,56 @@
+error: future cannot be sent between threads safely
+  --> $DIR/issue-68112.rs:34:5
+   |
+LL | fn require_send(_: impl Send) {}
+   |                         ---- required by this bound in `require_send`
+...
+LL |     require_send(send_fut);
+   |     ^^^^^^^^^^^^ future created by async block is not `Send`
+   |
+   = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
+note: future is not `Send` as it awaits another future which is not `Send`
+  --> $DIR/issue-68112.rs:31:17
+   |
+LL |         let _ = non_send_fut.await;
+   |                 ^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send`
+
+error: future cannot be sent between threads safely
+  --> $DIR/issue-68112.rs:43:5
+   |
+LL | fn require_send(_: impl Send) {}
+   |                         ---- required by this bound in `require_send`
+...
+LL |     require_send(send_fut);
+   |     ^^^^^^^^^^^^ future created by async block is not `Send`
+   |
+   = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
+note: future is not `Send` as it awaits another future which is not `Send`
+  --> $DIR/issue-68112.rs:40:17
+   |
+LL |         let _ = make_non_send_future1().await;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send`
+
+error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
+  --> $DIR/issue-68112.rs:60:5
+   |
+LL | fn require_send(_: impl Send) {}
+   |                         ---- required by this bound in `require_send`
+...
+LL |     require_send(send_fut);
+   |     ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>`
+   = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36 t:std::sync::Arc<std::cell::RefCell<i32>> {}]`
+   = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36 t:std::sync::Arc<std::cell::RefCell<i32>> {}]>`
+   = note: required because it appears within the type `impl std::future::Future`
+   = note: required because it appears within the type `impl std::future::Future`
+   = note: required because it appears within the type `impl std::future::Future`
+   = note: required because it appears within the type `{std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}`
+   = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]`
+   = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]>`
+   = note: required because it appears within the type `impl std::future::Future`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr
index d2fa7e58f6a..496ca506c60 100644
--- a/src/test/ui/async-await/issue-70594.stderr
+++ b/src/test/ui/async-await/issue-70594.stderr
@@ -32,11 +32,8 @@ error[E0277]: the trait bound `(): std::future::Future` is not satisfied
    |
 LL |     [1; ().await];
    |         ^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
-   | 
-  ::: $SRC_DIR/libcore/future/mod.rs:LL:COL
    |
-LL |     F: Future,
-   |        ------ required by this bound in `std::future::poll_with_context`
+   = note: required by `std::future::Future::poll`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 2417b592c7d..ec4e9e397a8 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -32,11 +32,8 @@ error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std:
    |
 LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
-   | 
-  ::: $SRC_DIR/libcore/future/mod.rs:LL:COL
    |
-LL |     F: Future,
-   |        ------ required by this bound in `std::future::poll_with_context`
+   = note: required by `std::future::Future::poll`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
index 73e2a92d815..49cd30e11a0 100644
--- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
+++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr
@@ -5,7 +5,7 @@ LL | fn assert_send<T: Send>(_: T) {}
    |                   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send(async {
-   |     ^^^^^^^^^^^ future returned by `main` is not `Send`
+   |     ^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*const u8`
 note: future is not `Send` as this value is used across an await
@@ -14,7 +14,7 @@ note: future is not `Send` as this value is used across an await
 LL |         bar(Foo(std::ptr::null())).await;
    |         ^^^^^^^^----------------^^^^^^^^- `std::ptr::null()` is later dropped here
    |         |       |
-   |         |       has type `*const u8`
+   |         |       has type `*const u8` which is not `Send`
    |         await occurs here, with `std::ptr::null()` maybe used later
 help: consider moving this into a `let` binding to create a shorter lived borrow
   --> $DIR/issue-65436-raw-ptr-not-send.rs:14:13
diff --git a/src/test/ui/const-generics/const-fn-with-const-param.rs b/src/test/ui/const-generics/const-fn-with-const-param.rs
index e9e236be556..3d8b77bcf7b 100644
--- a/src/test/ui/const-generics/const-fn-with-const-param.rs
+++ b/src/test/ui/const-generics/const-fn-with-const-param.rs
@@ -1,11 +1,11 @@
+// run-pass
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
 const fn const_u32_identity<const X: u32>() -> u32 {
-    //~^ ERROR const parameters are not permitted in const functions
     X
 }
 
 fn main() {
-    println!("{:?}", const_u32_identity::<18>());
+    assert_eq!(const_u32_identity::<18>(), 18);
 }
diff --git a/src/test/ui/const-generics/const-fn-with-const-param.stderr b/src/test/ui/const-generics/const-fn-with-const-param.stderr
index e944b02101e..64b9c18a8f5 100644
--- a/src/test/ui/const-generics/const-fn-with-const-param.stderr
+++ b/src/test/ui/const-generics/const-fn-with-const-param.stderr
@@ -1,23 +1,10 @@
-error: const parameters are not permitted in const functions
-  --> $DIR/const-fn-with-const-param.rs:4:1
-   |
-LL |   const fn const_u32_identity<const X: u32>() -> u32 {
-   |   ^----
-   |   |
-   |  _`const` because of this
-   | |
-LL | |
-LL | |     X
-LL | | }
-   | |_^
-
 warning: the feature `const_generics` is incomplete and may cause the compiler to crash
-  --> $DIR/const-fn-with-const-param.rs:1:12
+  --> $DIR/const-fn-with-const-param.rs:2:12
    |
 LL | #![feature(const_generics)]
    |            ^^^^^^^^^^^^^^
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error: aborting due to previous error; 1 warning emitted
+warning: 1 warning emitted
 
diff --git a/src/test/ui/const-generics/issues/issue-62456.rs b/src/test/ui/const-generics/issues/issue-62456.rs
index 14b1190df0f..5d068eb7fc8 100644
--- a/src/test/ui/const-generics/issues/issue-62456.rs
+++ b/src/test/ui/const-generics/issues/issue-62456.rs
@@ -1,10 +1,9 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
-// build-pass
-
 fn foo<const N: usize>() {
     let _ = [0u64; N + 1];
+    //~^ ERROR constant expression depends on a generic parameter
 }
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-62456.stderr b/src/test/ui/const-generics/issues/issue-62456.stderr
index fc26f68d235..96a07110e73 100644
--- a/src/test/ui/const-generics/issues/issue-62456.stderr
+++ b/src/test/ui/const-generics/issues/issue-62456.stderr
@@ -6,5 +6,13 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-warning: 1 warning emitted
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-62456.rs:5:20
+   |
+LL |     let _ = [0u64; N + 1];
+   |                    ^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs
index 212e16253f6..264e693a008 100644
--- a/src/test/ui/const-generics/issues/issue-62504.rs
+++ b/src/test/ui/const-generics/issues/issue-62504.rs
@@ -17,6 +17,7 @@ impl<const X: usize> ArrayHolder<X> {
     pub const fn new() -> Self {
         ArrayHolder([0; Self::SIZE])
         //~^ ERROR: mismatched types
+        //~| ERROR constant expression depends on a generic parameter
     }
 }
 
diff --git a/src/test/ui/const-generics/issues/issue-62504.stderr b/src/test/ui/const-generics/issues/issue-62504.stderr
index 4482389bbdd..a3a864f770c 100644
--- a/src/test/ui/const-generics/issues/issue-62504.stderr
+++ b/src/test/ui/const-generics/issues/issue-62504.stderr
@@ -7,6 +7,14 @@ LL |         ArrayHolder([0; Self::SIZE])
    = note: expected array `[u32; _]`
               found array `[u32; _]`
 
-error: aborting due to previous error
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-62504.rs:18:25
+   |
+LL |         ArrayHolder([0; Self::SIZE])
+   |                         ^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/issues/issue-66205.rs b/src/test/ui/const-generics/issues/issue-66205.rs
index 2e47b4d1882..73ba4fa6aae 100644
--- a/src/test/ui/const-generics/issues/issue-66205.rs
+++ b/src/test/ui/const-generics/issues/issue-66205.rs
@@ -1,10 +1,9 @@
-// check-pass
-
 #![allow(incomplete_features, dead_code, unconditional_recursion)]
 #![feature(const_generics)]
 
 fn fact<const N: usize>() {
     fact::<{ N - 1 }>();
+    //~^ ERROR constant expression depends on a generic parameter
 }
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-66205.stderr b/src/test/ui/const-generics/issues/issue-66205.stderr
new file mode 100644
index 00000000000..2bd013e8b41
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-66205.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-66205.rs:5:12
+   |
+LL |     fact::<{ N - 1 }>();
+   |            ^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs
index 3d657b0947b..c8ee1821239 100644
--- a/src/test/ui/const-generics/issues/issue-67739.rs
+++ b/src/test/ui/const-generics/issues/issue-67739.rs
@@ -1,7 +1,5 @@
 // Regression test for #67739
 
-// check-pass
-
 #![allow(incomplete_features)]
 #![feature(const_generics)]
 
@@ -12,6 +10,7 @@ pub trait Trait {
 
     fn associated_size(&self) -> usize {
         [0u8; mem::size_of::<Self::Associated>()];
+        //~^ ERROR constant expression depends on a generic parameter
         0
     }
 }
diff --git a/src/test/ui/const-generics/issues/issue-67739.stderr b/src/test/ui/const-generics/issues/issue-67739.stderr
new file mode 100644
index 00000000000..27a56b8eb02
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-67739.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-67739.rs:12:15
+   |
+LL |         [0u8; mem::size_of::<Self::Associated>()];
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/const-eval/issue-52442.rs b/src/test/ui/consts/const-eval/issue-52442.rs
index df4cc8e3026..07fb491015a 100644
--- a/src/test/ui/consts/const-eval/issue-52442.rs
+++ b/src/test/ui/consts/const-eval/issue-52442.rs
@@ -1,4 +1,6 @@
 fn main() {
     [();  { &loop { break } as *const _ as usize } ];
     //~^ ERROR `loop` is not allowed in a `const`
+    //~| ERROR casting pointers to integers in constants is unstable
+    //~| ERROR evaluation of constant value failed
 }
diff --git a/src/test/ui/consts/const-eval/issue-52442.stderr b/src/test/ui/consts/const-eval/issue-52442.stderr
index 0ea974f1f66..eda2dbf0b6b 100644
--- a/src/test/ui/consts/const-eval/issue-52442.stderr
+++ b/src/test/ui/consts/const-eval/issue-52442.stderr
@@ -7,6 +7,22 @@ LL |     [();  { &loop { break } as *const _ as usize } ];
    = note: see issue #52000 <https://github.com/rust-lang/rust/issues/52000> for more information
    = help: add `#![feature(const_loop)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: casting pointers to integers in constants is unstable
+  --> $DIR/issue-52442.rs:2:13
+   |
+LL |     [();  { &loop { break } as *const _ as usize } ];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
+   = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/issue-52442.rs:2:13
+   |
+LL |     [();  { &loop { break } as *const _ as usize } ];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0080, E0658.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/issue-52432.rs b/src/test/ui/consts/issue-52432.rs
index ded79458e63..d719bf1b971 100644
--- a/src/test/ui/consts/issue-52432.rs
+++ b/src/test/ui/consts/issue-52432.rs
@@ -6,4 +6,5 @@ fn main() {
     //~| ERROR: type annotations needed
     [(); &(static || {}) as *const _ as usize];
     //~^ ERROR: closures cannot be static
+    //~| ERROR evaluation of constant value failed
 }
diff --git a/src/test/ui/consts/issue-52432.stderr b/src/test/ui/consts/issue-52432.stderr
index d25c11138f4..e9539d24118 100644
--- a/src/test/ui/consts/issue-52432.stderr
+++ b/src/test/ui/consts/issue-52432.stderr
@@ -16,7 +16,13 @@ error[E0282]: type annotations needed
 LL |     [(); &(static |x| {}) as *const _ as usize];
    |                    ^ consider giving this closure parameter a type
 
-error: aborting due to 3 previous errors
+error[E0080]: evaluation of constant value failed
+  --> $DIR/issue-52432.rs:7:10
+   |
+LL |     [(); &(static || {}) as *const _ as usize];
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0282, E0697.
-For more information about an error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0080, E0282, E0697.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs
new file mode 100644
index 00000000000..07af8310424
--- /dev/null
+++ b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+const HASH_LEN: usize = 20;
+struct Hash([u8; HASH_LEN]);
+fn init_hash(_: &mut [u8; HASH_LEN]) {}
+
+fn foo<'a>() -> &'a () {
+    Hash([0; HASH_LEN]);
+    init_hash(&mut [0; HASH_LEN]);
+    &()
+}
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/consts/too_generic_eval_ice.rs b/src/test/ui/consts/too_generic_eval_ice.rs
index 7e4d4dbe446..3ea5f88f07d 100644
--- a/src/test/ui/consts/too_generic_eval_ice.rs
+++ b/src/test/ui/consts/too_generic_eval_ice.rs
@@ -4,10 +4,9 @@ impl<A, B> Foo<A, B> {
     const HOST_SIZE: usize = std::mem::size_of::<B>();
 
     pub fn crash() -> bool {
-        [5; Self::HOST_SIZE] == [6; 0] //~ ERROR no associated item named `HOST_SIZE`
-        //~^ the size for values of type `A` cannot be known
-        //~| the size for values of type `B` cannot be known
-        //~| binary operation `==` cannot be applied to type `[{integer}; _]`
+        [5; Self::HOST_SIZE] == [6; 0]
+        //~^ ERROR constant expression depends on a generic parameter
+        //~| ERROR binary operation `==` cannot be applied to type `[{integer}; _]`
     }
 }
 
diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr
index 8b57d237516..8b29c533bcc 100644
--- a/src/test/ui/consts/too_generic_eval_ice.stderr
+++ b/src/test/ui/consts/too_generic_eval_ice.stderr
@@ -1,45 +1,10 @@
-error[E0599]: no associated item named `HOST_SIZE` found for struct `Foo<A, B>` in the current scope
-  --> $DIR/too_generic_eval_ice.rs:7:19
-   |
-LL | pub struct Foo<A, B>(A, B);
-   | --------------------------- associated item `HOST_SIZE` not found for this
-...
-LL |         [5; Self::HOST_SIZE] == [6; 0]
-   |                   ^^^^^^^^^ associated item not found in `Foo<A, B>`
-   |
-   = note: the method `HOST_SIZE` exists but the following trait bounds were not satisfied:
-           `A: std::marker::Sized`
-           `B: std::marker::Sized`
-
-error[E0277]: the size for values of type `A` cannot be known at compilation time
-  --> $DIR/too_generic_eval_ice.rs:7:13
-   |
-LL | pub struct Foo<A, B>(A, B);
-   |                - required by this bound in `Foo`
-LL | 
-LL | impl<A, B> Foo<A, B> {
-   |      - this type parameter needs to be `std::marker::Sized`
-...
-LL |         [5; Self::HOST_SIZE] == [6; 0]
-   |             ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `std::marker::Sized` is not implemented for `A`
-   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-
-error[E0277]: the size for values of type `B` cannot be known at compilation time
+error: constant expression depends on a generic parameter
   --> $DIR/too_generic_eval_ice.rs:7:13
    |
-LL | pub struct Foo<A, B>(A, B);
-   |                   - required by this bound in `Foo`
-LL | 
-LL | impl<A, B> Foo<A, B> {
-   |         - this type parameter needs to be `std::marker::Sized`
-...
 LL |         [5; Self::HOST_SIZE] == [6; 0]
-   |             ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |             ^^^^^^^^^^^^^^^
    |
-   = help: the trait `std::marker::Sized` is not implemented for `B`
-   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+   = note: this may fail depending on what value the parameter takes
 
 error[E0369]: binary operation `==` cannot be applied to type `[{integer}; _]`
   --> $DIR/too_generic_eval_ice.rs:7:30
@@ -49,7 +14,6 @@ LL |         [5; Self::HOST_SIZE] == [6; 0]
    |         |
    |         [{integer}; _]
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0369, E0599.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/error-codes/E0034.stderr b/src/test/ui/error-codes/E0034.stderr
index 7977e529a11..471512ca8f7 100644
--- a/src/test/ui/error-codes/E0034.stderr
+++ b/src/test/ui/error-codes/E0034.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Trait2` for the type `Tes
    |
 LL |     fn foo() {}
    |     ^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     Trait1::foo()
    |     ^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     Trait2::foo()
    |     ^^^^^^^^^^^
diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs
new file mode 100644
index 00000000000..9ab2abf7405
--- /dev/null
+++ b/src/test/ui/generator/issue-68112.rs
@@ -0,0 +1,56 @@
+#![feature(generators, generator_trait)]
+
+use std::{
+    cell::RefCell,
+    sync::Arc,
+    pin::Pin,
+    ops::{Generator, GeneratorState},
+};
+
+pub struct Ready<T>(Option<T>);
+impl<T> Generator<()> for Ready<T> {
+    type Return = T;
+    type Yield = ();
+    fn resume(mut self: Pin<&mut Self>, _args: ()) -> GeneratorState<(), T> {
+        GeneratorState::Complete(self.0.take().unwrap())
+    }
+}
+pub fn make_gen1<T>(t: T) -> Ready<T> {
+    Ready(Some(t))
+}
+
+fn require_send(_: impl Send) {}
+
+fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> {
+    make_gen1(Arc::new(RefCell::new(0)))
+}
+
+fn test1() {
+    let send_gen = || {
+        let _non_send_gen = make_non_send_generator();
+        yield;
+    };
+    require_send(send_gen);
+    //~^ ERROR generator cannot be sent between threads
+}
+
+pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
+    || {
+        yield;
+        t
+    }
+}
+fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
+    make_gen2(Arc::new(RefCell::new(0)))
+}
+
+fn test2() {
+    let send_gen = || {
+        let _non_send_gen = make_non_send_generator2();
+        yield;
+    };
+    require_send(send_gen);
+    //~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely
+}
+
+fn main() {}
diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr
new file mode 100644
index 00000000000..83536f2af14
--- /dev/null
+++ b/src/test/ui/generator/issue-68112.stderr
@@ -0,0 +1,40 @@
+error: generator cannot be sent between threads safely
+  --> $DIR/issue-68112.rs:33:5
+   |
+LL | fn require_send(_: impl Send) {}
+   |                         ---- required by this bound in `require_send`
+...
+LL |     require_send(send_gen);
+   |     ^^^^^^^^^^^^ generator is not `Send`
+   |
+   = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
+note: generator is not `Send` as this value is used across a yield
+  --> $DIR/issue-68112.rs:31:9
+   |
+LL |         let _non_send_gen = make_non_send_generator();
+   |             ------------- has type `impl std::ops::Generator` which is not `Send`
+LL |         yield;
+   |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
+LL |     };
+   |     - `_non_send_gen` is later dropped here
+
+error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
+  --> $DIR/issue-68112.rs:52:5
+   |
+LL | fn require_send(_: impl Send) {}
+   |                         ---- required by this bound in `require_send`
+...
+LL |     require_send(send_gen);
+   |     ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>`
+   = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6 t:std::sync::Arc<std::cell::RefCell<i32>> {()}]`
+   = note: required because it appears within the type `impl std::ops::Generator`
+   = note: required because it appears within the type `impl std::ops::Generator`
+   = note: required because it appears within the type `{impl std::ops::Generator, ()}`
+   = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6 {impl std::ops::Generator, ()}]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generator/not-send-sync.rs b/src/test/ui/generator/not-send-sync.rs
index 0db01c6f756..8ca5565fb2a 100644
--- a/src/test/ui/generator/not-send-sync.rs
+++ b/src/test/ui/generator/not-send-sync.rs
@@ -7,7 +7,7 @@ fn main() {
     fn assert_send<T: Send>(_: T) {}
 
     assert_sync(|| {
-        //~^ ERROR: future cannot be shared between threads safely
+        //~^ ERROR: generator cannot be shared between threads safely
         let a = Cell::new(2);
         yield;
     });
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index 5f5211b5092..5df2c1b52fb 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -11,21 +11,21 @@ LL |     assert_send(|| {
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell<i32>`
    = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:16:17: 20:6 a:&std::cell::Cell<i32> _]`
 
-error: future cannot be shared between threads safely
+error: generator cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:9:5
    |
 LL |     fn assert_sync<T: Sync>(_: T) {}
    |                       ---- required by this bound in `main::assert_sync`
 ...
 LL |     assert_sync(|| {
-   |     ^^^^^^^^^^^ future returned by `main` is not `Sync`
+   |     ^^^^^^^^^^^ generator is not `Sync`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
-note: future is not `Sync` as this value is used across an yield
+note: generator is not `Sync` as this value is used across a yield
   --> $DIR/not-send-sync.rs:12:9
    |
 LL |         let a = Cell::new(2);
-   |             - has type `std::cell::Cell<i32>`
+   |             - has type `std::cell::Cell<i32>` which is not `Sync`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `a` maybe used later
 LL |     });
diff --git a/src/test/ui/inference/inference_unstable_featured.stderr b/src/test/ui/inference/inference_unstable_featured.stderr
index fa908440e41..e23b934ac18 100644
--- a/src/test/ui/inference/inference_unstable_featured.stderr
+++ b/src/test/ui/inference/inference_unstable_featured.stderr
@@ -6,11 +6,11 @@ LL |     assert_eq!('x'.ipu_flatten(), 0);
    |
    = note: candidate #1 is defined in an impl of the trait `inference_unstable_iterator::IpuIterator` for the type `char`
    = note: candidate #2 is defined in an impl of the trait `inference_unstable_itertools::IpuItertools` for the type `char`
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     assert_eq!(inference_unstable_iterator::IpuIterator::ipu_flatten(&'x'), 0);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     assert_eq!(inference_unstable_itertools::IpuItertools::ipu_flatten(&'x'), 0);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/integer-literal-suffix-inference.rs b/src/test/ui/integer-literal-suffix-inference.rs
index 3f4bedc4c22..c320f2bb7b4 100644
--- a/src/test/ui/integer-literal-suffix-inference.rs
+++ b/src/test/ui/integer-literal-suffix-inference.rs
@@ -16,6 +16,7 @@ fn main() {
     fn id_i16(n: i16) -> i16 { n }
     fn id_i32(n: i32) -> i32 { n }
     fn id_i64(n: i64) -> i64 { n }
+    fn id_isize(n: isize) -> isize { n }
 
     // the smallest values that need these types
     let b8: u8 = 16;
@@ -27,6 +28,11 @@ fn main() {
     fn id_u16(n: u16) -> u16 { n }
     fn id_u32(n: u32) -> u32 { n }
     fn id_u64(n: u64) -> u64 { n }
+    fn id_usize(n: usize) -> usize { n }
+
+    // Values for testing *size
+    let asize: isize = 1;
+    let bsize: usize = 3;
 
     id_i8(a8); // ok
     id_i8(a16);
@@ -38,6 +44,9 @@ fn main() {
     id_i8(a64);
     //~^ ERROR mismatched types
     //~| expected `i8`, found `i64`
+    id_i8(asize);
+    //~^ ERROR mismatched types
+    //~| expected `i8`, found `isize`
 
     id_i16(a8);
     //~^ ERROR mismatched types
@@ -49,6 +58,9 @@ fn main() {
     id_i16(a64);
     //~^ ERROR mismatched types
     //~| expected `i16`, found `i64`
+    id_i16(asize);
+    //~^ ERROR mismatched types
+    //~| expected `i16`, found `isize`
 
     id_i32(a8);
     //~^ ERROR mismatched types
@@ -60,6 +72,9 @@ fn main() {
     id_i32(a64);
     //~^ ERROR mismatched types
     //~| expected `i32`, found `i64`
+    id_i32(asize);
+    //~^ ERROR mismatched types
+    //~| expected `i32`, found `isize`
 
     id_i64(a8);
     //~^ ERROR mismatched types
@@ -71,6 +86,23 @@ fn main() {
     //~^ ERROR mismatched types
     //~| expected `i64`, found `i32`
     id_i64(a64); // ok
+    id_i64(asize);
+    //~^ ERROR mismatched types
+    //~| expected `i64`, found `isize`
+
+    id_isize(a8);
+    //~^ ERROR mismatched types
+    //~| expected `isize`, found `i8`
+    id_isize(a16);
+    //~^ ERROR mismatched types
+    //~| expected `isize`, found `i16`
+    id_isize(a32);
+    //~^ ERROR mismatched types
+    //~| expected `isize`, found `i32`
+    id_isize(a64);
+    //~^ ERROR mismatched types
+    //~| expected `isize`, found `i64`
+    id_isize(asize); //ok
 
     id_i8(c8); // ok
     id_i8(c16);
@@ -126,6 +158,9 @@ fn main() {
     id_u8(b64);
     //~^ ERROR mismatched types
     //~| expected `u8`, found `u64`
+    id_u8(bsize);
+    //~^ ERROR mismatched types
+    //~| expected `u8`, found `usize`
 
     id_u16(b8);
     //~^ ERROR mismatched types
@@ -137,6 +172,9 @@ fn main() {
     id_u16(b64);
     //~^ ERROR mismatched types
     //~| expected `u16`, found `u64`
+    id_u16(bsize);
+    //~^ ERROR mismatched types
+    //~| expected `u16`, found `usize`
 
     id_u32(b8);
     //~^ ERROR mismatched types
@@ -148,6 +186,9 @@ fn main() {
     id_u32(b64);
     //~^ ERROR mismatched types
     //~| expected `u32`, found `u64`
+    id_u32(bsize);
+    //~^ ERROR mismatched types
+    //~| expected `u32`, found `usize`
 
     id_u64(b8);
     //~^ ERROR mismatched types
@@ -159,4 +200,21 @@ fn main() {
     //~^ ERROR mismatched types
     //~| expected `u64`, found `u32`
     id_u64(b64); // ok
+    id_u64(bsize);
+    //~^ ERROR mismatched types
+    //~| expected `u64`, found `usize`
+
+    id_usize(b8);
+    //~^ ERROR mismatched types
+    //~| expected `usize`, found `u8`
+    id_usize(b16);
+    //~^ ERROR mismatched types
+    //~| expected `usize`, found `u16`
+    id_usize(b32);
+    //~^ ERROR mismatched types
+    //~| expected `usize`, found `u32`
+    id_usize(b64);
+    //~^ ERROR mismatched types
+    //~| expected `usize`, found `u64`
+    id_usize(bsize); //ok
 }
diff --git a/src/test/ui/integer-literal-suffix-inference.stderr b/src/test/ui/integer-literal-suffix-inference.stderr
index a34f0645c6b..b8502768e1d 100644
--- a/src/test/ui/integer-literal-suffix-inference.stderr
+++ b/src/test/ui/integer-literal-suffix-inference.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:32:11
+  --> $DIR/integer-literal-suffix-inference.rs:38:11
    |
 LL |     id_i8(a16);
    |           ^^^ expected `i8`, found `i16`
@@ -10,7 +10,7 @@ LL |     id_i8(a16.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:35:11
+  --> $DIR/integer-literal-suffix-inference.rs:41:11
    |
 LL |     id_i8(a32);
    |           ^^^ expected `i8`, found `i32`
@@ -21,7 +21,7 @@ LL |     id_i8(a32.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:38:11
+  --> $DIR/integer-literal-suffix-inference.rs:44:11
    |
 LL |     id_i8(a64);
    |           ^^^ expected `i8`, found `i64`
@@ -32,7 +32,18 @@ LL |     id_i8(a64.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:42:12
+  --> $DIR/integer-literal-suffix-inference.rs:47:11
+   |
+LL |     id_i8(asize);
+   |           ^^^^^ expected `i8`, found `isize`
+   |
+help: you can convert an `isize` to `i8` and panic if the converted value wouldn't fit
+   |
+LL |     id_i8(asize.try_into().unwrap());
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:51:12
    |
 LL |     id_i16(a8);
    |            ^^
@@ -41,7 +52,7 @@ LL |     id_i16(a8);
    |            help: you can convert an `i8` to `i16`: `a8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:46:12
+  --> $DIR/integer-literal-suffix-inference.rs:55:12
    |
 LL |     id_i16(a32);
    |            ^^^ expected `i16`, found `i32`
@@ -52,7 +63,7 @@ LL |     id_i16(a32.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:49:12
+  --> $DIR/integer-literal-suffix-inference.rs:58:12
    |
 LL |     id_i16(a64);
    |            ^^^ expected `i16`, found `i64`
@@ -63,7 +74,18 @@ LL |     id_i16(a64.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:53:12
+  --> $DIR/integer-literal-suffix-inference.rs:61:12
+   |
+LL |     id_i16(asize);
+   |            ^^^^^ expected `i16`, found `isize`
+   |
+help: you can convert an `isize` to `i16` and panic if the converted value wouldn't fit
+   |
+LL |     id_i16(asize.try_into().unwrap());
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:65:12
    |
 LL |     id_i32(a8);
    |            ^^
@@ -72,7 +94,7 @@ LL |     id_i32(a8);
    |            help: you can convert an `i8` to `i32`: `a8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:56:12
+  --> $DIR/integer-literal-suffix-inference.rs:68:12
    |
 LL |     id_i32(a16);
    |            ^^^
@@ -81,7 +103,7 @@ LL |     id_i32(a16);
    |            help: you can convert an `i16` to `i32`: `a16.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:60:12
+  --> $DIR/integer-literal-suffix-inference.rs:72:12
    |
 LL |     id_i32(a64);
    |            ^^^ expected `i32`, found `i64`
@@ -92,7 +114,18 @@ LL |     id_i32(a64.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:64:12
+  --> $DIR/integer-literal-suffix-inference.rs:75:12
+   |
+LL |     id_i32(asize);
+   |            ^^^^^ expected `i32`, found `isize`
+   |
+help: you can convert an `isize` to `i32` and panic if the converted value wouldn't fit
+   |
+LL |     id_i32(asize.try_into().unwrap());
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:79:12
    |
 LL |     id_i64(a8);
    |            ^^
@@ -101,7 +134,7 @@ LL |     id_i64(a8);
    |            help: you can convert an `i8` to `i64`: `a8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:67:12
+  --> $DIR/integer-literal-suffix-inference.rs:82:12
    |
 LL |     id_i64(a16);
    |            ^^^
@@ -110,7 +143,7 @@ LL |     id_i64(a16);
    |            help: you can convert an `i16` to `i64`: `a16.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:70:12
+  --> $DIR/integer-literal-suffix-inference.rs:85:12
    |
 LL |     id_i64(a32);
    |            ^^^
@@ -119,7 +152,58 @@ LL |     id_i64(a32);
    |            help: you can convert an `i32` to `i64`: `a32.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:76:11
+  --> $DIR/integer-literal-suffix-inference.rs:89:12
+   |
+LL |     id_i64(asize);
+   |            ^^^^^ expected `i64`, found `isize`
+   |
+help: you can convert an `isize` to `i64` and panic if the converted value wouldn't fit
+   |
+LL |     id_i64(asize.try_into().unwrap());
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:93:14
+   |
+LL |     id_isize(a8);
+   |              ^^
+   |              |
+   |              expected `isize`, found `i8`
+   |              help: you can convert an `i8` to `isize`: `a8.into()`
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:96:14
+   |
+LL |     id_isize(a16);
+   |              ^^^
+   |              |
+   |              expected `isize`, found `i16`
+   |              help: you can convert an `i16` to `isize`: `a16.into()`
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:99:14
+   |
+LL |     id_isize(a32);
+   |              ^^^ expected `isize`, found `i32`
+   |
+help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
+   |
+LL |     id_isize(a32.try_into().unwrap());
+   |              ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:102:14
+   |
+LL |     id_isize(a64);
+   |              ^^^ expected `isize`, found `i64`
+   |
+help: you can convert an `i64` to `isize` and panic if the converted value wouldn't fit
+   |
+LL |     id_isize(a64.try_into().unwrap());
+   |              ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:108:11
    |
 LL |     id_i8(c16);
    |           ^^^ expected `i8`, found `i16`
@@ -130,7 +214,7 @@ LL |     id_i8(c16.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:79:11
+  --> $DIR/integer-literal-suffix-inference.rs:111:11
    |
 LL |     id_i8(c32);
    |           ^^^ expected `i8`, found `i32`
@@ -141,7 +225,7 @@ LL |     id_i8(c32.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:82:11
+  --> $DIR/integer-literal-suffix-inference.rs:114:11
    |
 LL |     id_i8(c64);
    |           ^^^ expected `i8`, found `i64`
@@ -152,7 +236,7 @@ LL |     id_i8(c64.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:86:12
+  --> $DIR/integer-literal-suffix-inference.rs:118:12
    |
 LL |     id_i16(c8);
    |            ^^
@@ -161,7 +245,7 @@ LL |     id_i16(c8);
    |            help: you can convert an `i8` to `i16`: `c8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:90:12
+  --> $DIR/integer-literal-suffix-inference.rs:122:12
    |
 LL |     id_i16(c32);
    |            ^^^ expected `i16`, found `i32`
@@ -172,7 +256,7 @@ LL |     id_i16(c32.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:93:12
+  --> $DIR/integer-literal-suffix-inference.rs:125:12
    |
 LL |     id_i16(c64);
    |            ^^^ expected `i16`, found `i64`
@@ -183,7 +267,7 @@ LL |     id_i16(c64.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:97:12
+  --> $DIR/integer-literal-suffix-inference.rs:129:12
    |
 LL |     id_i32(c8);
    |            ^^
@@ -192,7 +276,7 @@ LL |     id_i32(c8);
    |            help: you can convert an `i8` to `i32`: `c8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:100:12
+  --> $DIR/integer-literal-suffix-inference.rs:132:12
    |
 LL |     id_i32(c16);
    |            ^^^
@@ -201,7 +285,7 @@ LL |     id_i32(c16);
    |            help: you can convert an `i16` to `i32`: `c16.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:104:12
+  --> $DIR/integer-literal-suffix-inference.rs:136:12
    |
 LL |     id_i32(c64);
    |            ^^^ expected `i32`, found `i64`
@@ -212,7 +296,7 @@ LL |     id_i32(c64.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:108:12
+  --> $DIR/integer-literal-suffix-inference.rs:140:12
    |
 LL |     id_i64(a8);
    |            ^^
@@ -221,7 +305,7 @@ LL |     id_i64(a8);
    |            help: you can convert an `i8` to `i64`: `a8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:111:12
+  --> $DIR/integer-literal-suffix-inference.rs:143:12
    |
 LL |     id_i64(a16);
    |            ^^^
@@ -230,7 +314,7 @@ LL |     id_i64(a16);
    |            help: you can convert an `i16` to `i64`: `a16.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:114:12
+  --> $DIR/integer-literal-suffix-inference.rs:146:12
    |
 LL |     id_i64(a32);
    |            ^^^
@@ -239,7 +323,7 @@ LL |     id_i64(a32);
    |            help: you can convert an `i32` to `i64`: `a32.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:120:11
+  --> $DIR/integer-literal-suffix-inference.rs:152:11
    |
 LL |     id_u8(b16);
    |           ^^^ expected `u8`, found `u16`
@@ -250,7 +334,7 @@ LL |     id_u8(b16.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:123:11
+  --> $DIR/integer-literal-suffix-inference.rs:155:11
    |
 LL |     id_u8(b32);
    |           ^^^ expected `u8`, found `u32`
@@ -261,7 +345,7 @@ LL |     id_u8(b32.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:126:11
+  --> $DIR/integer-literal-suffix-inference.rs:158:11
    |
 LL |     id_u8(b64);
    |           ^^^ expected `u8`, found `u64`
@@ -272,7 +356,18 @@ LL |     id_u8(b64.try_into().unwrap());
    |           ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:130:12
+  --> $DIR/integer-literal-suffix-inference.rs:161:11
+   |
+LL |     id_u8(bsize);
+   |           ^^^^^ expected `u8`, found `usize`
+   |
+help: you can convert an `usize` to `u8` and panic if the converted value wouldn't fit
+   |
+LL |     id_u8(bsize.try_into().unwrap());
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:165:12
    |
 LL |     id_u16(b8);
    |            ^^
@@ -281,7 +376,7 @@ LL |     id_u16(b8);
    |            help: you can convert an `u8` to `u16`: `b8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:134:12
+  --> $DIR/integer-literal-suffix-inference.rs:169:12
    |
 LL |     id_u16(b32);
    |            ^^^ expected `u16`, found `u32`
@@ -292,7 +387,7 @@ LL |     id_u16(b32.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:137:12
+  --> $DIR/integer-literal-suffix-inference.rs:172:12
    |
 LL |     id_u16(b64);
    |            ^^^ expected `u16`, found `u64`
@@ -303,7 +398,18 @@ LL |     id_u16(b64.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:141:12
+  --> $DIR/integer-literal-suffix-inference.rs:175:12
+   |
+LL |     id_u16(bsize);
+   |            ^^^^^ expected `u16`, found `usize`
+   |
+help: you can convert an `usize` to `u16` and panic if the converted value wouldn't fit
+   |
+LL |     id_u16(bsize.try_into().unwrap());
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:179:12
    |
 LL |     id_u32(b8);
    |            ^^
@@ -312,7 +418,7 @@ LL |     id_u32(b8);
    |            help: you can convert an `u8` to `u32`: `b8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:144:12
+  --> $DIR/integer-literal-suffix-inference.rs:182:12
    |
 LL |     id_u32(b16);
    |            ^^^
@@ -321,7 +427,7 @@ LL |     id_u32(b16);
    |            help: you can convert an `u16` to `u32`: `b16.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:148:12
+  --> $DIR/integer-literal-suffix-inference.rs:186:12
    |
 LL |     id_u32(b64);
    |            ^^^ expected `u32`, found `u64`
@@ -332,7 +438,18 @@ LL |     id_u32(b64.try_into().unwrap());
    |            ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:152:12
+  --> $DIR/integer-literal-suffix-inference.rs:189:12
+   |
+LL |     id_u32(bsize);
+   |            ^^^^^ expected `u32`, found `usize`
+   |
+help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit
+   |
+LL |     id_u32(bsize.try_into().unwrap());
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:193:12
    |
 LL |     id_u64(b8);
    |            ^^
@@ -341,7 +458,7 @@ LL |     id_u64(b8);
    |            help: you can convert an `u8` to `u64`: `b8.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:155:12
+  --> $DIR/integer-literal-suffix-inference.rs:196:12
    |
 LL |     id_u64(b16);
    |            ^^^
@@ -350,7 +467,7 @@ LL |     id_u64(b16);
    |            help: you can convert an `u16` to `u64`: `b16.into()`
 
 error[E0308]: mismatched types
-  --> $DIR/integer-literal-suffix-inference.rs:158:12
+  --> $DIR/integer-literal-suffix-inference.rs:199:12
    |
 LL |     id_u64(b32);
    |            ^^^
@@ -358,6 +475,57 @@ LL |     id_u64(b32);
    |            expected `u64`, found `u32`
    |            help: you can convert an `u32` to `u64`: `b32.into()`
 
-error: aborting due to 36 previous errors
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:203:12
+   |
+LL |     id_u64(bsize);
+   |            ^^^^^ expected `u64`, found `usize`
+   |
+help: you can convert an `usize` to `u64` and panic if the converted value wouldn't fit
+   |
+LL |     id_u64(bsize.try_into().unwrap());
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:207:14
+   |
+LL |     id_usize(b8);
+   |              ^^
+   |              |
+   |              expected `usize`, found `u8`
+   |              help: you can convert an `u8` to `usize`: `b8.into()`
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:210:14
+   |
+LL |     id_usize(b16);
+   |              ^^^
+   |              |
+   |              expected `usize`, found `u16`
+   |              help: you can convert an `u16` to `usize`: `b16.into()`
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:213:14
+   |
+LL |     id_usize(b32);
+   |              ^^^ expected `usize`, found `u32`
+   |
+help: you can convert an `u32` to `usize` and panic if the converted value wouldn't fit
+   |
+LL |     id_usize(b32.try_into().unwrap());
+   |              ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/integer-literal-suffix-inference.rs:216:14
+   |
+LL |     id_usize(b64);
+   |              ^^^ expected `usize`, found `u64`
+   |
+help: you can convert an `u64` to `usize` and panic if the converted value wouldn't fit
+   |
+LL |     id_usize(b64.try_into().unwrap());
+   |              ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 52 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-18446.stderr b/src/test/ui/issues/issue-18446.stderr
index 3422add9dd9..11c8cfdcf66 100644
--- a/src/test/ui/issues/issue-18446.stderr
+++ b/src/test/ui/issues/issue-18446.stderr
@@ -5,9 +5,9 @@ LL |     x.foo();
    |     --^^^--
    |     | |
    |     | multiple `foo` found
-   |     help: disambiguate the method call for candidate #2: `T::foo(&x)`
+   |     help: disambiguate the associated function for candidate #2: `T::foo(&x)`
    |
-note: candidate #1 is defined in an impl for the type `dyn T`
+note: candidate #1 is defined in an impl for the type `(dyn T + 'a)`
   --> $DIR/issue-18446.rs:9:5
    |
 LL |     fn foo(&self) {}
diff --git a/src/test/ui/issues/issue-3702-2.stderr b/src/test/ui/issues/issue-3702-2.stderr
index b18e407c3d4..6d8d17292f2 100644
--- a/src/test/ui/issues/issue-3702-2.stderr
+++ b/src/test/ui/issues/issue-3702-2.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Add` for the type `isize`
    |
 LL |     fn to_int(&self) -> isize { *self }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |         ToPrimitive::to_int(&self) + other.to_int()
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |         Add::to_int(&self) + other.to_int()
    |         ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-39211.rs b/src/test/ui/issues/issue-39211.rs
index db101ae248c..c7b6f1d58f3 100644
--- a/src/test/ui/issues/issue-39211.rs
+++ b/src/test/ui/issues/issue-39211.rs
@@ -8,7 +8,8 @@ trait Mat {
 }
 
 fn m<M: Mat>() {
-    let a = [3; M::Row::DIM]; //~ ERROR associated type `Row` not found for `M`
+    let a = [3; M::Row::DIM];
+    //~^ ERROR constant expression depends on a generic parameter
 }
 fn main() {
 }
diff --git a/src/test/ui/issues/issue-39211.stderr b/src/test/ui/issues/issue-39211.stderr
index c14c663e5a1..c555983ea68 100644
--- a/src/test/ui/issues/issue-39211.stderr
+++ b/src/test/ui/issues/issue-39211.stderr
@@ -1,9 +1,10 @@
-error[E0220]: associated type `Row` not found for `M`
-  --> $DIR/issue-39211.rs:11:20
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-39211.rs:11:17
    |
 LL |     let a = [3; M::Row::DIM];
-   |                    ^^^ associated type `Row` not found
+   |                 ^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr
index feaf3dc753f..83d8770b2e0 100644
--- a/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr
+++ b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn
    |
 LL |     fn r#struct(&self) {
    |     ^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     async::r#struct(&r#fn {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     await::r#struct(&r#fn {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-66706.rs b/src/test/ui/issues/issue-66706.rs
index 5e64f63d533..02305191f6e 100644
--- a/src/test/ui/issues/issue-66706.rs
+++ b/src/test/ui/issues/issue-66706.rs
@@ -10,4 +10,17 @@ fn b() {
     //~^ ERROR expected identifier, found reserved identifier `_`
 }
 
+fn c() {
+    [0; [|&_: _ &_| {}; 0 ].len()]
+    //~^ ERROR expected `,`, found `&`
+    //~| ERROR mismatched types
+}
+
+fn d() {
+    [0; match [|f @ &ref _| () ] {} ]
+    //~^ ERROR expected identifier, found reserved identifier `_`
+    //~| ERROR `match` is not allowed in a `const`
+    //~| ERROR mismatched types
+}
+
 fn main() {}
diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr
index 6d290bccc7d..ea461cc5d03 100644
--- a/src/test/ui/issues/issue-66706.stderr
+++ b/src/test/ui/issues/issue-66706.stderr
@@ -12,6 +12,29 @@ error: expected identifier, found reserved identifier `_`
 LL |     [0; [|f @ &ref _| {} ; 0 ].len() ];
    |                    ^ expected identifier, found reserved identifier
 
+error: expected `,`, found `&`
+  --> $DIR/issue-66706.rs:14:17
+   |
+LL |     [0; [|&_: _ &_| {}; 0 ].len()]
+   |                -^ expected `,`
+   |                |
+   |                help: missing `,`
+
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/issue-66706.rs:20:26
+   |
+LL |     [0; match [|f @ &ref _| () ] {} ]
+   |                          ^ expected identifier, found reserved identifier
+
+error[E0658]: `match` is not allowed in a `const`
+  --> $DIR/issue-66706.rs:20:9
+   |
+LL |     [0; match [|f @ &ref _| () ] {} ]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information
+   = help: add `#![feature(const_if_match)]` to the crate attributes to enable
+
 error[E0282]: type annotations needed
   --> $DIR/issue-66706.rs:2:11
    |
@@ -26,7 +49,23 @@ LL | fn a() {
 LL |     [0; [|_: _ &_| ()].len()]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
 
-error: aborting due to 4 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-66706.rs:14:5
+   |
+LL | fn c() {
+   |        - help: try adding a return type: `-> [{integer}; _]`
+LL |     [0; [|&_: _ &_| {}; 0 ].len()]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-66706.rs:20:5
+   |
+LL | fn d() {
+   |        - help: try adding a return type: `-> [{integer}; _]`
+LL |     [0; match [|f @ &ref _| () ] {} ]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
+
+error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0282, E0308.
+Some errors have detailed explanations: E0282, E0308, E0658.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
index 2c5257ce063..6ac3eb53cb3 100644
--- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
@@ -19,4 +19,5 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA`
 
 fn main() {
     let _ = [0; B::VALUE];
+    //~^ ERROR constant expression depends on a generic parameter
 }
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
index 8ae0f8b804c..175e6b0eaa0 100644
--- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
@@ -13,7 +13,15 @@ LL |     type MyA: TraitA;
 LL | impl TraitB for B {
    | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation
 
-error: aborting due to 2 previous errors
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17
+   |
+LL |     let _ = [0; B::VALUE];
+   |                 ^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0046, E0437.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/src/test/ui/issues/issue-69841.rs b/src/test/ui/issues/issue-69841.rs
index 942b99b742b..1aca16ca804 100644
--- a/src/test/ui/issues/issue-69841.rs
+++ b/src/test/ui/issues/issue-69841.rs
@@ -2,6 +2,7 @@
 // LLVM bug which needed a fix to be backported.
 
 // run-pass
+// no-system-llvm
 
 fn main() {
     let buffer = [49u8, 10];
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
index ce9b02b6d82..a2fb5ad8b8b 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr
@@ -1,146 +1,152 @@
-error: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:18:20
    |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left with overflow
+LL |     const N: i32 = T::N << 42;
+   |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
   --> $DIR/lint-exceeding-bitshifts.rs:9:9
    |
-LL | #![deny(arithmetic_overflow, const_err)]
+LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+   |
+LL |     let _ = x << 42;
+   |             ^^^^^^^ attempt to shift left with overflow
+
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:27:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:29:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:31:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:33:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:35:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:37:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:39:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:41:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:44:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:46:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:48:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:50:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:52:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:54:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:56:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:58:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:62:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:64:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:69:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:71:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:78:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: aborting due to 23 previous errors
+warning: 24 warnings emitted
 
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
index ce9b02b6d82..a2fb5ad8b8b 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr
@@ -1,146 +1,152 @@
-error: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:18:20
    |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left with overflow
+LL |     const N: i32 = T::N << 42;
+   |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
   --> $DIR/lint-exceeding-bitshifts.rs:9:9
    |
-LL | #![deny(arithmetic_overflow, const_err)]
+LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+   |
+LL |     let _ = x << 42;
+   |             ^^^^^^^ attempt to shift left with overflow
+
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:27:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:29:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:31:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:33:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:35:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:37:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:39:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:41:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:44:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:46:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:48:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:50:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:52:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:54:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:56:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:58:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:62:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:64:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:69:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:71:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:78:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: aborting due to 23 previous errors
+warning: 24 warnings emitted
 
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
index ce9b02b6d82..a2fb5ad8b8b 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr
@@ -1,146 +1,152 @@
-error: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:18:20
    |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left with overflow
+LL |     const N: i32 = T::N << 42;
+   |                    ^^^^^^^^^^ attempt to shift left with overflow
    |
 note: the lint level is defined here
   --> $DIR/lint-exceeding-bitshifts.rs:9:9
    |
-LL | #![deny(arithmetic_overflow, const_err)]
+LL | #![warn(arithmetic_overflow, const_err)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
+  --> $DIR/lint-exceeding-bitshifts.rs:22:13
+   |
+LL |     let _ = x << 42;
+   |             ^^^^^^^ attempt to shift left with overflow
+
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:27:15
    |
 LL |       let n = 1u8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:29:15
    |
 LL |       let n = 1u16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:31:15
    |
 LL |       let n = 1u32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:33:15
    |
 LL |       let n = 1u64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:35:15
    |
 LL |       let n = 1i8 << 8;
    |               ^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:37:15
    |
 LL |       let n = 1i16 << 16;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:39:15
    |
 LL |       let n = 1i32 << 32;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:41:15
    |
 LL |       let n = 1i64 << 64;
    |               ^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:44:15
    |
 LL |       let n = 1u8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:46:15
    |
 LL |       let n = 1u16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:48:15
    |
 LL |       let n = 1u32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:50:15
    |
 LL |       let n = 1u64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:52:15
    |
 LL |       let n = 1i8 >> 8;
    |               ^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:54:15
    |
 LL |       let n = 1i16 >> 16;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:56:15
    |
 LL |       let n = 1i32 >> 32;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:58:15
    |
 LL |       let n = 1i64 >> 64;
    |               ^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:62:15
    |
 LL |       let n = n << 8;
    |               ^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:64:15
    |
 LL |       let n = 1u8 << -8;
    |               ^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:69:15
    |
 LL |       let n = 1u8 << (4+4);
    |               ^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:71:15
    |
 LL |       let n = 1i64 >> [64][0];
    |               ^^^^^^^^^^^^^^^ attempt to shift right with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:77:15
    |
 LL |       let n = 1_isize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: this arithmetic operation will overflow
+warning: this arithmetic operation will overflow
   --> $DIR/lint-exceeding-bitshifts.rs:78:15
    |
 LL |       let n = 1_usize << BITS;
    |               ^^^^^^^^^^^^^^^ attempt to shift left with overflow
 
-error: aborting due to 23 previous errors
+warning: 24 warnings emitted
 
diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.rs b/src/test/ui/lint/lint-exceeding-bitshifts.rs
index 7deee5320a8..5d0cfd3ab78 100644
--- a/src/test/ui/lint/lint-exceeding-bitshifts.rs
+++ b/src/test/ui/lint/lint-exceeding-bitshifts.rs
@@ -3,10 +3,10 @@
 //[opt]compile-flags: -O
 //[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
 
-// build-fail
+// build-pass
 
 #![crate_type="lib"]
-#![deny(arithmetic_overflow, const_err)]
+#![warn(arithmetic_overflow, const_err)]
 #![allow(unused_variables)]
 #![allow(dead_code)]
 
@@ -15,65 +15,65 @@ pub trait Foo {
 }
 
 impl<T: Foo> Foo for Vec<T> {
-    const N: i32 = T::N << 42; // FIXME this should warn
+    const N: i32 = T::N << 42; //~ WARN: arithmetic operation will overflow
 }
 
 pub fn foo(x: i32) {
-    let _ = x << 42; //~ ERROR: arithmetic operation will overflow
+    let _ = x << 42; //~ WARN: arithmetic operation will overflow
 }
 
 pub fn main() {
       let n = 1u8 << 7;
-      let n = 1u8 << 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1u8 << 8;   //~ WARN: arithmetic operation will overflow
       let n = 1u16 << 15;
-      let n = 1u16 << 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1u16 << 16; //~ WARN: arithmetic operation will overflow
       let n = 1u32 << 31;
-      let n = 1u32 << 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1u32 << 32; //~ WARN: arithmetic operation will overflow
       let n = 1u64 << 63;
-      let n = 1u64 << 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1u64 << 64; //~ WARN: arithmetic operation will overflow
       let n = 1i8 << 7;
-      let n = 1i8 << 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1i8 << 8;   //~ WARN: arithmetic operation will overflow
       let n = 1i16 << 15;
-      let n = 1i16 << 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1i16 << 16; //~ WARN: arithmetic operation will overflow
       let n = 1i32 << 31;
-      let n = 1i32 << 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1i32 << 32; //~ WARN: arithmetic operation will overflow
       let n = 1i64 << 63;
-      let n = 1i64 << 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1i64 << 64; //~ WARN: arithmetic operation will overflow
 
       let n = 1u8 >> 7;
-      let n = 1u8 >> 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1u8 >> 8;   //~ WARN: arithmetic operation will overflow
       let n = 1u16 >> 15;
-      let n = 1u16 >> 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1u16 >> 16; //~ WARN: arithmetic operation will overflow
       let n = 1u32 >> 31;
-      let n = 1u32 >> 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1u32 >> 32; //~ WARN: arithmetic operation will overflow
       let n = 1u64 >> 63;
-      let n = 1u64 >> 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1u64 >> 64; //~ WARN: arithmetic operation will overflow
       let n = 1i8 >> 7;
-      let n = 1i8 >> 8;   //~ ERROR: arithmetic operation will overflow
+      let n = 1i8 >> 8;   //~ WARN: arithmetic operation will overflow
       let n = 1i16 >> 15;
-      let n = 1i16 >> 16; //~ ERROR: arithmetic operation will overflow
+      let n = 1i16 >> 16; //~ WARN: arithmetic operation will overflow
       let n = 1i32 >> 31;
-      let n = 1i32 >> 32; //~ ERROR: arithmetic operation will overflow
+      let n = 1i32 >> 32; //~ WARN: arithmetic operation will overflow
       let n = 1i64 >> 63;
-      let n = 1i64 >> 64; //~ ERROR: arithmetic operation will overflow
+      let n = 1i64 >> 64; //~ WARN: arithmetic operation will overflow
 
       let n = 1u8;
       let n = n << 7;
-      let n = n << 8; //~ ERROR: arithmetic operation will overflow
+      let n = n << 8; //~ WARN: arithmetic operation will overflow
 
-      let n = 1u8 << -8; //~ ERROR: arithmetic operation will overflow
+      let n = 1u8 << -8; //~ WARN: arithmetic operation will overflow
 
       let n = 1i8<<(1isize+-1);
 
       let n = 1u8 << (4+3);
-      let n = 1u8 << (4+4); //~ ERROR: arithmetic operation will overflow
+      let n = 1u8 << (4+4); //~ WARN: arithmetic operation will overflow
       let n = 1i64 >> [63][0];
-      let n = 1i64 >> [64][0]; //~ ERROR: arithmetic operation will overflow
+      let n = 1i64 >> [64][0]; //~ WARN: arithmetic operation will overflow
 
       #[cfg(target_pointer_width = "32")]
       const BITS: usize = 32;
       #[cfg(target_pointer_width = "64")]
       const BITS: usize = 64;
-      let n = 1_isize << BITS; //~ ERROR: arithmetic operation will overflow
-      let n = 1_usize << BITS; //~ ERROR: arithmetic operation will overflow
+      let n = 1_isize << BITS; //~ WARN: arithmetic operation will overflow
+      let n = 1_usize << BITS; //~ WARN: arithmetic operation will overflow
 }
diff --git a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr
index fa3add81a28..1b354fc697a 100644
--- a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr
+++ b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr
@@ -10,11 +10,11 @@ note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize`
 LL | impl Me2 for usize { fn me(&self) -> usize { *self } }
    |                      ^^^^^^^^^^^^^^^^^^^^^
    = note: candidate #2 is defined in an impl of the trait `ambig_impl_2_lib::Me` for the type `usize`
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL | fn main() { Me2::me(&1_usize); }
    |             ^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL | fn main() { ambig_impl_2_lib::Me::me(&1_usize); }
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr b/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr
index b6c81c2377e..5cbed652b0a 100644
--- a/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr
+++ b/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B`
    |
 LL | trait B { fn foo(&self); }
    |           ^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     A::foo(t);
    |     ^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     B::foo(t);
    |     ^^^^^^^^^
diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr
index 71c65f7ccc6..8585929934e 100644
--- a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr
+++ b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `AB`
    |
 LL |     fn foo(self) {}
    |     ^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     A::foo(AB {});
    |     ^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     B::foo(AB {});
    |     ^^^^^^^^^^^^^
diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr
index 24946410887..85b39647885 100644
--- a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr
+++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `AB`
    |
 LL |     fn foo() {}
    |     ^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     A::foo();
    |     ^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     B::foo();
    |     ^^^^^^
diff --git a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr
index 3dbb1737100..4ce7236ed96 100644
--- a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr
+++ b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize`
    |
 LL | trait Bar { fn method(&self) {} }
    |             ^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     Foo::method(&1_usize);
    |     ^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     Bar::method(&1_usize);
    |     ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
index e7f295df8c4..1bc7f30d04d 100644
--- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
+++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
@@ -20,12 +20,12 @@ error[E0034]: multiple applicable items in scope
 LL |     let z = x.foo();
    |               ^^^ multiple `foo` found
    |
-note: candidate #1 is defined in an impl of the trait `internal::X` for the type `_`
+note: candidate #1 is defined in an impl of the trait `internal::X` for the type `T`
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:43:9
    |
 LL |         fn foo(self: Smaht<Self, u64>) -> u64 {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `_`
+note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `T`
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:70:9
    |
 LL |         fn foo(self) {}
@@ -35,15 +35,15 @@ note: candidate #3 is defined in the trait `FinalFoo`
    |
 LL |     fn foo(&self) -> u8;
    |     ^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     let z = internal::X::foo(x);
    |             ^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     let z = nuisance_foo::NuisanceFoo::foo(x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #3
+help: disambiguate the associated function for candidate #3
    |
 LL |     let z = FinalFoo::foo(x);
    |             ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/numeric/numeric-cast.fixed b/src/test/ui/numeric/numeric-cast.fixed
index 6f78228a85d..31acdb8faf6 100644
--- a/src/test/ui/numeric/numeric-cast.fixed
+++ b/src/test/ui/numeric/numeric-cast.fixed
@@ -24,9 +24,9 @@ fn main() {
     //~^ ERROR mismatched types
     foo::<usize>(x_u32.try_into().unwrap());
     //~^ ERROR mismatched types
-    foo::<usize>(x_u16.try_into().unwrap());
+    foo::<usize>(x_u16.into());
     //~^ ERROR mismatched types
-    foo::<usize>(x_u8.try_into().unwrap());
+    foo::<usize>(x_u8.into());
     //~^ ERROR mismatched types
     foo::<usize>(x_isize.try_into().unwrap());
     //~^ ERROR mismatched types
@@ -56,9 +56,9 @@ fn main() {
     //~^ ERROR mismatched types
     foo::<isize>(x_i32.try_into().unwrap());
     //~^ ERROR mismatched types
-    foo::<isize>(x_i16.try_into().unwrap());
+    foo::<isize>(x_i16.into());
     //~^ ERROR mismatched types
-    foo::<isize>(x_i8.try_into().unwrap());
+    foo::<isize>(x_i8.into());
     //~^ ERROR mismatched types
     // foo::<isize>(x_f64);
     // foo::<isize>(x_f32);
diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr
index eef40cbdbe4..ff92a86c3a7 100644
--- a/src/test/ui/numeric/numeric-cast.stderr
+++ b/src/test/ui/numeric/numeric-cast.stderr
@@ -24,23 +24,19 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:27:18
    |
 LL |     foo::<usize>(x_u16);
-   |                  ^^^^^ expected `usize`, found `u16`
-   |
-help: you can convert an `u16` to `usize` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<usize>(x_u16.try_into().unwrap());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^
+   |                  |
+   |                  expected `usize`, found `u16`
+   |                  help: you can convert an `u16` to `usize`: `x_u16.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:29:18
    |
 LL |     foo::<usize>(x_u8);
-   |                  ^^^^ expected `usize`, found `u8`
-   |
-help: you can convert an `u8` to `usize` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<usize>(x_u8.try_into().unwrap());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^
+   |                  |
+   |                  expected `usize`, found `u8`
+   |                  help: you can convert an `u8` to `usize`: `x_u8.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:31:18
@@ -178,23 +174,19 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:59:18
    |
 LL |     foo::<isize>(x_i16);
-   |                  ^^^^^ expected `isize`, found `i16`
-   |
-help: you can convert an `i16` to `isize` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<isize>(x_i16.try_into().unwrap());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^
+   |                  |
+   |                  expected `isize`, found `i16`
+   |                  help: you can convert an `i16` to `isize`: `x_i16.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:61:18
    |
 LL |     foo::<isize>(x_i8);
-   |                  ^^^^ expected `isize`, found `i8`
-   |
-help: you can convert an `i8` to `isize` and panic if the converted value wouldn't fit
-   |
-LL |     foo::<isize>(x_i8.try_into().unwrap());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^
+   |                  |
+   |                  expected `isize`, found `i8`
+   |                  help: you can convert an `i8` to `isize`: `x_i8.into()`
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:66:16
diff --git a/src/test/ui/option-to-result.rs b/src/test/ui/option-to-result.rs
new file mode 100644
index 00000000000..00e8b5244c5
--- /dev/null
+++ b/src/test/ui/option-to-result.rs
@@ -0,0 +1,13 @@
+fn main(){ }
+
+fn test_result() -> Result<(),()> {
+    let a:Option<()> = Some(());
+    a?;//~ ERROR `?` couldn't convert the error
+    Ok(())
+}
+
+fn test_option() -> Option<i32>{
+    let a:Result<i32, i32> = Ok(5);
+    a?;//~ ERROR `?` couldn't convert the error
+    Some(5)
+}
diff --git a/src/test/ui/option-to-result.stderr b/src/test/ui/option-to-result.stderr
new file mode 100644
index 00000000000..f673ef7fc1e
--- /dev/null
+++ b/src/test/ui/option-to-result.stderr
@@ -0,0 +1,29 @@
+error[E0277]: `?` couldn't convert the error to `()`
+  --> $DIR/option-to-result.rs:5:6
+   |
+LL |     a?;
+   |      ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
+   |
+   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
+   = note: required by `std::convert::From::from`
+help: consider converting the `Option<T>` into a `Result<T, _>` using `Option::ok_or` or `Option::ok_or_else`
+   |
+LL |     a.ok_or_else(|| /* error value */)?;
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `?` couldn't convert the error to `std::option::NoneError`
+  --> $DIR/option-to-result.rs:11:6
+   |
+LL |     a?;
+   |      ^ the trait `std::convert::From<i32>` is not implemented for `std::option::NoneError`
+   |
+   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
+   = note: required by `std::convert::From::from`
+help: consider converting the `Result<T, _>` into an `Option<T>` using `Result::ok`
+   |
+LL |     a.ok()?;
+   |      ^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs
new file mode 100644
index 00000000000..87222ef4b59
--- /dev/null
+++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs
@@ -0,0 +1,35 @@
+mod a {
+    use std::marker::PhantomData;
+
+    enum Bug {
+        V = [PhantomData; { [ () ].len() ].len() as isize,
+        //~^ ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+    }
+}
+
+mod b {
+    enum Bug {
+        V = [Vec::new; { [].len()  ].len() as isize,
+        //~^ ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR type annotations needed
+    }
+}
+
+mod c {
+    enum Bug {
+        V = [Vec::new; { [0].len() ].len() as isize,
+        //~^ ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR type annotations needed
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr
new file mode 100644
index 00000000000..f20ec755353
--- /dev/null
+++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr
@@ -0,0 +1,123 @@
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |                             ^^^ cannot infer type for type parameter `T`
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |              ^^^^^^^^ cannot infer type for type parameter `T`
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/span/issue-37767.stderr b/src/test/ui/span/issue-37767.stderr
index 9ed6c8b826f..fc6c556c16d 100644
--- a/src/test/ui/span/issue-37767.stderr
+++ b/src/test/ui/span/issue-37767.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B`
    |
 LL |     fn foo(&mut self) {}
    |     ^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     A::foo(&a)
    |     ^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     B::foo(&a)
    |     ^^^^^^^^^^
@@ -39,11 +39,11 @@ note: candidate #2 is defined in the trait `D`
    |
 LL |     fn foo(&self) {}
    |     ^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     C::foo(&a)
    |     ^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     D::foo(&a)
    |     ^^^^^^^^^^
@@ -64,11 +64,11 @@ note: candidate #2 is defined in the trait `F`
    |
 LL |     fn foo(self) {}
    |     ^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     E::foo(a)
    |     ^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     F::foo(a)
    |     ^^^^^^^^^
diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr
index 89b36848a28..16a1ac6d718 100644
--- a/src/test/ui/span/issue-7575.stderr
+++ b/src/test/ui/span/issue-7575.stderr
@@ -25,15 +25,15 @@ LL |     fn f9(_: usize) -> usize;
            candidate #1: `CtxtFn`
            candidate #2: `OtherTrait`
            candidate #3: `UnusedTrait`
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     u.f8(42) + CtxtFn::f9(u, 342) + m.fff(42)
    |                ^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     u.f8(42) + OtherTrait::f9(u, 342) + m.fff(42)
    |                ^^^^^^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #3
+help: disambiguate the associated function for candidate #3
    |
 LL |     u.f8(42) + UnusedTrait::f9(u, 342) + m.fff(42)
    |                ^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |     t.is_str()
    |     --^^^^^^--
    |     | |
    |     | this is an associated function, not a method
-   |     help: disambiguate the method call for the candidate: `ManyImplTrait::is_str(t)`
+   |     help: disambiguate the associated function for the candidate: `ManyImplTrait::is_str(t)`
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
 note: the candidate is defined in the trait `ManyImplTrait`
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr
index dfc1887d3af..f1c0cd6b543 100644
--- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr
@@ -11,7 +11,7 @@ LL |     x.default_hello();
    |     help: use associated function syntax instead: `GenericAssocMethod::<i32>::default_hello`
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-note: the candidate is defined in an impl for the type `GenericAssocMethod<_>`
+note: the candidate is defined in an impl for the type `GenericAssocMethod<T>`
   --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5
    |
 LL |     fn default_hello() {}
diff --git a/src/test/ui/traits/trait-alias-ambiguous.stderr b/src/test/ui/traits/trait-alias-ambiguous.stderr
index 48a029104ae..7c00bb5207b 100644
--- a/src/test/ui/traits/trait-alias-ambiguous.stderr
+++ b/src/test/ui/traits/trait-alias-ambiguous.stderr
@@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `inner::B` for the type `u
    |
 LL |         fn foo(&self) {}
    |         ^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #1
+help: disambiguate the associated function for candidate #1
    |
 LL |     inner::A::foo(&t);
    |     ^^^^^^^^^^^^^^^^^
-help: disambiguate the method call for candidate #2
+help: disambiguate the associated function for candidate #2
    |
 LL |     inner::B::foo(&t);
    |     ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/try-block/try-block-in-match.rs b/src/test/ui/try-block/try-block-in-match.rs
index bce0d0340b6..cd0b967e79d 100644
--- a/src/test/ui/try-block/try-block-in-match.rs
+++ b/src/test/ui/try-block/try-block-in-match.rs
@@ -1,7 +1,11 @@
+// run-pass
 // compile-flags: --edition 2018
 
 #![feature(try_blocks)]
 
 fn main() {
-    match try { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `try`
+    match try { } {
+        Err(()) => (),
+        Ok(()) => (),
+    }
 }
diff --git a/src/test/ui/try-block/try-block-in-match.stderr b/src/test/ui/try-block/try-block-in-match.stderr
deleted file mode 100644
index 936e0fe19ba..00000000000
--- a/src/test/ui/try-block/try-block-in-match.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: expected expression, found reserved keyword `try`
-  --> $DIR/try-block-in-match.rs:6:11
-   |
-LL |     match try { false } { _ => {} }
-   |     ----- ^^^ expected expression
-   |     |
-   |     while parsing this match expression
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/try-block/try-block-in-while.rs b/src/test/ui/try-block/try-block-in-while.rs
index 98af796dd37..33d27236519 100644
--- a/src/test/ui/try-block/try-block-in-while.rs
+++ b/src/test/ui/try-block/try-block-in-while.rs
@@ -3,5 +3,6 @@
 #![feature(try_blocks)]
 
 fn main() {
-    while try { false } {} //~ ERROR expected expression, found reserved keyword `try`
+    while try { false } {}
+    //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied
 }
diff --git a/src/test/ui/try-block/try-block-in-while.stderr b/src/test/ui/try-block/try-block-in-while.stderr
index 026df15eb87..ac41ddfd8c0 100644
--- a/src/test/ui/try-block/try-block-in-while.stderr
+++ b/src/test/ui/try-block/try-block-in-while.stderr
@@ -1,8 +1,11 @@
-error: expected expression, found reserved keyword `try`
-  --> $DIR/try-block-in-while.rs:6:11
+error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
+  --> $DIR/try-block-in-while.rs:6:15
    |
 LL |     while try { false } {}
-   |           ^^^ expected expression
+   |               ^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
+   |
+   = note: required by `std::ops::Try::from_ok`
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/try-block/try-block-unused-delims.rs b/src/test/ui/try-block/try-block-unused-delims.rs
new file mode 100644
index 00000000000..0b767eb2dad
--- /dev/null
+++ b/src/test/ui/try-block/try-block-unused-delims.rs
@@ -0,0 +1,28 @@
+// check-pass
+// compile-flags: --edition 2018
+
+#![feature(try_blocks)]
+#![warn(unused_parens, unused_braces)]
+
+fn consume<T>(_: Result<T, T>) -> T { todo!() }
+
+fn main() {
+    consume((try {}));
+    //~^ WARN unnecessary parentheses
+
+    consume({ try {} });
+    //~^ WARN unnecessary braces
+
+    match (try {}) {
+        //~^ WARN unnecessary parentheses
+        Ok(()) | Err(()) => (),
+    }
+
+    if let Err(()) = (try {}) {}
+    //~^ WARN unnecessary parentheses
+
+    match (try {}) {
+        //~^ WARN unnecessary parentheses
+        Ok(()) | Err(()) => (),
+    }
+}
diff --git a/src/test/ui/try-block/try-block-unused-delims.stderr b/src/test/ui/try-block/try-block-unused-delims.stderr
new file mode 100644
index 00000000000..5c7602ee0ab
--- /dev/null
+++ b/src/test/ui/try-block/try-block-unused-delims.stderr
@@ -0,0 +1,44 @@
+warning: unnecessary parentheses around function argument
+  --> $DIR/try-block-unused-delims.rs:10:13
+   |
+LL |     consume((try {}));
+   |             ^^^^^^^^ help: remove these parentheses
+   |
+note: the lint level is defined here
+  --> $DIR/try-block-unused-delims.rs:5:9
+   |
+LL | #![warn(unused_parens, unused_braces)]
+   |         ^^^^^^^^^^^^^
+
+warning: unnecessary braces around function argument
+  --> $DIR/try-block-unused-delims.rs:13:13
+   |
+LL |     consume({ try {} });
+   |             ^^^^^^^^^^ help: remove these braces
+   |
+note: the lint level is defined here
+  --> $DIR/try-block-unused-delims.rs:5:24
+   |
+LL | #![warn(unused_parens, unused_braces)]
+   |                        ^^^^^^^^^^^^^
+
+warning: unnecessary parentheses around `match` scrutinee expression
+  --> $DIR/try-block-unused-delims.rs:16:11
+   |
+LL |     match (try {}) {
+   |           ^^^^^^^^ help: remove these parentheses
+
+warning: unnecessary parentheses around `let` scrutinee expression
+  --> $DIR/try-block-unused-delims.rs:21:22
+   |
+LL |     if let Err(()) = (try {}) {}
+   |                      ^^^^^^^^ help: remove these parentheses
+
+warning: unnecessary parentheses around `match` scrutinee expression
+  --> $DIR/try-block-unused-delims.rs:24:11
+   |
+LL |     match (try {}) {
+   |           ^^^^^^^^ help: remove these parentheses
+
+warning: 5 warnings emitted
+
diff --git a/src/test/ui/try-on-option.stderr b/src/test/ui/try-on-option.stderr
index 07615b52a48..7a4bb75967b 100644
--- a/src/test/ui/try-on-option.stderr
+++ b/src/test/ui/try-on-option.stderr
@@ -6,6 +6,10 @@ LL |     x?;
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = note: required by `std::convert::From::from`
+help: consider converting the `Option<T>` into a `Result<T, _>` using `Option::ok_or` or `Option::ok_or_else`
+   |
+LL |     x.ok_or_else(|| /* error value */)?;
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
   --> $DIR/try-on-option.rs:13:5
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
new file mode 100644
index 00000000000..c54df664243
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type A = impl Sized;
+fn f1() -> A { 0 }
+
+type B = impl ?Sized;
+fn f2() -> &'static B { &[0] }
+
+type C = impl ?Sized + 'static;
+fn f3() -> &'static C { &[0] }
+
+type D = impl ?Sized;
+fn f4() -> &'static D { &1 }
+
+fn main() {}
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index f075d3e22d6..6de07d3e5cf 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -139,6 +139,7 @@ static TARGETS: &[&str] = &[
     "x86_64-pc-solaris",
     "x86_64-unknown-cloudabi",
     "x86_64-unknown-freebsd",
+    "x86_64-unknown-illumos",
     "x86_64-unknown-linux-gnu",
     "x86_64-unknown-linux-gnux32",
     "x86_64-unknown-linux-musl",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 390e8f245ef2cd7ac698b8a76abf029f9abcab0
+Subproject 74e3a7d5b756d7c0e94399fc29fcd154e792c22
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject af5940b73153b2a4ea2922aa803abac45d02998
+Subproject 6651c1b9b2a1b3e995565467218ff7eca7479c5
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 2944864abbf..61a7d8ee5c9 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -357,14 +357,15 @@ impl<'test> TestCx<'test> {
             Ui if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => {
                 WillExecute::Yes
             }
-            Ui => WillExecute::No,
+            MirOpt if pm == Some(PassMode::Run) => WillExecute::Yes,
+            Ui | MirOpt => WillExecute::No,
             mode => panic!("unimplemented for mode {:?}", mode),
         }
     }
 
     fn should_run_successfully(&self, pm: Option<PassMode>) -> bool {
         match self.config.mode {
-            Ui => pm == Some(PassMode::Run),
+            Ui | MirOpt => pm == Some(PassMode::Run),
             mode => panic!("unimplemented for mode {:?}", mode),
         }
     }
@@ -2809,10 +2810,16 @@ impl<'test> TestCx<'test> {
             self.document(&out_dir);
 
             let root = self.config.find_rust_src_root().unwrap();
+            let file_stem =
+                self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem");
             let res = self.cmd2procres(
                 Command::new(&nodejs)
                     .arg(root.join("src/tools/rustdoc-js/tester.js"))
-                    .arg(out_dir.parent().expect("no parent"))
+                    .arg("--doc-folder")
+                    .arg(out_dir)
+                    .arg("--crate-name")
+                    .arg(file_stem.replace("-", "_"))
+                    .arg("--test-file")
                     .arg(self.testpaths.file.with_extension("js")),
             );
             if !res.status.success() {
@@ -3059,18 +3066,24 @@ impl<'test> TestCx<'test> {
     }
 
     fn run_mir_opt_test(&self) {
-        let proc_res = self.compile_test(WillExecute::Yes, EmitMetadata::No);
+        let pm = self.pass_mode();
+        let should_run = self.should_run(pm);
+        let emit_metadata = self.should_emit_metadata(pm);
+        let proc_res = self.compile_test(should_run, emit_metadata);
 
         if !proc_res.status.success() {
             self.fatal_proc_rec("compilation failed!", &proc_res);
         }
 
-        let proc_res = self.exec_compiled_test();
+        self.check_mir_dump();
 
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("test run failed!", &proc_res);
+        if let WillExecute::Yes = should_run {
+            let proc_res = self.exec_compiled_test();
+
+            if !proc_res.status.success() {
+                self.fatal_proc_rec("test run failed!", &proc_res);
+            }
         }
-        self.check_mir_dump();
     }
 
     fn check_mir_dump(&self) {
@@ -3148,7 +3161,7 @@ impl<'test> TestCx<'test> {
                     }
                     let expected_string = fs::read_to_string(&expected_file).unwrap();
                     if dumped_string != expected_string {
-                        print_diff(&dumped_string, &expected_string, 3);
+                        print_diff(&expected_string, &dumped_string, 3);
                         panic!(
                             "Actual MIR output differs from expected MIR output {}",
                             expected_file.display()
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 2663b3d160a..c61bee0f8d9 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -21,6 +21,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[
     ("fuchsia", "fuchsia"),
     ("haiku", "haiku"),
     ("hermit", "hermit"),
+    ("illumos", "illumos"),
     ("ios", "ios"),
     ("l4re", "l4re"),
     ("linux", "linux"),
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 325682ad56d23369059ea93d5a8d44e5782e41c
+Subproject 5c823a1ec1eb3ff89bcbcb6c1fa8e1f8b24eb52
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 307239fa4c9..2da62b6bd99 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -39,7 +39,7 @@ MAINTAINERS = {
         'adamgreig', 'andre-richter', 'jamesmunns', 'korken89',
         'ryankurte', 'thejpster', 'therealprof',
     },
-    'edition-guide': {'ehuss', 'Centril', 'steveklabnik'},
+    'edition-guide': {'ehuss', 'steveklabnik'},
     'rustc-dev-guide': {'mark-i-m', 'spastorino', 'amanjeev', 'JohnTitor'},
 }
 
diff --git a/src/tools/rls b/src/tools/rls
-Subproject 1cfb87845f45758442830506b7242947dfc989d
+Subproject 2659cbf14bfb0929a16d7ce9b6858d0bb286ede
diff --git a/src/tools/rustdoc-js-common/lib.js b/src/tools/rustdoc-js-common/lib.js
deleted file mode 100644
index 81e64aec491..00000000000
--- a/src/tools/rustdoc-js-common/lib.js
+++ /dev/null
@@ -1,319 +0,0 @@
-const fs = require('fs');
-
-function getNextStep(content, pos, stop) {
-    while (pos < content.length && content[pos] !== stop &&
-           (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) {
-        pos += 1;
-    }
-    if (pos >= content.length) {
-        return null;
-    }
-    if (content[pos] !== stop) {
-        return pos * -1;
-    }
-    return pos;
-}
-
-// Stupid function extractor based on indent. Doesn't support block
-// comments. If someone puts a ' or an " in a block comment this
-// will blow up. Template strings are not tested and might also be
-// broken.
-function extractFunction(content, functionName) {
-    var indent = 0;
-    var splitter = "function " + functionName + "(";
-
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = start;
-        while (pos < content.length && content[pos] !== ')') {
-            pos += 1;
-        }
-        if (pos >= content.length) {
-            break;
-        }
-        pos = getNextStep(content, pos + 1, '{');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            // Eat single-line comments
-            if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') {
-                do {
-                    pos += 1;
-                } while (pos < content.length && content[pos] !== '\n');
-
-            // Eat quoted strings
-            } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") {
-                var stop = content[pos];
-                var is_escaped = false;
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-
-            // Otherwise, check for indent
-            } else if (content[pos] === '{') {
-                indent += 1;
-            } else if (content[pos] === '}') {
-                indent -= 1;
-                if (indent === 0) {
-                    return content.slice(start, pos + 1);
-                }
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-// Stupid function extractor for array.
-function extractArrayVariable(content, arrayName) {
-    var splitter = "var " + arrayName;
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = getNextStep(content, start, '=');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        pos = getNextStep(content, pos, '[');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            if (content[pos] === '"' || content[pos] === "'") {
-                var stop = content[pos];
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-            } else if (content[pos] === ']' &&
-                       pos + 1 < content.length &&
-                       content[pos + 1] === ';') {
-                return content.slice(start, pos + 2);
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-// Stupid function extractor for variable.
-function extractVariable(content, varName) {
-    var splitter = "var " + varName;
-    while (true) {
-        var start = content.indexOf(splitter);
-        if (start === -1) {
-            break;
-        }
-        var pos = getNextStep(content, start, '=');
-        if (pos === null) {
-            break;
-        } else if (pos < 0) {
-            content = content.slice(-pos);
-            continue;
-        }
-        while (pos < content.length) {
-            if (content[pos] === '"' || content[pos] === "'") {
-                var stop = content[pos];
-                do {
-                    if (content[pos] === '\\') {
-                        pos += 2;
-                    } else {
-                        pos += 1;
-                    }
-                } while (pos < content.length &&
-                         (content[pos] !== stop || content[pos - 1] === '\\'));
-            } else if (content[pos] === ';' || content[pos] === ',') {
-                return content.slice(start, pos + 1);
-            }
-            pos += 1;
-        }
-        content = content.slice(start + 1);
-    }
-    return null;
-}
-
-function loadContent(content) {
-    var Module = module.constructor;
-    var m = new Module();
-    m._compile(content, "tmp.js");
-    m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 ||
-        content.startsWith("// ignore-order\n");
-    m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 ||
-        content.startsWith("// exact-check\n");
-    m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 ||
-        content.startsWith("// should-fail\n");
-    return m.exports;
-}
-
-function readFile(filePath) {
-    return fs.readFileSync(filePath, 'utf8');
-}
-
-function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
-    var content = '';
-    for (var i = 0; i < thingsToLoad.length; ++i) {
-        var tmp = funcToCall(fileContent, thingsToLoad[i]);
-        if (tmp === null) {
-            console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
-            process.exit(1);
-        }
-        content += tmp;
-        content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';';
-    }
-    return content;
-}
-
-function lookForEntry(entry, data) {
-    for (var i = 0; i < data.length; ++i) {
-        var allGood = true;
-        for (var key in entry) {
-            if (!entry.hasOwnProperty(key)) {
-                continue;
-            }
-            var value = data[i][key];
-            // To make our life easier, if there is a "parent" type, we add it to the path.
-            if (key === 'path' && data[i]['parent'] !== undefined) {
-                if (value.length > 0) {
-                    value += '::' + data[i]['parent']['name'];
-                } else {
-                    value = data[i]['parent']['name'];
-                }
-            }
-            if (value !== entry[key]) {
-                allGood = false;
-                break;
-            }
-        }
-        if (allGood === true) {
-            return i;
-        }
-    }
-    return null;
-}
-
-function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) {
-    if (searchIndex[searchIndex.length - 1].length === 0) {
-        searchIndex.pop();
-    }
-    searchIndex.pop();
-    searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;');
-    finalJS = "";
-
-    var arraysToLoad = ["itemTypes"];
-    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER",
-                           "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA",
-                           "TY_PRIMITIVE", "TY_KEYWORD",
-                           "levenshtein_row2"];
-    // execQuery first parameter is built in getQuery (which takes in the search input).
-    // execQuery last parameter is built in buildIndex.
-    // buildIndex requires the hashmap from search-index.
-    var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
-                           "getQuery", "buildIndex", "execQuery", "execSearch"];
-
-    finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
-    finalJS += 'var rootPath = "../";\n';
-    finalJS += aliases;
-    finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
-    finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
-    finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);
-
-    var loaded = loadContent(finalJS);
-    var index = loaded.buildIndex(searchIndex.searchIndex);
-
-    return [loaded, index];
-}
-
-function runChecks(testFile, loaded, index) {
-    var errors = 0;
-    var loadedFile = loadContent(
-        readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
-
-    const expected = loadedFile.EXPECTED;
-    const query = loadedFile.QUERY;
-    const filter_crate = loadedFile.FILTER_CRATE;
-    const ignore_order = loadedFile.ignore_order;
-    const exact_check = loadedFile.exact_check;
-    const should_fail = loadedFile.should_fail;
-
-    var results = loaded.execSearch(loaded.getQuery(query), index);
-    var error_text = [];
-
-    for (var key in expected) {
-        if (!expected.hasOwnProperty(key)) {
-            continue;
-        }
-        if (!results.hasOwnProperty(key)) {
-            error_text.push('==> Unknown key "' + key + '"');
-            break;
-        }
-        var entry = expected[key];
-        var prev_pos = -1;
-        for (var i = 0; i < entry.length; ++i) {
-            var entry_pos = lookForEntry(entry[i], results[key]);
-            if (entry_pos === null) {
-                error_text.push("==> Result not found in '" + key + "': '" +
-                                JSON.stringify(entry[i]) + "'");
-            } else if (exact_check === true && prev_pos + 1 !== entry_pos) {
-                error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " +
-                                "expected '" + JSON.stringify(entry[i]) + "' but found '" +
-                                JSON.stringify(results[key][i]) + "'");
-            } else if (ignore_order === false && entry_pos < prev_pos) {
-                error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " +
-                                " before '" + JSON.stringify(results[key][entry_pos]) + "'");
-            } else {
-                prev_pos = entry_pos;
-            }
-        }
-    }
-    if (error_text.length === 0 && should_fail === true) {
-        errors += 1;
-        console.error("FAILED");
-        console.error("==> Test was supposed to fail but all items were found...");
-    } else if (error_text.length !== 0 && should_fail === false) {
-        errors += 1;
-        console.error("FAILED");
-        console.error(error_text.join("\n"));
-    } else {
-        console.log("OK");
-    }
-    return errors;
-}
-
-module.exports = {
-    'getNextStep': getNextStep,
-    'extractFunction': extractFunction,
-    'extractArrayVariable': extractArrayVariable,
-    'extractVariable': extractVariable,
-    'loadContent': loadContent,
-    'readFile': readFile,
-    'loadThings': loadThings,
-    'lookForEntry': lookForEntry,
-    'loadMainJsAndIndex': loadMainJsAndIndex,
-    'runChecks': runChecks,
-};
diff --git a/src/tools/rustdoc-js-std/tester.js b/src/tools/rustdoc-js-std/tester.js
deleted file mode 100644
index 6f730b0fdbb..00000000000
--- a/src/tools/rustdoc-js-std/tester.js
+++ /dev/null
@@ -1,74 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-const tools = require('../rustdoc-js-common/lib.js');
-
-
-function findFile(dir, name, extension) {
-    var entries = fs.readdirSync(dir);
-    var matches = [];
-    for (var i = 0; i < entries.length; ++i) {
-        var entry = entries[i];
-        var file_type = fs.statSync(dir + entry);
-        if (file_type.isDirectory()) {
-            continue;
-        }
-        if (entry.startsWith(name) && entry.endsWith(extension)) {
-            var version = entry.slice(name.length, entry.length - extension.length);
-            version = version.split(".").map(function(x) {
-                return parseInt(x);
-            });
-            var total = 0;
-            var mult = 1;
-            for (var j = version.length - 1; j >= 0; --j) {
-                total += version[j] * mult;
-                mult *= 1000;
-            }
-            matches.push([entry, total]);
-        }
-    }
-    if (matches.length === 0) {
-        return null;
-    }
-    // We make a reverse sort to have the "highest" file. Very useful in case you didn't clean up
-    // you std doc folder...
-    matches.sort(function(a, b) {
-        return b[1] - a[1];
-    });
-    return matches[0][0];
-}
-
-function readFileMatching(dir, name, extension) {
-    if (dir.endsWith("/") === false) {
-        dir += "/";
-    }
-    var f = findFile(dir, name, extension);
-    if (f === null) {
-        return "";
-    }
-    return tools.readFile(dir + f);
-}
-
-function main(argv) {
-    if (argv.length !== 4) {
-        console.error("USAGE: node tester.js STD_DOCS TEST_FOLDER");
-        return 1;
-    }
-    var std_docs = argv[2];
-    var test_folder = argv[3];
-
-    var mainJs = readFileMatching(std_docs, "main", ".js");
-    var aliases = readFileMatching(std_docs, "aliases", ".js");
-    var searchIndex = readFileMatching(std_docs, "search-index", ".js").split("\n");
-
-    var [loaded, index] = tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, "std");
-
-    var errors = 0;
-
-    fs.readdirSync(test_folder).forEach(function(file) {
-        process.stdout.write('Checking "' + file + '" ... ');
-        errors += tools.runChecks(path.join(test_folder, file), loaded, index);
-    });
-    return errors > 0 ? 1 : 0;
-}
-
-process.exit(main(process.argv));
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 2e8901d56d0..03f06fc1c6c 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -1,43 +1,408 @@
 const fs = require('fs');
 const path = require('path');
-const tools = require('../rustdoc-js-common/lib.js');
 
-function load_files(out_folder, crate) {
-    var mainJs = tools.readFile(out_folder + "/main.js");
-    var aliases = tools.readFile(out_folder + "/aliases.js");
-    var searchIndex = tools.readFile(out_folder + "/search-index.js").split("\n");
+function getNextStep(content, pos, stop) {
+    while (pos < content.length && content[pos] !== stop &&
+           (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) {
+        pos += 1;
+    }
+    if (pos >= content.length) {
+        return null;
+    }
+    if (content[pos] !== stop) {
+        return pos * -1;
+    }
+    return pos;
+}
+
+// Stupid function extractor based on indent. Doesn't support block
+// comments. If someone puts a ' or an " in a block comment this
+// will blow up. Template strings are not tested and might also be
+// broken.
+function extractFunction(content, functionName) {
+    var indent = 0;
+    var splitter = "function " + functionName + "(";
 
-    return tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, crate);
+    while (true) {
+        var start = content.indexOf(splitter);
+        if (start === -1) {
+            break;
+        }
+        var pos = start;
+        while (pos < content.length && content[pos] !== ')') {
+            pos += 1;
+        }
+        if (pos >= content.length) {
+            break;
+        }
+        pos = getNextStep(content, pos + 1, '{');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        while (pos < content.length) {
+            // Eat single-line comments
+            if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') {
+                do {
+                    pos += 1;
+                } while (pos < content.length && content[pos] !== '\n');
+
+            // Eat quoted strings
+            } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") {
+                var stop = content[pos];
+                var is_escaped = false;
+                do {
+                    if (content[pos] === '\\') {
+                        pos += 2;
+                    } else {
+                        pos += 1;
+                    }
+                } while (pos < content.length &&
+                         (content[pos] !== stop || content[pos - 1] === '\\'));
+
+            // Otherwise, check for indent
+            } else if (content[pos] === '{') {
+                indent += 1;
+            } else if (content[pos] === '}') {
+                indent -= 1;
+                if (indent === 0) {
+                    return content.slice(start, pos + 1);
+                }
+            }
+            pos += 1;
+        }
+        content = content.slice(start + 1);
+    }
+    return null;
 }
 
-function main(argv) {
-    if (argv.length < 4) {
-        console.error("USAGE: node tester.js OUT_FOLDER [TESTS]");
-        return 1;
+// Stupid function extractor for array.
+function extractArrayVariable(content, arrayName) {
+    var splitter = "var " + arrayName;
+    while (true) {
+        var start = content.indexOf(splitter);
+        if (start === -1) {
+            break;
+        }
+        var pos = getNextStep(content, start, '=');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        pos = getNextStep(content, pos, '[');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        while (pos < content.length) {
+            if (content[pos] === '"' || content[pos] === "'") {
+                var stop = content[pos];
+                do {
+                    if (content[pos] === '\\') {
+                        pos += 2;
+                    } else {
+                        pos += 1;
+                    }
+                } while (pos < content.length &&
+                         (content[pos] !== stop || content[pos - 1] === '\\'));
+            } else if (content[pos] === ']' &&
+                       pos + 1 < content.length &&
+                       content[pos + 1] === ';') {
+                return content.slice(start, pos + 2);
+            }
+            pos += 1;
+        }
+        content = content.slice(start + 1);
     }
-    if (argv[2].substr(-1) !== "/") {
-        argv[2] += "/";
+    return null;
+}
+
+// Stupid function extractor for variable.
+function extractVariable(content, varName) {
+    var splitter = "var " + varName;
+    while (true) {
+        var start = content.indexOf(splitter);
+        if (start === -1) {
+            break;
+        }
+        var pos = getNextStep(content, start, '=');
+        if (pos === null) {
+            break;
+        } else if (pos < 0) {
+            content = content.slice(-pos);
+            continue;
+        }
+        while (pos < content.length) {
+            if (content[pos] === '"' || content[pos] === "'") {
+                var stop = content[pos];
+                do {
+                    if (content[pos] === '\\') {
+                        pos += 2;
+                    } else {
+                        pos += 1;
+                    }
+                } while (pos < content.length &&
+                         (content[pos] !== stop || content[pos - 1] === '\\'));
+            } else if (content[pos] === ';' || content[pos] === ',') {
+                return content.slice(start, pos + 1);
+            }
+            pos += 1;
+        }
+        content = content.slice(start + 1);
     }
-    const out_folder = argv[2];
+    return null;
+}
 
+function loadContent(content) {
+    var Module = module.constructor;
+    var m = new Module();
+    m._compile(content, "tmp.js");
+    m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 ||
+        content.startsWith("// ignore-order\n");
+    m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 ||
+        content.startsWith("// exact-check\n");
+    m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 ||
+        content.startsWith("// should-fail\n");
+    return m.exports;
+}
+
+function readFile(filePath) {
+    return fs.readFileSync(filePath, 'utf8');
+}
+
+function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
+    var content = '';
+    for (var i = 0; i < thingsToLoad.length; ++i) {
+        var tmp = funcToCall(fileContent, thingsToLoad[i]);
+        if (tmp === null) {
+            console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
+            process.exit(1);
+        }
+        content += tmp;
+        content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';';
+    }
+    return content;
+}
+
+function lookForEntry(entry, data) {
+    for (var i = 0; i < data.length; ++i) {
+        var allGood = true;
+        for (var key in entry) {
+            if (!entry.hasOwnProperty(key)) {
+                continue;
+            }
+            var value = data[i][key];
+            // To make our life easier, if there is a "parent" type, we add it to the path.
+            if (key === 'path' && data[i]['parent'] !== undefined) {
+                if (value.length > 0) {
+                    value += '::' + data[i]['parent']['name'];
+                } else {
+                    value = data[i]['parent']['name'];
+                }
+            }
+            if (value !== entry[key]) {
+                allGood = false;
+                break;
+            }
+        }
+        if (allGood === true) {
+            return i;
+        }
+    }
+    return null;
+}
+
+function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) {
+    if (searchIndex[searchIndex.length - 1].length === 0) {
+        searchIndex.pop();
+    }
+    searchIndex.pop();
+    searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;');
+    var finalJS = "";
+
+    var arraysToLoad = ["itemTypes"];
+    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER",
+                           "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA",
+                           "TY_PRIMITIVE", "TY_KEYWORD",
+                           "levenshtein_row2"];
+    // execQuery first parameter is built in getQuery (which takes in the search input).
+    // execQuery last parameter is built in buildIndex.
+    // buildIndex requires the hashmap from search-index.
+    var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
+                           "getQuery", "buildIndex", "execQuery", "execSearch"];
+
+    finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
+    finalJS += 'var rootPath = "../";\n';
+    finalJS += aliases;
+    finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
+    finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
+    finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);
+
+    var loaded = loadContent(finalJS);
+    var index = loaded.buildIndex(searchIndex.searchIndex);
+
+    return [loaded, index];
+}
+
+function runChecks(testFile, loaded, index) {
     var errors = 0;
+    var loadedFile = loadContent(
+        readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
+
+    const expected = loadedFile.EXPECTED;
+    const query = loadedFile.QUERY;
+    const filter_crate = loadedFile.FILTER_CRATE;
+    const ignore_order = loadedFile.ignore_order;
+    const exact_check = loadedFile.exact_check;
+    const should_fail = loadedFile.should_fail;
 
-    for (var j = 3; j < argv.length; ++j) {
-        const test_file = argv[j];
-        const test_name = path.basename(test_file, ".js");
+    var results = loaded.execSearch(loaded.getQuery(query), index);
+    var error_text = [];
 
-        process.stdout.write('Checking "' + test_name + '" ... ');
-        if (!fs.existsSync(test_file)) {
-            errors += 1;
-            console.error("FAILED");
-            console.error("==> Missing '" + test_name + ".js' file...");
+    for (var key in expected) {
+        if (!expected.hasOwnProperty(key)) {
             continue;
         }
+        if (!results.hasOwnProperty(key)) {
+            error_text.push('==> Unknown key "' + key + '"');
+            break;
+        }
+        var entry = expected[key];
+        var prev_pos = -1;
+        for (var i = 0; i < entry.length; ++i) {
+            var entry_pos = lookForEntry(entry[i], results[key]);
+            if (entry_pos === null) {
+                error_text.push("==> Result not found in '" + key + "': '" +
+                                JSON.stringify(entry[i]) + "'");
+            } else if (exact_check === true && prev_pos + 1 !== entry_pos) {
+                error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " +
+                                "expected '" + JSON.stringify(entry[i]) + "' but found '" +
+                                JSON.stringify(results[key][i]) + "'");
+            } else if (ignore_order === false && entry_pos < prev_pos) {
+                error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " +
+                                " before '" + JSON.stringify(results[key][entry_pos]) + "'");
+            } else {
+                prev_pos = entry_pos;
+            }
+        }
+    }
+    if (error_text.length === 0 && should_fail === true) {
+        errors += 1;
+        console.error("FAILED");
+        console.error("==> Test was supposed to fail but all items were found...");
+    } else if (error_text.length !== 0 && should_fail === false) {
+        errors += 1;
+        console.error("FAILED");
+        console.error(error_text.join("\n"));
+    } else {
+        console.log("OK");
+    }
+    return errors;
+}
 
-        const test_out_folder = out_folder + test_name;
+function load_files(doc_folder, resource_suffix, crate) {
+    var mainJs = readFile(path.join(doc_folder, "main" + resource_suffix + ".js"));
+    var aliases = readFile(path.join(doc_folder, "aliases" + resource_suffix + ".js"));
+    var searchIndex = readFile(
+        path.join(doc_folder, "search-index" + resource_suffix + ".js")).split("\n");
+
+    return loadMainJsAndIndex(mainJs, aliases, searchIndex, crate);
+}
 
-        var [loaded, index] = load_files(test_out_folder, test_name);
-        errors += tools.runChecks(test_file, loaded, index);
+function showHelp() {
+    console.log("rustdoc-js options:");
+    console.log("  --doc-folder [PATH]        : location of the generated doc folder");
+    console.log("  --help                     : show this message then quit");
+    console.log("  --crate-name [STRING]      : crate name to be used");
+    console.log("  --test-file [PATH]         : location of the JS test file");
+    console.log("  --test-folder [PATH]       : location of the JS tests folder");
+    console.log("  --resource-suffix [STRING] : suffix to refer to the correct files");
+}
+
+function parseOptions(args) {
+    var opts = {
+        "crate_name": "",
+        "resource_suffix": "",
+        "doc_folder": "",
+        "test_folder": "",
+        "test_file": "",
+    };
+    var correspondances = {
+        "--resource-suffix": "resource_suffix",
+        "--doc-folder": "doc_folder",
+        "--test-folder": "test_folder",
+        "--test-file": "test_file",
+        "--crate-name": "crate_name",
+    };
+
+    for (var i = 0; i < args.length; ++i) {
+        if (args[i] === "--resource-suffix"
+            || args[i] === "--doc-folder"
+            || args[i] === "--test-folder"
+            || args[i] === "--test-file"
+            || args[i] === "--crate-name") {
+            i += 1;
+            if (i >= args.length) {
+                console.error("Missing argument after `" + args[i - 1] + "` option.");
+                return null;
+            }
+            opts[correspondances[args[i - 1]]] = args[i];
+        } else if (args[i] === "--help") {
+            showHelp();
+            process.exit(0);
+        } else {
+            console.error("Unknown option `" + args[i] + "`.");
+            console.error("Use `--help` to see the list of options");
+            return null;
+        }
+    }
+    if (opts["doc_folder"].length < 1) {
+        console.error("Missing `--doc-folder` option.");
+    } else if (opts["crate_name"].length < 1) {
+        console.error("Missing `--crate-name` option.");
+    } else if (opts["test_folder"].length < 1 && opts["test_file"].length < 1) {
+        console.error("At least one of `--test-folder` or `--test-file` option is required.");
+    } else {
+        return opts;
+    }
+    return null;
+}
+
+function checkFile(test_file, opts, loaded, index) {
+    const test_name = path.basename(test_file, ".js");
+
+    process.stdout.write('Checking "' + test_name + '" ... ');
+    return runChecks(test_file, loaded, index);
+}
+
+function main(argv) {
+    var opts = parseOptions(argv.slice(2));
+    if (opts === null) {
+        return 1;
+    }
+
+    var [loaded, index] = load_files(
+        opts["doc_folder"],
+        opts["resource_suffix"],
+        opts["crate_name"]);
+    var errors = 0;
+
+    if (opts["test_file"].length !== 0) {
+        errors += checkFile(opts["test_file"], opts, loaded, index);
+    }
+    if (opts["test_folder"].length !== 0) {
+        fs.readdirSync(opts["test_folder"]).forEach(function(file) {
+            if (!file.endsWith(".js")) {
+                return;
+            }
+            errors += checkFile(path.join(opts["test_folder"], file), opts, loaded, index);
+        });
     }
     return errors > 0 ? 1 : 0;
 }
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
-Subproject c1267303bc06408b4ce406175e8f9cddbbe11b9
+Subproject a5cb5d26833cfda6fa2ed35735448953f728bd5