about summary refs log tree commit diff
diff options
context:
space:
mode:
authorpawanbisht62 <36775517+pawanbisht62@users.noreply.github.com>2020-08-06 17:00:51 +0530
committerGitHub <noreply@github.com>2020-08-06 17:00:51 +0530
commitbac939edcf2137f625cfd7b56dfa4aa7b814868f (patch)
treebbeab2a9f6869b0be809a8e7029a62a77c8e22da
parentfdfbd89946ca34d12eec658d111ce9a85cd23df0 (diff)
parent3cfc7fe78eccc754b16981704a098d7bd520e2fd (diff)
downloadrust-bac939edcf2137f625cfd7b56dfa4aa7b814868f.tar.gz
rust-bac939edcf2137f625cfd7b56dfa4aa7b814868f.zip
Merge branch 'master' into feature/incorporate-tracing
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--Cargo.lock361
-rw-r--r--config.toml.example4
-rw-r--r--library/alloc/benches/btree/map.rs302
-rw-r--r--library/alloc/benches/btree/set.rs52
-rw-r--r--library/alloc/src/alloc.rs163
-rw-r--r--library/alloc/src/alloc/tests.rs9
-rw-r--r--library/alloc/src/boxed.rs11
-rw-r--r--library/alloc/src/collections/btree/map.rs126
-rw-r--r--library/alloc/src/collections/btree/navigate.rs4
-rw-r--r--library/alloc/src/collections/btree/node.rs201
-rw-r--r--library/alloc/src/collections/vec_deque/tests.rs17
-rw-r--r--library/alloc/src/lib.rs3
-rw-r--r--library/alloc/src/raw_vec.rs72
-rw-r--r--library/alloc/src/raw_vec/tests.rs4
-rw-r--r--library/alloc/src/rc.rs10
-rw-r--r--library/alloc/src/sync.rs12
-rw-r--r--library/alloc/tests/boxed.rs2
-rw-r--r--library/alloc/tests/heap.rs17
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/slice.rs4
-rw-r--r--library/core/src/alloc/mod.rs374
-rw-r--r--library/core/src/cell.rs2
-rw-r--r--library/core/src/intrinsics.rs36
-rw-r--r--library/core/src/num/mod.rs23
-rw-r--r--library/core/src/result.rs28
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/num/flt2dec/random.rs2
-rw-r--r--library/core/tests/num/flt2dec/strategy/grisu.rs1
-rw-r--r--library/core/tests/result.rs127
-rw-r--r--library/core/tests/slice.rs6
-rw-r--r--library/proc_macro/src/lib.rs8
-rw-r--r--library/std/src/alloc.rs190
-rw-r--r--library/std/src/keyword_docs.rs2
-rw-r--r--library/std/src/lib.rs3
-rw-r--r--library/std/src/sync/once.rs2
-rw-r--r--library/std/src/sys/unix/fd.rs40
-rw-r--r--library/std/src/sys/wasi/fs.rs1
m---------library/stdarch0
-rw-r--r--src/bootstrap/bin/rustc.rs4
-rw-r--r--src/bootstrap/builder.rs7
-rw-r--r--src/bootstrap/dist.rs74
-rw-r--r--src/bootstrap/test.rs30
-rw-r--r--src/ci/github-actions/ci.yml11
-rwxr-xr-xsrc/ci/scripts/symlink-build-dir.sh2
-rw-r--r--src/ci/shared.sh5
m---------src/doc/book0
m---------src/doc/embedded-book0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/librustc_ast/attr/mod.rs17
-rw-r--r--src/librustc_ast/token.rs117
-rw-r--r--src/librustc_ast/tokenstream.rs125
-rw-r--r--src/librustc_ast_lowering/Cargo.toml2
-rw-r--r--src/librustc_ast_lowering/item.rs2
-rw-r--r--src/librustc_ast_lowering/lib.rs2
-rw-r--r--src/librustc_ast_lowering/pat.rs2
-rw-r--r--src/librustc_ast_lowering/path.rs2
-rw-r--r--src/librustc_ast_passes/Cargo.toml2
-rw-r--r--src/librustc_ast_passes/feature_gate.rs6
-rw-r--r--src/librustc_ast_pretty/Cargo.toml2
-rw-r--r--src/librustc_ast_pretty/pp.rs2
-rw-r--r--src/librustc_ast_pretty/pprust.rs4
-rw-r--r--src/librustc_attr/builtin.rs10
-rw-r--r--src/librustc_builtin_macros/lib.rs1
-rw-r--r--src/librustc_builtin_macros/proc_macro_harness.rs2
-rw-r--r--src/librustc_builtin_macros/test.rs2
-rw-r--r--src/librustc_codegen_llvm/builder.rs61
-rw-r--r--src/librustc_codegen_llvm/coverageinfo/mapgen.rs24
-rw-r--r--src/librustc_codegen_llvm/coverageinfo/mod.rs40
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs191
-rw-r--r--src/librustc_codegen_ssa/coverageinfo/map.rs184
-rw-r--r--src/librustc_codegen_ssa/coverageinfo/mod.rs1
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs167
-rw-r--r--src/librustc_codegen_ssa/traits/builder.rs1
-rw-r--r--src/librustc_codegen_ssa/traits/coverageinfo.rs15
-rw-r--r--src/librustc_error_codes/error_codes/E0733.md14
-rw-r--r--src/librustc_error_codes/error_codes/E0744.md8
-rw-r--r--src/librustc_error_codes/error_codes/E0745.md11
-rw-r--r--src/librustc_errors/emitter.rs4
-rw-r--r--src/librustc_expand/expand.rs4
-rw-r--r--src/librustc_expand/mbe.rs4
-rw-r--r--src/librustc_expand/mbe/macro_parser.rs206
-rw-r--r--src/librustc_expand/mbe/macro_rules.rs175
-rw-r--r--src/librustc_expand/mbe/quoted.rs22
-rw-r--r--src/librustc_incremental/assert_module_sources.rs2
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs10
-rw-r--r--src/librustc_index/bit_set.rs24
-rw-r--r--src/librustc_infer/infer/canonical/canonicalizer.rs4
-rw-r--r--src/librustc_infer/infer/combine.rs4
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs2
-rw-r--r--src/librustc_interface/interface.rs11
-rw-r--r--src/librustc_interface/passes.rs8
-rw-r--r--src/librustc_interface/util.rs24
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_lint/context.rs2
-rw-r--r--src/librustc_lint/unused.rs27
-rw-r--r--src/librustc_metadata/creader.rs30
-rw-r--r--src/librustc_metadata/dependency_format.rs6
-rw-r--r--src/librustc_metadata/native_libs.rs8
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs31
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs21
-rw-r--r--src/librustc_metadata/rmeta/mod.rs8
-rw-r--r--src/librustc_middle/Cargo.toml1
-rw-r--r--src/librustc_middle/lib.rs2
-rw-r--r--src/librustc_middle/middle/cstore.rs8
-rw-r--r--src/librustc_middle/middle/stability.rs20
-rw-r--r--src/librustc_middle/mir/coverage/mod.rs21
-rw-r--r--src/librustc_middle/mir/interpret/error.rs8
-rw-r--r--src/librustc_middle/mir/interpret/value.rs9
-rw-r--r--src/librustc_middle/mir/mod.rs29
-rw-r--r--src/librustc_middle/query/mod.rs8
-rw-r--r--src/librustc_middle/traits/mod.rs35
-rw-r--r--src/librustc_middle/traits/select.rs99
-rw-r--r--src/librustc_middle/traits/structural_impls.rs223
-rw-r--r--src/librustc_middle/ty/context.rs59
-rw-r--r--src/librustc_middle/ty/query/job.rs10
-rw-r--r--src/librustc_middle/ty/query/mod.rs12
-rw-r--r--src/librustc_middle/ty/structural_impls.rs2
-rw-r--r--src/librustc_middle/ty/subst.rs37
-rw-r--r--src/librustc_middle/ty/trait_def.rs50
-rw-r--r--src/librustc_middle/ty/util.rs2
-rw-r--r--src/librustc_mir/dataflow/framework/engine.rs4
-rw-r--r--src/librustc_mir/dataflow/mod.rs2
-rw-r--r--src/librustc_mir/interpret/memory.rs2
-rw-r--r--src/librustc_mir/interpret/util.rs16
-rw-r--r--src/librustc_mir/monomorphize/polymorphize.rs23
-rw-r--r--src/librustc_mir/transform/instrument_coverage.rs94
-rw-r--r--src/librustc_mir/transform/promote_consts.rs2
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs10
-rw-r--r--src/librustc_mir/transform/simplify.rs4
-rw-r--r--src/librustc_mir_build/thir/pattern/mod.rs2
-rw-r--r--src/librustc_parse/Cargo.toml1
-rw-r--r--src/librustc_parse/lib.rs188
-rw-r--r--src/librustc_parse/parser/diagnostics.rs1
-rw-r--r--src/librustc_parse/parser/expr.rs2
-rw-r--r--src/librustc_parse/parser/mod.rs15
-rw-r--r--src/librustc_parse/parser/nonterminal.rs163
-rw-r--r--src/librustc_parse/parser/path.rs2
-rw-r--r--src/librustc_parse/parser/stmt.rs4
-rw-r--r--src/librustc_parse/parser/ty.rs4
-rw-r--r--src/librustc_passes/check_attr.rs2
-rw-r--r--src/librustc_query_system/cache.rs62
-rw-r--r--src/librustc_query_system/lib.rs1
-rw-r--r--src/librustc_resolve/late.rs37
-rw-r--r--src/librustc_resolve/late/diagnostics.rs195
-rw-r--r--src/librustc_resolve/macros.rs2
-rw-r--r--src/librustc_save_analysis/lib.rs4
-rw-r--r--src/librustc_session/config.rs2
-rw-r--r--src/librustc_session/parse.rs5
-rw-r--r--src/librustc_span/hygiene.rs4
-rw-r--r--src/librustc_target/spec/wasm32_base.rs7
-rw-r--r--src/librustc_trait_selection/traits/on_unimplemented.rs10
-rw-r--r--src/librustc_trait_selection/traits/select/mod.rs88
-rw-r--r--src/librustc_typeck/check/coercion.rs2
-rw-r--r--src/librustc_typeck/check/intrinsic.rs39
-rw-r--r--src/librustc_typeck/collect.rs8
-rw-r--r--src/librustc_typeck/lib.rs40
-rw-r--r--src/librustdoc/clean/mod.rs8
-rw-r--r--src/librustdoc/clean/types.rs24
-rw-r--r--src/librustdoc/html/render/cache.rs2
-rw-r--r--src/librustdoc/lib.rs113
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs2
-rw-r--r--src/librustdoc/test.rs12
-rw-r--r--src/librustdoc/visit_ast.rs12
-rw-r--r--src/test/assembly/asm/aarch64-modifiers.rs1
-rw-r--r--src/test/assembly/asm/aarch64-types.rs1
-rw-r--r--src/test/assembly/asm/arm-modifiers.rs1
-rw-r--r--src/test/assembly/asm/arm-types.rs1
-rw-r--r--src/test/assembly/asm/hexagon-types.rs1
-rw-r--r--src/test/assembly/asm/nvptx-types.rs1
-rw-r--r--src/test/assembly/asm/riscv-modifiers.rs1
-rw-r--r--src/test/assembly/asm/riscv-types.rs1
-rw-r--r--src/test/codegen/abi-efiapi.rs8
-rw-r--r--src/test/codegen/avr/avr-func-addrspace.rs1
-rw-r--r--src/test/codegen/wasm_casts_trapping.rs48
-rw-r--r--src/test/debuginfo/rc_arc.rs1
-rw-r--r--src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff58
-rw-r--r--src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff90
-rw-r--r--src/test/mir-opt/instrument_coverage.rs18
-rw-r--r--src/test/pretty/block-comment-wchar.pp2
-rw-r--r--src/test/pretty/issue-74745.rs5
-rw-r--r--src/test/ui/allocator/custom.rs15
-rw-r--r--src/test/ui/allocator/xcrate-use.rs15
-rw-r--r--src/test/ui/async-await/issue-68523-start.rs2
-rw-r--r--src/test/ui/async-await/issue-68523-start.stderr4
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-multi-true.rs8
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.rs19
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.stderr18
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.rs32
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.stderr42
-rw-r--r--src/test/ui/consts/const_in_pattern/warn_corner_cases.rs2
-rw-r--r--src/test/ui/consts/issue-73976-polymorphic.rs2
-rw-r--r--src/test/ui/consts/unsizing-cast-non-null.rs10
-rw-r--r--src/test/ui/consts/unsizing-cast-non-null.stderr12
-rw-r--r--src/test/ui/deprecation/atomic_initializers.fixed2
-rw-r--r--src/test/ui/deprecation/atomic_initializers.rs2
-rw-r--r--src/test/ui/deprecation/atomic_initializers.stderr4
-rw-r--r--src/test/ui/deprecation/deprecation-in-future.rs2
-rw-r--r--src/test/ui/deprecation/deprecation-in-future.stderr2
-rw-r--r--src/test/ui/deprecation/deprecation-lint-2.rs2
-rw-r--r--src/test/ui/deprecation/deprecation-lint-2.stderr2
-rw-r--r--src/test/ui/deprecation/deprecation-lint-3.rs2
-rw-r--r--src/test/ui/deprecation/deprecation-lint-3.stderr2
-rw-r--r--src/test/ui/deprecation/deprecation-lint-nested.rs12
-rw-r--r--src/test/ui/deprecation/deprecation-lint-nested.stderr12
-rw-r--r--src/test/ui/deprecation/deprecation-lint.rs250
-rw-r--r--src/test/ui/deprecation/deprecation-lint.stderr316
-rw-r--r--src/test/ui/deprecation/rustc_deprecation-in-future.rs2
-rw-r--r--src/test/ui/deprecation/rustc_deprecation-in-future.stderr2
-rw-r--r--src/test/ui/deprecation/suggestion.stderr4
-rw-r--r--src/test/ui/issues/issue-17337.rs2
-rw-r--r--src/test/ui/issues/issue-17337.stderr2
-rw-r--r--src/test/ui/issues/issue-37131.rs1
-rw-r--r--src/test/ui/issues/issue-49851/compiler-builtins-error.rs1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr13
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr4
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr13
-rw-r--r--src/test/ui/issues/issue-50993.rs1
-rw-r--r--src/test/ui/issues/issue-72574-1.rs2
-rw-r--r--src/test/ui/issues/issue-72574-1.stderr22
-rw-r--r--src/test/ui/issues/issue-72574-2.rs2
-rw-r--r--src/test/ui/issues/issue-72574-2.stderr20
-rw-r--r--src/test/ui/issues/issue-74539.rs12
-rw-r--r--src/test/ui/issues/issue-74539.stderr21
-rw-r--r--src/test/ui/issues/issue-75704.rs7
-rw-r--r--src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs26
-rw-r--r--src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr50
-rw-r--r--src/test/ui/lint/lint-nonstandard-style-unicode-1.rs2
-rw-r--r--src/test/ui/lint/lint-nonstandard-style-unicode-2.rs2
-rw-r--r--src/test/ui/lint/lint-output-format-2.rs4
-rw-r--r--src/test/ui/lint/lint-output-format-2.stderr4
-rw-r--r--src/test/ui/lint/lint-stability-deprecated.rs224
-rw-r--r--src/test/ui/lint/lint-stability-deprecated.stderr320
-rw-r--r--src/test/ui/lint/lint-stability-fields-deprecated.rs124
-rw-r--r--src/test/ui/lint/lint-stability-fields-deprecated.stderr124
-rw-r--r--src/test/ui/lint/lint-stability2.rs2
-rw-r--r--src/test/ui/lint/lint-stability2.stderr2
-rw-r--r--src/test/ui/lint/lint-stability3.rs2
-rw-r--r--src/test/ui/lint/lint-stability3.stderr2
-rw-r--r--src/test/ui/lint/unused-braces-while-let-with-mutable-value.rs12
-rw-r--r--src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr8
-rw-r--r--src/test/ui/macros/macro-deprecation.rs4
-rw-r--r--src/test/ui/macros/macro-deprecation.stderr4
-rw-r--r--src/test/ui/macros/macro-stability.rs4
-rw-r--r--src/test/ui/macros/macro-stability.stderr4
-rw-r--r--src/test/ui/pattern/issue-74539.rs15
-rw-r--r--src/test/ui/pattern/issue-74539.stderr32
-rw-r--r--src/test/ui/pattern/issue-74702.rs7
-rw-r--r--src/test/ui/pattern/issue-74702.stderr34
-rw-r--r--src/test/ui/pattern/issue-74954.rs7
-rw-r--r--src/test/ui/proc-macro/attributes-on-definitions.rs2
-rw-r--r--src/test/ui/proc-macro/attributes-on-definitions.stderr2
-rw-r--r--src/test/ui/proc-macro/auxiliary/raw-ident.rs35
-rw-r--r--src/test/ui/proc-macro/crt-static.rs2
-rw-r--r--src/test/ui/proc-macro/raw-ident.rs16
-rw-r--r--src/test/ui/proc-macro/raw-ident.stderr10
-rw-r--r--src/test/ui/realloc-16687.rs21
-rw-r--r--src/test/ui/regions/regions-mock-codegen.rs8
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-main.rs4
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-main.stderr12
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-start.rs7
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-start.stderr12
-rw-r--r--src/test/ui/rfc-2091-track-caller/std-panic-locations.rs9
-rw-r--r--src/test/ui/suggestions/issue-61226.fixed6
-rw-r--r--src/test/ui/suggestions/issue-61226.rs3
-rw-r--r--src/test/ui/suggestions/issue-61226.stderr6
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-method.fixed5
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-method.rs3
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-method.stderr10
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed6
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path-2.rs3
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr10
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-variant.fixed5
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-variant.rs1
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-variant.stderr2
-rw-r--r--src/test/ui/type/ascription/issue-47666.fixed4
-rw-r--r--src/test/ui/type/ascription/issue-47666.rs5
-rw-r--r--src/test/ui/type/ascription/issue-47666.stderr34
-rw-r--r--src/test/ui/type/ascription/issue-54516.fixed7
-rw-r--r--src/test/ui/type/ascription/issue-54516.rs3
-rw-r--r--src/test/ui/type/ascription/issue-54516.stderr22
-rw-r--r--src/test/ui/type/ascription/issue-60933.fixed5
-rw-r--r--src/test/ui/type/ascription/issue-60933.rs5
-rw-r--r--src/test/ui/type/ascription/issue-60933.stderr24
-rw-r--r--src/test/ui/type/type-ascription-with-fn-call.fixed9
-rw-r--r--src/test/ui/type/type-ascription-with-fn-call.rs1
-rw-r--r--src/test/ui/type/type-ascription-with-fn-call.stderr4
-rw-r--r--src/test/ui/warn-path-statement.rs13
-rw-r--r--src/test/ui/warn-path-statement.stderr16
-rw-r--r--src/tools/build-manifest/src/main.rs1
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrow.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs2
-rw-r--r--src/tools/clippy/tests/ui/formatting.rs2
-rw-r--r--src/tools/compiletest/src/header.rs12
-rw-r--r--src/tools/compiletest/src/runtest.rs25
-rw-r--r--src/tools/tidy/src/deps.rs1
313 files changed, 4630 insertions, 3878 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 565c916db5b..a19cca9071f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -575,8 +575,14 @@ jobs:
       CACHE_DOMAIN: ci-caches-gha.rust-lang.org
     if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'"
     strategy:
+      fail-fast: false
       matrix:
         include:
+          - name: aarch64-gnu
+            os:
+              - self-hosted
+              - ARM64
+              - linux
           - name: dist-x86_64-apple
             env:
               SCRIPT: "./x.py dist"
diff --git a/Cargo.lock b/Cargo.lock
index 7e90b7e6fba..d4f4ec7f6f0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -37,19 +37,20 @@ version = "0.0.0"
 dependencies = [
  "compiler_builtins",
  "core",
- "rand 0.7.3",
- "rand_xorshift 0.2.0",
+ "rand",
+ "rand_xorshift",
 ]
 
 [[package]]
 name = "ammonia"
-version = "3.0.0"
+version = "3.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e266e1f4be5ffa05309f650e2586fe1d3ae6034eb24025a7ae1dfecc330823a"
+checksum = "89eac85170f4b3fb3dc5e442c1cfb036cb8eecf9dbbd431a161ffad15d90ea3b"
 dependencies = [
  "html5ever",
  "lazy_static",
  "maplit",
+ "markup5ever_rcdom",
  "matches",
  "tendril",
  "url 2.1.0",
@@ -343,7 +344,7 @@ dependencies = [
  "termcolor",
  "toml",
  "unicode-width",
- "unicode-xid 0.2.0",
+ "unicode-xid",
  "url 2.1.0",
  "walkdir",
  "winapi 0.3.8",
@@ -444,9 +445,9 @@ version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d463e01905d607e181de72e8608721d3269f29176c9a14ce037011316ae7131d"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
  "synstructure",
 ]
 
@@ -547,12 +548,12 @@ dependencies = [
  "lazy_static",
  "pulldown-cmark",
  "quine-mc_cluskey",
- "quote 1.0.2",
+ "quote",
  "regex-syntax",
  "semver 0.9.0",
  "serde",
  "smallvec 1.4.0",
- "syn 1.0.11",
+ "syn",
  "toml",
  "unicode-normalization",
  "url 2.1.0",
@@ -667,7 +668,7 @@ checksum = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 name = "core"
 version = "0.0.0"
 dependencies = [
- "rand 0.7.3",
+ "rand",
 ]
 
 [[package]]
@@ -788,8 +789,8 @@ version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1"
 dependencies = [
- "quote 1.0.2",
- "syn 1.0.11",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -835,9 +836,9 @@ version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -846,9 +847,9 @@ version = "0.99.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -923,9 +924,9 @@ checksum = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
 
 [[package]]
 name = "elasticlunr-rs"
-version = "2.3.4"
+version = "2.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a99a310cd1f9770e7bf8e48810c7bcbb0e078c8fb23a8c7bcf0da4c2bf61a455"
+checksum = "35622eb004c8f0c5e7e2032815f3314a93df0db30a1ce5c94e62c1ecc81e22b9"
 dependencies = [
  "lazy_static",
  "regex",
@@ -1003,9 +1004,9 @@ version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
  "synstructure",
 ]
 
@@ -1298,16 +1299,16 @@ dependencies = [
 
 [[package]]
 name = "html5ever"
-version = "0.24.1"
+version = "0.25.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "025483b0a1e4577bb28578318c886ee5f817dda6eb62473269349044406644cb"
+checksum = "aafcf38a1a36118242d29b92e1b08ef84e67e4a5ed06e0a80be20e6a32bfed6b"
 dependencies = [
  "log",
  "mac",
  "markup5ever",
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -1515,9 +1516,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058"
 dependencies = [
  "proc-macro-crate",
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -1586,9 +1587,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.73"
+version = "0.2.74"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
+checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -1735,9 +1736,9 @@ checksum = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
 
 [[package]]
 name = "markup5ever"
-version = "0.9.0"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65381d9d47506b8592b97c4efd936afcf673b09b059f2bef39c7211ee78b9d03"
+checksum = "aae38d669396ca9b707bfc3db254bc382ddb94f57cc5c235f34623a669a01dab"
 dependencies = [
  "log",
  "phf",
@@ -1751,6 +1752,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "markup5ever_rcdom"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f015da43bcd8d4f144559a3423f4591d69b8ce0652c905374da7205df336ae2b"
+dependencies = [
+ "html5ever",
+ "markup5ever",
+ "tendril",
+ "xml5ever",
+]
+
+[[package]]
 name = "matchers"
 version = "0.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1937,7 +1950,7 @@ dependencies = [
  "hex 0.4.0",
  "libc",
  "log",
- "rand 0.7.3",
+ "rand",
  "rustc-workspace-hack",
  "rustc_version",
  "shell-escape",
@@ -2131,7 +2144,7 @@ dependencies = [
  "log",
  "mio-named-pipes",
  "miow 0.3.3",
- "rand 0.7.3",
+ "rand",
  "tokio",
  "tokio-named-pipes",
  "tokio-uds",
@@ -2233,9 +2246,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
 dependencies = [
  "pest",
  "pest_meta",
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -2261,18 +2274,18 @@ dependencies = [
 
 [[package]]
 name = "phf"
-version = "0.7.24"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
+checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
 dependencies = [
  "phf_shared",
 ]
 
 [[package]]
 name = "phf_codegen"
-version = "0.7.24"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
+checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
 dependencies = [
  "phf_generator",
  "phf_shared",
@@ -2280,19 +2293,19 @@ dependencies = [
 
 [[package]]
 name = "phf_generator"
-version = "0.7.24"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
+checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
 dependencies = [
  "phf_shared",
- "rand 0.6.1",
+ "rand",
 ]
 
 [[package]]
 name = "phf_shared"
-version = "0.7.24"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
+checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
 dependencies = [
  "siphasher",
 ]
@@ -2363,18 +2376,9 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "0.4.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
-dependencies = [
- "unicode-xid 0.1.0",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -2383,7 +2387,7 @@ version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
 dependencies = [
- "unicode-xid 0.2.0",
+ "unicode-xid",
 ]
 
 [[package]]
@@ -2443,20 +2447,11 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
 
 [[package]]
 name = "quote"
-version = "0.6.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
-dependencies = [
- "proc-macro2 0.4.30",
-]
-
-[[package]]
-name = "quote"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
 dependencies = [
- "proc-macro2 1.0.3",
+ "proc-macro2",
 ]
 
 [[package]]
@@ -2484,44 +2479,16 @@ dependencies = [
 
 [[package]]
 name = "rand"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a"
-dependencies = [
- "cloudabi",
- "fuchsia-zircon",
- "libc",
- "rand_chacha 0.1.0",
- "rand_core 0.3.0",
- "rand_hc 0.1.0",
- "rand_isaac",
- "rand_pcg",
- "rand_xorshift 0.1.0",
- "rustc_version",
- "winapi 0.3.8",
-]
-
-[[package]]
-name = "rand"
 version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
 dependencies = [
  "getrandom",
  "libc",
- "rand_chacha 0.2.2",
+ "rand_chacha",
  "rand_core 0.5.1",
- "rand_hc 0.2.0",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a"
-dependencies = [
- "rand_core 0.3.0",
- "rustc_version",
+ "rand_hc",
+ "rand_pcg",
 ]
 
 [[package]]
@@ -2557,15 +2524,6 @@ dependencies = [
 
 [[package]]
 name = "rand_hc"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
-dependencies = [
- "rand_core 0.3.0",
-]
-
-[[package]]
-name = "rand_hc"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
@@ -2574,15 +2532,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rand_isaac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
-dependencies = [
- "rand_core 0.3.0",
-]
-
-[[package]]
 name = "rand_os"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2598,21 +2547,11 @@ dependencies = [
 
 [[package]]
 name = "rand_pcg"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05"
-dependencies = [
- "rand_core 0.3.0",
- "rustc_version",
-]
-
-[[package]]
-name = "rand_xorshift"
-version = "0.1.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3"
+checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
 dependencies = [
- "rand_core 0.3.0",
+ "rand_core 0.5.1",
 ]
 
 [[package]]
@@ -2752,7 +2691,7 @@ dependencies = [
  "num_cpus",
  "ordslice",
  "racer",
- "rand 0.7.3",
+ "rand",
  "rayon",
  "regex",
  "rls-analysis",
@@ -2824,7 +2763,7 @@ dependencies = [
  "env_logger 0.7.1",
  "futures",
  "log",
- "rand 0.7.3",
+ "rand",
  "rls-data",
  "rls-ipc",
  "serde",
@@ -3051,7 +2990,7 @@ version = "669.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "456af5f09c006cf6c22c1a433ee0232c4bb74bdc6c647a010166a47c94ed2a63"
 dependencies = [
- "unicode-xid 0.2.0",
+ "unicode-xid",
 ]
 
 [[package]]
@@ -3060,9 +2999,9 @@ version = "669.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "64f6acd192f313047759a346b892998b626466b93fe04f415da5f38906bb3b4c"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
  "synstructure",
 ]
 
@@ -3224,13 +3163,13 @@ name = "rustc-workspace-hack"
 version = "1.0.0"
 dependencies = [
  "crossbeam-utils 0.7.2",
- "proc-macro2 1.0.3",
- "quote 1.0.2",
+ "proc-macro2",
+ "quote",
  "serde",
  "serde_json",
  "smallvec 0.6.10",
  "smallvec 1.4.0",
- "syn 1.0.11",
+ "syn",
  "url 2.1.0",
  "winapi 0.3.8",
 ]
@@ -3555,7 +3494,7 @@ dependencies = [
 name = "rustc_incremental"
 version = "0.0.0"
 dependencies = [
- "rand 0.7.3",
+ "rand",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_fs_util",
@@ -3644,7 +3583,7 @@ dependencies = [
 name = "rustc_lexer"
 version = "0.1.0"
 dependencies = [
- "unicode-xid 0.2.0",
+ "unicode-xid",
 ]
 
 [[package]]
@@ -3681,9 +3620,9 @@ dependencies = [
 name = "rustc_macros"
 version = "0.1.0"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
  "synstructure",
 ]
 
@@ -3738,7 +3677,6 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
- "scoped-tls",
  "smallvec 1.4.0",
  "tracing",
 ]
@@ -3808,6 +3746,7 @@ dependencies = [
  "rustc_lexer",
  "rustc_session",
  "rustc_span",
+ "smallvec 1.4.0",
  "tracing",
  "unicode-normalization",
 ]
@@ -4134,10 +4073,10 @@ dependencies = [
 name = "rustfmt-config_proc_macro"
 version = "0.2.0"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
+ "proc-macro2",
+ "quote",
  "serde",
- "syn 1.0.11",
+ "syn",
 ]
 
 [[package]]
@@ -4264,9 +4203,9 @@ version = "1.0.106"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -4295,9 +4234,9 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -4345,9 +4284,9 @@ dependencies = [
 
 [[package]]
 name = "siphasher"
-version = "0.2.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
+checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
 
 [[package]]
 name = "sized-chunks"
@@ -4427,7 +4366,7 @@ dependencies = [
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
- "rand 0.7.3",
+ "rand",
  "rustc-demangle",
  "unwind",
  "wasi",
@@ -4435,39 +4374,30 @@ dependencies = [
 
 [[package]]
 name = "string_cache"
-version = "0.7.3"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
+checksum = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a"
 dependencies = [
  "lazy_static",
  "new_debug_unreachable",
  "phf_shared",
  "precomputed-hash",
  "serde",
- "string_cache_codegen",
- "string_cache_shared",
 ]
 
 [[package]]
 name = "string_cache_codegen"
-version = "0.4.2"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
+checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97"
 dependencies = [
  "phf_generator",
  "phf_shared",
- "proc-macro2 0.4.30",
- "quote 0.6.12",
- "string_cache_shared",
+ "proc-macro2",
+ "quote",
 ]
 
 [[package]]
-name = "string_cache_shared"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
-
-[[package]]
 name = "strip-ansi-escapes"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4500,38 +4430,27 @@ checksum = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37"
 dependencies = [
  "heck",
  "proc-macro-error",
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
 name = "strum"
-version = "0.11.0"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6c3a2071519ab6a48f465808c4c1ffdd00dfc8e93111d02b4fc5abab177676e"
+checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
 
 [[package]]
 name = "strum_macros"
-version = "0.11.0"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8baacebd7b7c9b864d83a6ba7a246232983e277b86fa5cdec77f565715a4b136"
+checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
 dependencies = [
  "heck",
- "proc-macro2 0.4.30",
- "quote 0.6.12",
- "syn 0.15.35",
-]
-
-[[package]]
-name = "syn"
-version = "0.15.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3"
-dependencies = [
- "proc-macro2 0.4.30",
- "quote 0.6.12",
- "unicode-xid 0.1.0",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -4540,9 +4459,9 @@ version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "unicode-xid 0.2.0",
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
 ]
 
 [[package]]
@@ -4551,10 +4470,10 @@ version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
- "unicode-xid 0.2.0",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
 ]
 
 [[package]]
@@ -4577,7 +4496,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
 dependencies = [
  "cfg-if",
  "libc",
- "rand 0.7.3",
+ "rand",
  "redox_syscall",
  "remove_dir_all",
  "winapi 0.3.8",
@@ -4682,9 +4601,9 @@ version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24069c0ba08aab54289d6a25f5036d94afc61e1538bbc42ae5501df141c9027d"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -4983,9 +4902,9 @@ version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b"
 dependencies = [
- "proc-macro2 1.0.3",
- "quote 1.0.2",
- "syn 1.0.11",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
@@ -5104,12 +5023,6 @@ dependencies = [
 
 [[package]]
 name = "unicode-xid"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
-
-[[package]]
-name = "unicode-xid"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
@@ -5296,6 +5209,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "xml5ever"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b1b52e6e8614d4a58b8e70cf51ec0cc21b256ad8206708bcff8139b5bbd6a59"
+dependencies = [
+ "log",
+ "mac",
+ "markup5ever",
+ "time",
+]
+
+[[package]]
 name = "xz2"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/config.toml.example b/config.toml.example
index 8ecd8d88d48..a9835ad12ad 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -433,7 +433,7 @@
 #
 # LLD will not be used if we're cross linking or running tests.
 #
-# Explicitly setting the linker for a target will override this option.
+# Explicitly setting the linker for a target will override this option when targeting MSVC.
 #use-lld = false
 
 # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
@@ -503,7 +503,7 @@
 # Linker to be used to link Rust code. Note that the
 # default value is platform specific, and if not specified it may also depend on
 # what platform is crossing to what platform.
-# Setting this will override the `use-lld` option for Rust code.
+# Setting this will override the `use-lld` option for Rust code when targeting MSVC.
 #linker = "cc"
 
 # Path to the `llvm-config` binary of the installation of a custom LLVM to link
diff --git a/library/alloc/benches/btree/map.rs b/library/alloc/benches/btree/map.rs
index 38d19c59ad1..7c2e5694a62 100644
--- a/library/alloc/benches/btree/map.rs
+++ b/library/alloc/benches/btree/map.rs
@@ -282,3 +282,305 @@ pub fn iter_10k(b: &mut Bencher) {
 pub fn iter_1m(b: &mut Bencher) {
     bench_iter(b, 1_000, 1_000_000);
 }
+
+const FAT: usize = 256;
+
+// The returned map has small keys and values.
+// Benchmarks on it have a counterpart in set.rs with the same keys and no values at all.
+fn slim_map(n: usize) -> BTreeMap<usize, usize> {
+    (0..n).map(|i| (i, i)).collect::<BTreeMap<_, _>>()
+}
+
+// The returned map has small keys and large values.
+fn fat_val_map(n: usize) -> BTreeMap<usize, [usize; FAT]> {
+    (0..n).map(|i| (i, [i; FAT])).collect::<BTreeMap<_, _>>()
+}
+
+// The returned map has large keys and values.
+fn fat_map(n: usize) -> BTreeMap<[usize; FAT], [usize; FAT]> {
+    (0..n).map(|i| ([i; FAT], [i; FAT])).collect::<BTreeMap<_, _>>()
+}
+
+#[bench]
+pub fn clone_slim_100(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| src.clone())
+}
+
+#[bench]
+pub fn clone_slim_100_and_clear(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| src.clone().clear())
+}
+
+#[bench]
+pub fn clone_slim_100_and_drain_all(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| src.clone().drain_filter(|_, _| true).count())
+}
+
+#[bench]
+pub fn clone_slim_100_and_drain_half(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 100 / 2);
+        assert_eq!(map.len(), 100 / 2);
+    })
+}
+
+#[bench]
+pub fn clone_slim_100_and_into_iter(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| src.clone().into_iter().count())
+}
+
+#[bench]
+pub fn clone_slim_100_and_pop_all(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        while map.pop_first().is_some() {}
+        map
+    });
+}
+
+#[bench]
+pub fn clone_slim_100_and_remove_all(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        while let Some(elt) = map.iter().map(|(&i, _)| i).next() {
+            let v = map.remove(&elt);
+            debug_assert!(v.is_some());
+        }
+        map
+    });
+}
+
+#[bench]
+pub fn clone_slim_100_and_remove_half(b: &mut Bencher) {
+    let src = slim_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        for i in (0..100).step_by(2) {
+            let v = map.remove(&i);
+            debug_assert!(v.is_some());
+        }
+        assert_eq!(map.len(), 100 / 2);
+        map
+    })
+}
+
+#[bench]
+pub fn clone_slim_10k(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| src.clone())
+}
+
+#[bench]
+pub fn clone_slim_10k_and_clear(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| src.clone().clear())
+}
+
+#[bench]
+pub fn clone_slim_10k_and_drain_all(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| src.clone().drain_filter(|_, _| true).count())
+}
+
+#[bench]
+pub fn clone_slim_10k_and_drain_half(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| {
+        let mut map = src.clone();
+        assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 10_000 / 2);
+        assert_eq!(map.len(), 10_000 / 2);
+    })
+}
+
+#[bench]
+pub fn clone_slim_10k_and_into_iter(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| src.clone().into_iter().count())
+}
+
+#[bench]
+pub fn clone_slim_10k_and_pop_all(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| {
+        let mut map = src.clone();
+        while map.pop_first().is_some() {}
+        map
+    });
+}
+
+#[bench]
+pub fn clone_slim_10k_and_remove_all(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| {
+        let mut map = src.clone();
+        while let Some(elt) = map.iter().map(|(&i, _)| i).next() {
+            let v = map.remove(&elt);
+            debug_assert!(v.is_some());
+        }
+        map
+    });
+}
+
+#[bench]
+pub fn clone_slim_10k_and_remove_half(b: &mut Bencher) {
+    let src = slim_map(10_000);
+    b.iter(|| {
+        let mut map = src.clone();
+        for i in (0..10_000).step_by(2) {
+            let v = map.remove(&i);
+            debug_assert!(v.is_some());
+        }
+        assert_eq!(map.len(), 10_000 / 2);
+        map
+    })
+}
+
+#[bench]
+pub fn clone_fat_val_100(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| src.clone())
+}
+
+#[bench]
+pub fn clone_fat_val_100_and_clear(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| src.clone().clear())
+}
+
+#[bench]
+pub fn clone_fat_val_100_and_drain_all(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| src.clone().drain_filter(|_, _| true).count())
+}
+
+#[bench]
+pub fn clone_fat_val_100_and_drain_half(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        assert_eq!(map.drain_filter(|i, _| i % 2 == 0).count(), 100 / 2);
+        assert_eq!(map.len(), 100 / 2);
+    })
+}
+
+#[bench]
+pub fn clone_fat_val_100_and_into_iter(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| src.clone().into_iter().count())
+}
+
+#[bench]
+pub fn clone_fat_val_100_and_pop_all(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        while map.pop_first().is_some() {}
+        map
+    });
+}
+
+#[bench]
+pub fn clone_fat_val_100_and_remove_all(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        while let Some(elt) = map.iter().map(|(&i, _)| i).next() {
+            let v = map.remove(&elt);
+            debug_assert!(v.is_some());
+        }
+        map
+    });
+}
+
+#[bench]
+pub fn clone_fat_val_100_and_remove_half(b: &mut Bencher) {
+    let src = fat_val_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        for i in (0..100).step_by(2) {
+            let v = map.remove(&i);
+            debug_assert!(v.is_some());
+        }
+        assert_eq!(map.len(), 100 / 2);
+        map
+    })
+}
+
+#[bench]
+pub fn clone_fat_100(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| src.clone())
+}
+
+#[bench]
+pub fn clone_fat_100_and_clear(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| src.clone().clear())
+}
+
+#[bench]
+pub fn clone_fat_100_and_drain_all(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| src.clone().drain_filter(|_, _| true).count())
+}
+
+#[bench]
+pub fn clone_fat_100_and_drain_half(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        assert_eq!(map.drain_filter(|i, _| i[0] % 2 == 0).count(), 100 / 2);
+        assert_eq!(map.len(), 100 / 2);
+    })
+}
+
+#[bench]
+pub fn clone_fat_100_and_into_iter(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| src.clone().into_iter().count())
+}
+
+#[bench]
+pub fn clone_fat_100_and_pop_all(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        while map.pop_first().is_some() {}
+        map
+    });
+}
+
+#[bench]
+pub fn clone_fat_100_and_remove_all(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        while let Some(elt) = map.iter().map(|(&i, _)| i).next() {
+            let v = map.remove(&elt);
+            debug_assert!(v.is_some());
+        }
+        map
+    });
+}
+
+#[bench]
+pub fn clone_fat_100_and_remove_half(b: &mut Bencher) {
+    let src = fat_map(100);
+    b.iter(|| {
+        let mut map = src.clone();
+        for i in (0..100).step_by(2) {
+            let v = map.remove(&[i; FAT]);
+            debug_assert!(v.is_some());
+        }
+        assert_eq!(map.len(), 100 / 2);
+        map
+    })
+}
diff --git a/library/alloc/benches/btree/set.rs b/library/alloc/benches/btree/set.rs
index 2518506b9b5..07bf5093727 100644
--- a/library/alloc/benches/btree/set.rs
+++ b/library/alloc/benches/btree/set.rs
@@ -50,27 +50,31 @@ macro_rules! set_bench {
     };
 }
 
+fn slim_set(n: usize) -> BTreeSet<usize> {
+    (0..n).collect::<BTreeSet<_>>()
+}
+
 #[bench]
 pub fn clone_100(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| src.clone())
 }
 
 #[bench]
 pub fn clone_100_and_clear(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| src.clone().clear())
 }
 
 #[bench]
 pub fn clone_100_and_drain_all(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| src.clone().drain_filter(|_| true).count())
 }
 
 #[bench]
 pub fn clone_100_and_drain_half(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| {
         let mut set = src.clone();
         assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 100 / 2);
@@ -80,13 +84,13 @@ pub fn clone_100_and_drain_half(b: &mut Bencher) {
 
 #[bench]
 pub fn clone_100_and_into_iter(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| src.clone().into_iter().count())
 }
 
 #[bench]
 pub fn clone_100_and_pop_all(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| {
         let mut set = src.clone();
         while set.pop_first().is_some() {}
@@ -96,11 +100,12 @@ pub fn clone_100_and_pop_all(b: &mut Bencher) {
 
 #[bench]
 pub fn clone_100_and_remove_all(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| {
         let mut set = src.clone();
         while let Some(elt) = set.iter().copied().next() {
-            set.remove(&elt);
+            let ok = set.remove(&elt);
+            debug_assert!(ok);
         }
         set
     });
@@ -108,11 +113,12 @@ pub fn clone_100_and_remove_all(b: &mut Bencher) {
 
 #[bench]
 pub fn clone_100_and_remove_half(b: &mut Bencher) {
-    let src = pos(100);
+    let src = slim_set(100);
     b.iter(|| {
         let mut set = src.clone();
-        for i in (2..=100 as i32).step_by(2) {
-            set.remove(&i);
+        for i in (0..100).step_by(2) {
+            let ok = set.remove(&i);
+            debug_assert!(ok);
         }
         assert_eq!(set.len(), 100 / 2);
         set
@@ -121,25 +127,25 @@ pub fn clone_100_and_remove_half(b: &mut Bencher) {
 
 #[bench]
 pub fn clone_10k(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| src.clone())
 }
 
 #[bench]
 pub fn clone_10k_and_clear(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| src.clone().clear())
 }
 
 #[bench]
 pub fn clone_10k_and_drain_all(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| src.clone().drain_filter(|_| true).count())
 }
 
 #[bench]
 pub fn clone_10k_and_drain_half(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| {
         let mut set = src.clone();
         assert_eq!(set.drain_filter(|i| i % 2 == 0).count(), 10_000 / 2);
@@ -149,13 +155,13 @@ pub fn clone_10k_and_drain_half(b: &mut Bencher) {
 
 #[bench]
 pub fn clone_10k_and_into_iter(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| src.clone().into_iter().count())
 }
 
 #[bench]
 pub fn clone_10k_and_pop_all(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| {
         let mut set = src.clone();
         while set.pop_first().is_some() {}
@@ -165,11 +171,12 @@ pub fn clone_10k_and_pop_all(b: &mut Bencher) {
 
 #[bench]
 pub fn clone_10k_and_remove_all(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| {
         let mut set = src.clone();
         while let Some(elt) = set.iter().copied().next() {
-            set.remove(&elt);
+            let ok = set.remove(&elt);
+            debug_assert!(ok);
         }
         set
     });
@@ -177,11 +184,12 @@ pub fn clone_10k_and_remove_all(b: &mut Bencher) {
 
 #[bench]
 pub fn clone_10k_and_remove_half(b: &mut Bencher) {
-    let src = pos(10_000);
+    let src = slim_set(10_000);
     b.iter(|| {
         let mut set = src.clone();
-        for i in (2..=10_000 as i32).step_by(2) {
-            set.remove(&i);
+        for i in (0..10_000).step_by(2) {
+            let ok = set.remove(&i);
+            debug_assert!(ok);
         }
         assert_eq!(set.len(), 10_000 / 2);
         set
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 98c7ac3f2ef..518ac11b5a0 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -164,25 +164,34 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
 #[unstable(feature = "allocator_api", issue = "32838")]
 unsafe impl AllocRef for Global {
     #[inline]
-    fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
-        unsafe {
-            let size = layout.size();
-            if size == 0 {
-                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
-            } else {
-                let raw_ptr = match init {
-                    AllocInit::Uninitialized => alloc(layout),
-                    AllocInit::Zeroed => alloc_zeroed(layout),
-                };
-                let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
-                Ok(MemoryBlock { ptr, size })
-            }
-        }
+    fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+        let size = layout.size();
+        let ptr = if size == 0 {
+            layout.dangling()
+        } else {
+            // SAFETY: `layout` is non-zero in size,
+            unsafe { NonNull::new(alloc(layout)).ok_or(AllocErr)? }
+        };
+        Ok(NonNull::slice_from_raw_parts(ptr, size))
+    }
+
+    #[inline]
+    fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+        let size = layout.size();
+        let ptr = if size == 0 {
+            layout.dangling()
+        } else {
+            // SAFETY: `layout` is non-zero in size,
+            unsafe { NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr)? }
+        };
+        Ok(NonNull::slice_from_raw_parts(ptr, size))
     }
 
     #[inline]
     unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
         if layout.size() != 0 {
+            // SAFETY: `layout` is non-zero in size,
+            // other conditions must be upheld by the caller
             unsafe { dealloc(ptr.as_ptr(), layout) }
         }
     }
@@ -193,38 +202,59 @@ unsafe impl AllocRef for Global {
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-        init: AllocInit,
-    ) -> Result<MemoryBlock, AllocErr> {
-        let size = layout.size();
+    ) -> Result<NonNull<[u8]>, AllocErr> {
         debug_assert!(
-            new_size >= size,
-            "`new_size` must be greater than or equal to `memory.size()`"
+            new_size >= layout.size(),
+            "`new_size` must be greater than or equal to `layout.size()`"
         );
 
-        if size == new_size {
-            return Ok(MemoryBlock { ptr, size });
+        // SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+        // Other conditions must be upheld by the caller
+        unsafe {
+            match layout.size() {
+                old_size if old_size == new_size => {
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
+                }
+                0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
+                old_size => {
+                    // `realloc` probably checks for `new_size > size` or something similar.
+                    intrinsics::assume(new_size > old_size);
+                    let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
+                    let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
+                }
+            }
         }
+    }
 
-        match placement {
-            ReallocPlacement::InPlace => Err(AllocErr),
-            ReallocPlacement::MayMove if layout.size() == 0 => {
-                let new_layout =
-                    unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
-                self.alloc(new_layout, init)
-            }
-            ReallocPlacement::MayMove => {
-                // `realloc` probably checks for `new_size > size` or something similar.
-                let ptr = unsafe {
-                    intrinsics::assume(new_size > size);
-                    realloc(ptr.as_ptr(), layout, new_size)
-                };
-                let memory =
-                    MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
-                unsafe {
-                    init.init_offset(memory, size);
+    #[inline]
+    unsafe fn grow_zeroed(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        debug_assert!(
+            new_size >= layout.size(),
+            "`new_size` must be greater than or equal to `layout.size()`"
+        );
+
+        // SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+        // Other conditions must be upheld by the caller
+        unsafe {
+            match layout.size() {
+                old_size if old_size == new_size => {
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
+                }
+                0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())),
+                old_size => {
+                    // `realloc` probably checks for `new_size > size` or something similar.
+                    intrinsics::assume(new_size > old_size);
+                    let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
+                    raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+                    let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
                 }
-                Ok(memory)
             }
         }
     }
@@ -235,35 +265,34 @@ unsafe impl AllocRef for Global {
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-    ) -> Result<MemoryBlock, AllocErr> {
-        let size = layout.size();
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        let old_size = layout.size();
         debug_assert!(
-            new_size <= size,
-            "`new_size` must be smaller than or equal to `memory.size()`"
+            new_size <= old_size,
+            "`new_size` must be smaller than or equal to `layout.size()`"
         );
 
-        if size == new_size {
-            return Ok(MemoryBlock { ptr, size });
-        }
-
-        match placement {
-            ReallocPlacement::InPlace => Err(AllocErr),
-            ReallocPlacement::MayMove if new_size == 0 => {
-                unsafe {
-                    self.dealloc(ptr, layout);
-                }
-                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
-            }
-            ReallocPlacement::MayMove => {
-                // `realloc` probably checks for `new_size < size` or something similar.
-                let ptr = unsafe {
-                    intrinsics::assume(new_size < size);
-                    realloc(ptr.as_ptr(), layout, new_size)
-                };
-                Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })
+        let ptr = if new_size == old_size {
+            ptr
+        } else if new_size == 0 {
+            // SAFETY: `layout` is non-zero in size as `old_size` != `new_size`
+            // Other conditions must be upheld by the caller
+            unsafe {
+                self.dealloc(ptr, layout);
             }
-        }
+            layout.dangling()
+        } else {
+            // SAFETY: new_size is not zero,
+            // Other conditions must be upheld by the caller
+            let raw_ptr = unsafe {
+                // `realloc` probably checks for `new_size < old_size` or something similar.
+                intrinsics::assume(new_size < old_size);
+                realloc(ptr.as_ptr(), layout, new_size)
+            };
+            NonNull::new(raw_ptr).ok_or(AllocErr)?
+        };
+
+        Ok(NonNull::slice_from_raw_parts(ptr, new_size))
     }
 }
 
@@ -274,8 +303,8 @@ unsafe impl AllocRef for Global {
 #[inline]
 unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
     let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
-    match Global.alloc(layout, AllocInit::Uninitialized) {
-        Ok(memory) => memory.ptr.as_ptr(),
+    match Global.alloc(layout) {
+        Ok(ptr) => ptr.as_non_null_ptr().as_ptr(),
         Err(_) => handle_alloc_error(layout),
     }
 }
diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/src/alloc/tests.rs
index 1c003983df9..f7463d0daac 100644
--- a/library/alloc/src/alloc/tests.rs
+++ b/library/alloc/src/alloc/tests.rs
@@ -8,17 +8,16 @@ use test::Bencher;
 fn allocate_zeroed() {
     unsafe {
         let layout = Layout::from_size_align(1024, 1).unwrap();
-        let memory = Global
-            .alloc(layout.clone(), AllocInit::Zeroed)
-            .unwrap_or_else(|_| handle_alloc_error(layout));
+        let ptr =
+            Global.alloc_zeroed(layout.clone()).unwrap_or_else(|_| handle_alloc_error(layout));
 
-        let mut i = memory.ptr.cast::<u8>().as_ptr();
+        let mut i = ptr.as_non_null_ptr().as_ptr();
         let end = i.add(layout.size());
         while i < end {
             assert_eq!(*i, 0);
             i = i.offset(1);
         }
-        Global.dealloc(memory.ptr, layout);
+        Global.dealloc(ptr.as_non_null_ptr(), layout);
     }
 }
 
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 65e0c984fe8..5e304beff78 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -146,7 +146,7 @@ use core::pin::Pin;
 use core::ptr::{self, Unique};
 use core::task::{Context, Poll};
 
-use crate::alloc::{self, AllocInit, AllocRef, Global};
+use crate::alloc::{self, AllocRef, Global};
 use crate::borrow::Cow;
 use crate::raw_vec::RawVec;
 use crate::str::from_boxed_utf8_unchecked;
@@ -197,11 +197,7 @@ impl<T> Box<T> {
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
         let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
-        let ptr = Global
-            .alloc(layout, AllocInit::Uninitialized)
-            .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
-            .ptr
-            .cast();
+        let ptr = Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast();
         unsafe { Box::from_raw(ptr.as_ptr()) }
     }
 
@@ -227,9 +223,8 @@ impl<T> Box<T> {
     pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
         let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
         let ptr = Global
-            .alloc(layout, AllocInit::Zeroed)
+            .alloc_zeroed(layout)
             .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
-            .ptr
             .cast();
         unsafe { Box::from_raw(ptr.as_ptr()) }
     }
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 24d1f61fa68..1db629c3bdf 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -174,7 +174,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
 
                     {
                         let out_root = BTreeMap::ensure_is_owned(&mut out_tree.root);
-                        let mut out_node = out_root.push_level();
+                        let mut out_node = out_root.push_internal_level();
                         let mut in_edge = internal.first_edge();
                         while let Ok(kv) = in_edge.right_kv() {
                             let (k, v) = kv.into_kv();
@@ -1080,9 +1080,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
                                 test_node = parent.forget_type();
                             }
                         }
-                        Err(node) => {
+                        Err(_) => {
                             // We are at the top, create a new root node and push there.
-                            open_node = node.into_root_mut().push_level();
+                            open_node = root.push_internal_level();
                             break;
                         }
                     }
@@ -1092,7 +1092,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
                 let tree_height = open_node.height() - 1;
                 let mut right_tree = node::Root::new_leaf();
                 for _ in 0..tree_height {
-                    right_tree.push_level();
+                    right_tree.push_internal_level();
                 }
                 open_node.push(key, value, right_tree);
 
@@ -1171,7 +1171,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
         let mut right = Self::new();
         let right_root = Self::ensure_is_owned(&mut right.root);
         for _ in 0..left_root.height() {
-            right_root.push_level();
+            right_root.push_internal_level();
         }
 
         {
@@ -1255,7 +1255,11 @@ impl<K: Ord, V> BTreeMap<K, V> {
     }
     pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> {
         let front = self.root.as_mut().map(|r| r.as_mut().first_leaf_edge());
-        DrainFilterInner { length: &mut self.length, cur_leaf_edge: front }
+        DrainFilterInner {
+            length: &mut self.length,
+            cur_leaf_edge: front,
+            emptied_internal_root: false,
+        }
     }
 
     /// Calculates the number of elements if it is incorrect.
@@ -1625,6 +1629,7 @@ where
 pub(super) struct DrainFilterInner<'a, K: 'a, V: 'a> {
     length: &'a mut usize,
     cur_leaf_edge: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
+    emptied_internal_root: bool,
 }
 
 #[unstable(feature = "btree_drain_filter", issue = "70530")]
@@ -1665,6 +1670,17 @@ where
     }
 }
 
+impl<K, V> Drop for DrainFilterInner<'_, K, V> {
+    fn drop(&mut self) {
+        if self.emptied_internal_root {
+            if let Some(handle) = self.cur_leaf_edge.take() {
+                let root = handle.into_node().into_root_mut();
+                root.pop_internal_level();
+            }
+        }
+    }
+}
+
 impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
     /// Allow Debug implementations to predict the next element.
     pub(super) fn peek(&self) -> Option<(&K, &V)> {
@@ -1681,9 +1697,10 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
             let (k, v) = kv.kv_mut();
             if pred(k, v) {
                 *self.length -= 1;
-                let (k, v, leaf_edge_location) = kv.remove_kv_tracking();
-                self.cur_leaf_edge = Some(leaf_edge_location);
-                return Some((k, v));
+                let RemoveResult { old_kv, pos, emptied_internal_root } = kv.remove_kv_tracking();
+                self.cur_leaf_edge = Some(pos);
+                self.emptied_internal_root |= emptied_internal_root;
+                return Some(old_kv);
             }
             self.cur_leaf_edge = Some(kv.next_leaf_edge());
         }
@@ -2448,40 +2465,17 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
     pub fn insert(self, value: V) -> &'a mut V {
         *self.length += 1;
 
-        let out_ptr;
-
-        let mut ins_k;
-        let mut ins_v;
-        let mut ins_edge;
-
-        let mut cur_parent = match self.handle.insert(self.key, value) {
-            (Fit(handle), _) => return handle.into_kv_mut().1,
-            (Split(left, k, v, right), ptr) => {
-                ins_k = k;
-                ins_v = v;
-                ins_edge = right;
-                out_ptr = ptr;
-                left.ascend().map_err(|n| n.into_root_mut())
+        let out_ptr = match self.handle.insert_recursing(self.key, value) {
+            (Fit(_), val_ptr) => val_ptr,
+            (Split(ins), val_ptr) => {
+                let root = ins.left.into_root_mut();
+                root.push_internal_level().push(ins.k, ins.v, ins.right);
+                val_ptr
             }
         };
-
-        loop {
-            match cur_parent {
-                Ok(parent) => match parent.insert(ins_k, ins_v, ins_edge) {
-                    Fit(_) => return unsafe { &mut *out_ptr },
-                    Split(left, k, v, right) => {
-                        ins_k = k;
-                        ins_v = v;
-                        ins_edge = right;
-                        cur_parent = left.ascend().map_err(|n| n.into_root_mut());
-                    }
-                },
-                Err(root) => {
-                    root.push_level().push(ins_k, ins_v, ins_edge);
-                    return unsafe { &mut *out_ptr };
-                }
-            }
-        }
+        // Now that we have finished growing the tree using borrowed references,
+        // dereference the pointer to a part of it, that we picked up along the way.
+        unsafe { &mut *out_ptr }
     }
 }
 
@@ -2647,20 +2641,35 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
         self.remove_kv().1
     }
 
+    // Body of `remove_entry`, separate to keep the above implementations short.
     fn remove_kv(self) -> (K, V) {
         *self.length -= 1;
 
-        let (old_key, old_val, _) = self.handle.remove_kv_tracking();
-        (old_key, old_val)
+        let RemoveResult { old_kv, pos, emptied_internal_root } = self.handle.remove_kv_tracking();
+        let root = pos.into_node().into_root_mut();
+        if emptied_internal_root {
+            root.pop_internal_level();
+        }
+        old_kv
     }
 }
 
+struct RemoveResult<'a, K, V> {
+    // Key and value removed.
+    old_kv: (K, V),
+    // Unique location at the leaf level that the removed KV lopgically collapsed into.
+    pos: Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>,
+    // Whether the remove left behind and empty internal root node, that should be removed
+    // using `pop_internal_level`.
+    emptied_internal_root: bool,
+}
+
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
-    /// Removes a key/value-pair from the map, and returns that pair, as well as
-    /// the leaf edge corresponding to that former pair.
-    fn remove_kv_tracking(
-        self,
-    ) -> (K, V, Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
+    /// Removes a key/value-pair from the tree, and returns that pair, as well as
+    /// the leaf edge corresponding to that former pair. It's possible this leaves
+    /// an empty internal root node, which the caller should subsequently pop from
+    /// the map holding the tree. The caller should also decrement the map's length.
+    fn remove_kv_tracking(self) -> RemoveResult<'a, K, V> {
         let (mut pos, old_key, old_val, was_internal) = match self.force() {
             Leaf(leaf) => {
                 let (hole, old_key, old_val) = leaf.remove();
@@ -2689,6 +2698,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
         };
 
         // Handle underflow
+        let mut emptied_internal_root = false;
         let mut cur_node = unsafe { ptr::read(&pos).into_node().forget_type() };
         let mut at_leaf = true;
         while cur_node.len() < node::MIN_LEN {
@@ -2709,8 +2719,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
 
                     let parent = edge.into_node();
                     if parent.len() == 0 {
-                        // We must be at the root
-                        parent.into_root_mut().pop_level();
+                        // This empty parent must be the root, and should be popped off the tree.
+                        emptied_internal_root = true;
                         break;
                     } else {
                         cur_node = parent.forget_type();
@@ -2737,7 +2747,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
             pos = unsafe { unwrap_unchecked(pos.next_kv().ok()).next_leaf_edge() };
         }
 
-        (old_key, old_val, pos)
+        RemoveResult { old_kv: (old_key, old_val), pos, emptied_internal_root }
     }
 }
 
@@ -2745,7 +2755,7 @@ impl<K, V> node::Root<K, V> {
     /// Removes empty levels on the top, but keep an empty leaf if the entire tree is empty.
     fn fix_top(&mut self) {
         while self.height() > 0 && self.as_ref().len() == 0 {
-            self.pop_level();
+            self.pop_internal_level();
         }
     }
 
@@ -2817,8 +2827,16 @@ fn handle_underfull_node<K, V>(
     let (is_left, mut handle) = match parent.left_kv() {
         Ok(left) => (true, left),
         Err(parent) => {
-            let right = unsafe { unwrap_unchecked(parent.right_kv().ok()) };
-            (false, right)
+            match parent.right_kv() {
+                Ok(right) => (false, right),
+                Err(_) => {
+                    // The underfull node has an empty parent, so it is the only child
+                    // of an empty root. It is destined to become the new root, thus
+                    // allowed to be underfull. The empty parent should be removed later
+                    // by `pop_internal_level`.
+                    return AtRoot;
+                }
+            }
         }
     };
 
diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs
index 44f0e25bbd7..0dcb5930964 100644
--- a/library/alloc/src/collections/btree/navigate.rs
+++ b/library/alloc/src/collections/btree/navigate.rs
@@ -19,7 +19,7 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::E
                 Ok(internal_kv) => return Ok(internal_kv),
                 Err(last_edge) => match last_edge.into_node().ascend() {
                     Ok(parent_edge) => parent_edge.forget_node_type(),
-                    Err(root) => return Err(root.forget_type()),
+                    Err(root) => return Err(root),
                 },
             }
         }
@@ -40,7 +40,7 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::E
                 Ok(internal_kv) => return Ok(internal_kv),
                 Err(last_edge) => match last_edge.into_node().ascend() {
                     Ok(parent_edge) => parent_edge.forget_node_type(),
-                    Err(root) => return Err(root.forget_type()),
+                    Err(root) => return Err(root),
                 },
             }
         }
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index f7bd64608d6..6a4c495ea14 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -191,8 +191,9 @@ impl<K, V> Root<K, V> {
     }
 
     /// Adds a new internal node with a single edge, pointing to the previous root, and make that
-    /// new node the root. This increases the height by 1 and is the opposite of `pop_level`.
-    pub fn push_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
+    /// new node the root. This increases the height by 1 and is the opposite of
+    /// `pop_internal_level`.
+    pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
         let mut new_node = Box::new(unsafe { InternalNode::new() });
         new_node.edges[0].write(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) });
 
@@ -213,11 +214,12 @@ impl<K, V> Root<K, V> {
         ret
     }
 
-    /// Removes the root node, using its first child as the new root. This cannot be called when
-    /// the tree consists only of a leaf node. As it is intended only to be called when the root
-    /// has only one edge, no cleanup is done on any of the other children of the root.
-    /// This decreases the height by 1 and is the opposite of `push_level`.
-    pub fn pop_level(&mut self) {
+    /// Removes the internal root node, using its first child as the new root.
+    /// As it is intended only to be called when the root has only one child,
+    /// no cleanup is done on any of the other children of the root.
+    /// This decreases the height by 1 and is the opposite of `push_internal_level`.
+    /// Panics if there is no internal level, i.e. if the root is a leaf.
+    pub fn pop_internal_level(&mut self) {
         assert!(self.height > 0);
 
         let top = self.node.ptr;
@@ -305,12 +307,6 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
         self.height
     }
 
-    /// Removes any static information about whether this node is a `Leaf` or an
-    /// `Internal` node.
-    pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
-        NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData }
-    }
-
     /// Temporarily takes out another, immutable reference to the same node.
     fn reborrow(&self) -> NodeRef<marker::Immut<'_>, K, V, Type> {
         NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData }
@@ -466,12 +462,6 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
     fn into_val_slice(self) -> &'a [V] {
         unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) }
     }
-
-    fn into_slices(self) -> (&'a [K], &'a [V]) {
-        // SAFETY: equivalent to reborrow() except not requiring Type: 'a
-        let k = unsafe { ptr::read(&self) };
-        (k.into_key_slice(), self.into_val_slice())
-    }
 }
 
 impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
@@ -829,13 +819,13 @@ impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, mar
     }
 }
 
-impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
+impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::Edge> {
+    /// Helps implementations of `insert_fit` for a particular `NodeType`,
+    /// by taking care of leaf data.
     /// Inserts a new key/value pair between the key/value pairs to the right and left of
     /// this edge. This method assumes that there is enough space in the node for the new
     /// pair to fit.
-    ///
-    /// The returned pointer points to the inserted value.
-    fn insert_fit(&mut self, key: K, val: V) -> *mut V {
+    fn leafy_insert_fit(&mut self, key: K, val: V) {
         // Necessary for correctness, but in a private module
         debug_assert!(self.node.len() < CAPACITY);
 
@@ -844,16 +834,28 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
             slice_insert(self.node.vals_mut(), self.idx, val);
 
             (*self.node.as_leaf_mut()).len += 1;
-
-            self.node.vals_mut().get_unchecked_mut(self.idx)
         }
     }
+}
 
+impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
+    /// Inserts a new key/value pair between the key/value pairs to the right and left of
+    /// this edge. This method assumes that there is enough space in the node for the new
+    /// pair to fit.
+    ///
+    /// The returned pointer points to the inserted value.
+    fn insert_fit(&mut self, key: K, val: V) -> *mut V {
+        self.leafy_insert_fit(key, val);
+        unsafe { self.node.vals_mut().get_unchecked_mut(self.idx) }
+    }
+}
+
+impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
     /// Inserts a new key/value pair between the key/value pairs to the right and left of
     /// this edge. This method splits the node if there isn't enough room.
     ///
     /// The returned pointer points to the inserted value.
-    pub fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) {
+    fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) {
         if self.node.len() < CAPACITY {
             let ptr = self.insert_fit(key, val);
             let kv = unsafe { Handle::new_kv(self.node, self.idx) };
@@ -872,7 +874,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
                     .insert_fit(key, val)
                 }
             };
-            (InsertResult::Split(left, k, v, right), ptr)
+            (InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }), ptr)
         }
     }
 }
@@ -890,14 +892,6 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
         }
     }
 
-    /// Unsafely asserts to the compiler some static information about whether the underlying
-    /// node of this handle is a `Leaf` or an `Internal`.
-    unsafe fn cast_unchecked<NewType>(
-        &mut self,
-    ) -> Handle<NodeRef<marker::Mut<'_>, K, V, NewType>, marker::Edge> {
-        unsafe { Handle::new_edge(self.node.cast_unchecked(), self.idx) }
-    }
-
     /// Inserts a new key/value pair and an edge that will go to the right of that new pair
     /// between this edge and the key/value pair to the right of this edge. This method assumes
     /// that there is enough space in the node for the new pair to fit.
@@ -907,8 +901,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
         debug_assert!(edge.height == self.node.height - 1);
 
         unsafe {
-            // This cast is a lie, but it allows us to reuse the key/value insertion logic.
-            self.cast_unchecked::<marker::Leaf>().insert_fit(key, val);
+            self.leafy_insert_fit(key, val);
 
             slice_insert(
                 slice::from_raw_parts_mut(
@@ -928,7 +921,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
     /// Inserts a new key/value pair and an edge that will go to the right of that new pair
     /// between this edge and the key/value pair to the right of this edge. This method splits
     /// the node if there isn't enough room.
-    pub fn insert(
+    fn insert(
         mut self,
         key: K,
         val: V,
@@ -956,7 +949,43 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
                     .insert_fit(key, val, edge);
                 }
             }
-            InsertResult::Split(left, k, v, right)
+            InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right })
+        }
+    }
+}
+
+impl<'a, K: 'a, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge> {
+    /// Inserts a new key/value pair between the key/value pairs to the right and left of
+    /// this edge. This method splits the node if there isn't enough room, and tries to
+    /// insert the split off portion into the parent node recursively, until the root is reached.
+    ///
+    /// If the returned result is a `Fit`, its handle's node can be this edge's node or an ancestor.
+    /// If the returned result is a `Split`, the `left` field will be the root node.
+    /// The returned pointer points to the inserted value.
+    pub fn insert_recursing(
+        self,
+        key: K,
+        value: V,
+    ) -> (InsertResult<'a, K, V, marker::LeafOrInternal>, *mut V) {
+        let (mut split, val_ptr) = match self.insert(key, value) {
+            (InsertResult::Fit(handle), ptr) => {
+                return (InsertResult::Fit(handle.forget_node_type()), ptr);
+            }
+            (InsertResult::Split(split), val_ptr) => (split, val_ptr),
+        };
+
+        loop {
+            split = match split.left.ascend() {
+                Ok(parent) => match parent.insert(split.k, split.v, split.right) {
+                    InsertResult::Fit(handle) => {
+                        return (InsertResult::Fit(handle.forget_node_type()), val_ptr);
+                    }
+                    InsertResult::Split(split) => split,
+                },
+                Err(root) => {
+                    return (InsertResult::Split(SplitResult { left: root, ..split }), val_ptr);
+                }
+            };
         }
     }
 }
@@ -980,10 +1009,9 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marke
 
 impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Immut<'a>, K, V, NodeType>, marker::KV> {
     pub fn into_kv(self) -> (&'a K, &'a V) {
-        unsafe {
-            let (keys, vals) = self.node.into_slices();
-            (keys.get_unchecked(self.idx), vals.get_unchecked(self.idx))
-        }
+        let keys = self.node.into_key_slice();
+        let vals = self.node.into_val_slice();
+        unsafe { (keys.get_unchecked(self.idx), vals.get_unchecked(self.idx)) }
     }
 }
 
@@ -1005,18 +1033,11 @@ impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker
     }
 }
 
-impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> {
-    /// Splits the underlying node into three parts:
-    ///
-    /// - The node is truncated to only contain the key/value pairs to the right of
-    ///   this handle.
-    /// - The key and value pointed to by this handle and extracted.
-    /// - All the key/value pairs to the right of this handle are put into a newly
-    ///   allocated node.
-    pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) {
+impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
+    /// Helps implementations of `split` for a particular `NodeType`,
+    /// by taking care of leaf data.
+    fn leafy_split(&mut self, new_node: &mut LeafNode<K, V>) -> (K, V, usize) {
         unsafe {
-            let mut new_node = Box::new(LeafNode::new());
-
             let k = ptr::read(self.node.keys().get_unchecked(self.idx));
             let v = ptr::read(self.node.vals().get_unchecked(self.idx));
 
@@ -1035,6 +1056,24 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
 
             (*self.node.as_leaf_mut()).len = self.idx as u16;
             new_node.len = new_len as u16;
+            (k, v, new_len)
+        }
+    }
+}
+
+impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> {
+    /// Splits the underlying node into three parts:
+    ///
+    /// - The node is truncated to only contain the key/value pairs to the right of
+    ///   this handle.
+    /// - The key and value pointed to by this handle and extracted.
+    /// - All the key/value pairs to the right of this handle are put into a newly
+    ///   allocated node.
+    pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) {
+        unsafe {
+            let mut new_node = Box::new(LeafNode::new());
+
+            let (k, v, _) = self.leafy_split(&mut new_node);
 
             (self.node, k, v, Root { node: BoxedNode::from_leaf(new_node), height: 0 })
         }
@@ -1066,31 +1105,15 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
         unsafe {
             let mut new_node = Box::new(InternalNode::new());
 
-            let k = ptr::read(self.node.keys().get_unchecked(self.idx));
-            let v = ptr::read(self.node.vals().get_unchecked(self.idx));
-
+            let (k, v, new_len) = self.leafy_split(&mut new_node.data);
             let height = self.node.height;
-            let new_len = self.node.len() - self.idx - 1;
 
             ptr::copy_nonoverlapping(
-                self.node.keys().as_ptr().add(self.idx + 1),
-                new_node.data.keys.as_mut_ptr() as *mut K,
-                new_len,
-            );
-            ptr::copy_nonoverlapping(
-                self.node.vals().as_ptr().add(self.idx + 1),
-                new_node.data.vals.as_mut_ptr() as *mut V,
-                new_len,
-            );
-            ptr::copy_nonoverlapping(
                 self.node.as_internal().edges.as_ptr().add(self.idx + 1),
                 new_node.edges.as_mut_ptr(),
                 new_len + 1,
             );
 
-            (*self.node.as_leaf_mut()).len = self.idx as u16;
-            new_node.data.len = new_len as u16;
-
             let mut new_root = Root { node: BoxedNode::from_internal(new_node), height };
 
             for i in 0..(new_len + 1) {
@@ -1362,6 +1385,20 @@ unsafe fn move_edges<K, V>(
     }
 }
 
+impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Leaf> {
+    /// Removes any static information asserting that this node is a `Leaf` node.
+    pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
+        NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData }
+    }
+}
+
+impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
+    /// Removes any static information asserting that this node is an `Internal` node.
+    pub fn forget_type(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
+        NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData }
+    }
+}
+
 impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
     pub fn forget_node_type(
         self,
@@ -1386,6 +1423,14 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::K
     }
 }
 
+impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::KV> {
+    pub fn forget_node_type(
+        self,
+    ) -> Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::KV> {
+        unsafe { Handle::new_kv(self.node.forget_type(), self.idx) }
+    }
+}
+
 impl<BorrowType, K, V, HandleType>
     Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, HandleType>
 {
@@ -1452,9 +1497,21 @@ pub enum ForceResult<Leaf, Internal> {
     Internal(Internal),
 }
 
+/// Result of insertion, when a node needed to expand beyond its capacity.
+/// Does not distinguish between `Leaf` and `Internal` because `Root` doesn't.
+pub struct SplitResult<'a, K, V> {
+    // Altered node in existing tree with elements and edges that belong to the left of `k`.
+    pub left: NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>,
+    // Some key and value split off, to be inserted elsewhere.
+    pub k: K,
+    pub v: V,
+    // Owned, unattached, new node with elements and edges that belong to the right of `k`.
+    pub right: Root<K, V>,
+}
+
 pub enum InsertResult<'a, K, V, Type> {
     Fit(Handle<NodeRef<marker::Mut<'a>, K, V, Type>, marker::KV>),
-    Split(NodeRef<marker::Mut<'a>, K, V, Type>, K, V, Root<K, V>),
+    Split(SplitResult<'a, K, V>),
 }
 
 pub mod marker {
diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs
index e5edfe02a52..d74f91c752c 100644
--- a/library/alloc/src/collections/vec_deque/tests.rs
+++ b/library/alloc/src/collections/vec_deque/tests.rs
@@ -107,7 +107,8 @@ fn test_insert() {
     let cap = tester.capacity();
 
     // len is the length *after* insertion
-    for len in 1..cap {
+    let minlen = if cfg!(miri) { cap - 1 } else { 1 }; // Miri is too slow
+    for len in minlen..cap {
         // 0, 1, 2, .., len - 1
         let expected = (0..).take(len).collect::<VecDeque<_>>();
         for tail_pos in 0..cap {
@@ -221,7 +222,8 @@ fn test_remove() {
     let cap = tester.capacity();
 
     // len is the length *after* removal
-    for len in 0..cap - 1 {
+    let minlen = if cfg!(miri) { cap - 2 } else { 0 }; // Miri is too slow
+    for len in minlen..cap - 1 {
         // 0, 1, 2, .., len - 1
         let expected = (0..).take(len).collect::<VecDeque<_>>();
         for tail_pos in 0..cap {
@@ -251,7 +253,8 @@ fn test_range() {
     let mut tester: VecDeque<usize> = VecDeque::with_capacity(7);
 
     let cap = tester.capacity();
-    for len in 0..=cap {
+    let minlen = if cfg!(miri) { cap - 1 } else { 0 }; // Miri is too slow
+    for len in minlen..=cap {
         for tail in 0..=cap {
             for start in 0..=len {
                 for end in start..=len {
@@ -384,7 +387,8 @@ fn test_split_off() {
     let cap = tester.capacity();
 
     // len is the length *before* splitting
-    for len in 0..cap {
+    let minlen = if cfg!(miri) { cap - 1 } else { 0 }; // Miri is too slow
+    for len in minlen..cap {
         // index to split at
         for at in 0..=len {
             // 0, 1, 2, .., at - 1 (may be empty)
@@ -495,8 +499,9 @@ fn test_vec_from_vecdeque() {
 fn test_clone_from() {
     let m = vec![1; 8];
     let n = vec![2; 12];
-    for pfv in 0..8 {
-        for pfu in 0..8 {
+    let limit = if cfg!(miri) { 4 } else { 8 }; // Miri is too slow
+    for pfv in 0..limit {
+        for pfu in 0..limit {
             for longer in 0..2 {
                 let (vr, ur) = if longer == 0 { (&m, &n) } else { (&n, &m) };
                 let mut v = VecDeque::from(vr.clone());
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 097db30d634..9ac23886d4e 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -104,6 +104,7 @@
 #![feature(negative_impls)]
 #![feature(new_uninit)]
 #![feature(nll)]
+#![feature(nonnull_slice_from_raw_parts)]
 #![feature(optin_builtin_traits)]
 #![feature(or_patterns)]
 #![feature(pattern)]
@@ -113,6 +114,8 @@
 #![feature(rustc_attrs)]
 #![feature(receiver_trait)]
 #![feature(min_specialization)]
+#![feature(slice_ptr_get)]
+#![feature(slice_ptr_len)]
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(str_internals)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index ed81ce71ddf..2abd7231711 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -1,25 +1,27 @@
 #![unstable(feature = "raw_vec_internals", reason = "implementation detail", issue = "none")]
 #![doc(hidden)]
 
-use core::alloc::{LayoutErr, MemoryBlock};
+use core::alloc::LayoutErr;
 use core::cmp;
 use core::mem::{self, ManuallyDrop, MaybeUninit};
 use core::ops::Drop;
 use core::ptr::{NonNull, Unique};
 use core::slice;
 
-use crate::alloc::{
-    handle_alloc_error,
-    AllocInit::{self, *},
-    AllocRef, Global, Layout,
-    ReallocPlacement::{self, *},
-};
+use crate::alloc::{handle_alloc_error, AllocRef, Global, Layout};
 use crate::boxed::Box;
 use crate::collections::TryReserveError::{self, *};
 
 #[cfg(test)]
 mod tests;
 
+enum AllocInit {
+    /// The contents of the new memory are uninitialized.
+    Uninitialized,
+    /// The new memory is guaranteed to be zeroed.
+    Zeroed,
+}
+
 /// A low-level utility for more ergonomically allocating, reallocating, and deallocating
 /// a buffer of memory on the heap without having to worry about all the corner cases
 /// involved. This type is excellent for building your own data structures like Vec and VecDeque.
@@ -156,14 +158,14 @@ impl<T, A: AllocRef> RawVec<T, A> {
     /// allocator for the returned `RawVec`.
     #[inline]
     pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
-        Self::allocate_in(capacity, Uninitialized, alloc)
+        Self::allocate_in(capacity, AllocInit::Uninitialized, alloc)
     }
 
     /// Like `with_capacity_zeroed`, but parameterized over the choice
     /// of allocator for the returned `RawVec`.
     #[inline]
     pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
-        Self::allocate_in(capacity, Zeroed, alloc)
+        Self::allocate_in(capacity, AllocInit::Zeroed, alloc)
     }
 
     fn allocate_in(capacity: usize, init: AllocInit, mut alloc: A) -> Self {
@@ -180,14 +182,18 @@ impl<T, A: AllocRef> RawVec<T, A> {
                 Ok(_) => {}
                 Err(_) => capacity_overflow(),
             }
-            let memory = match alloc.alloc(layout, init) {
-                Ok(memory) => memory,
+            let result = match init {
+                AllocInit::Uninitialized => alloc.alloc(layout),
+                AllocInit::Zeroed => alloc.alloc_zeroed(layout),
+            };
+            let ptr = match result {
+                Ok(ptr) => ptr,
                 Err(_) => handle_alloc_error(layout),
             };
 
             Self {
-                ptr: unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) },
-                cap: Self::capacity_from_bytes(memory.size),
+                ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) },
+                cap: Self::capacity_from_bytes(ptr.len()),
                 alloc,
             }
         }
@@ -358,7 +364,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
     ///
     /// Aborts on OOM.
     pub fn shrink_to_fit(&mut self, amount: usize) {
-        match self.shrink(amount, MayMove) {
+        match self.shrink(amount) {
             Err(CapacityOverflow) => capacity_overflow(),
             Err(AllocError { layout, .. }) => handle_alloc_error(layout),
             Ok(()) => { /* yay */ }
@@ -378,9 +384,9 @@ impl<T, A: AllocRef> RawVec<T, A> {
         excess / mem::size_of::<T>()
     }
 
-    fn set_memory(&mut self, memory: MemoryBlock) {
-        self.ptr = unsafe { Unique::new_unchecked(memory.ptr.cast().as_ptr()) };
-        self.cap = Self::capacity_from_bytes(memory.size);
+    fn set_ptr(&mut self, ptr: NonNull<[u8]>) {
+        self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) };
+        self.cap = Self::capacity_from_bytes(ptr.len());
     }
 
     // This method is usually instantiated many times. So we want it to be as
@@ -426,8 +432,8 @@ impl<T, A: AllocRef> RawVec<T, A> {
         let new_layout = Layout::array::<T>(cap);
 
         // `finish_grow` is non-generic over `T`.
-        let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
-        self.set_memory(memory);
+        let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
+        self.set_ptr(ptr);
         Ok(())
     }
 
@@ -445,30 +451,24 @@ impl<T, A: AllocRef> RawVec<T, A> {
         let new_layout = Layout::array::<T>(cap);
 
         // `finish_grow` is non-generic over `T`.
-        let memory = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
-        self.set_memory(memory);
+        let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
+        self.set_ptr(ptr);
         Ok(())
     }
 
-    fn shrink(
-        &mut self,
-        amount: usize,
-        placement: ReallocPlacement,
-    ) -> Result<(), TryReserveError> {
+    fn shrink(&mut self, amount: usize) -> Result<(), TryReserveError> {
         assert!(amount <= self.capacity(), "Tried to shrink to a larger capacity");
 
         let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) };
         let new_size = amount * mem::size_of::<T>();
 
-        let memory = unsafe {
-            self.alloc.shrink(ptr, layout, new_size, placement).map_err(|_| {
-                TryReserveError::AllocError {
-                    layout: Layout::from_size_align_unchecked(new_size, layout.align()),
-                    non_exhaustive: (),
-                }
+        let ptr = unsafe {
+            self.alloc.shrink(ptr, layout, new_size).map_err(|_| TryReserveError::AllocError {
+                layout: Layout::from_size_align_unchecked(new_size, layout.align()),
+                non_exhaustive: (),
             })?
         };
-        self.set_memory(memory);
+        self.set_ptr(ptr);
         Ok(())
     }
 }
@@ -481,7 +481,7 @@ fn finish_grow<A>(
     new_layout: Result<Layout, LayoutErr>,
     current_memory: Option<(NonNull<u8>, Layout)>,
     alloc: &mut A,
-) -> Result<MemoryBlock, TryReserveError>
+) -> Result<NonNull<[u8]>, TryReserveError>
 where
     A: AllocRef,
 {
@@ -492,9 +492,9 @@ where
 
     let memory = if let Some((ptr, old_layout)) = current_memory {
         debug_assert_eq!(old_layout.align(), new_layout.align());
-        unsafe { alloc.grow(ptr, old_layout, new_layout.size(), MayMove, Uninitialized) }
+        unsafe { alloc.grow(ptr, old_layout, new_layout.size()) }
     } else {
-        alloc.alloc(new_layout, Uninitialized)
+        alloc.alloc(new_layout)
     }
     .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?;
 
diff --git a/library/alloc/src/raw_vec/tests.rs b/library/alloc/src/raw_vec/tests.rs
index 5408faa079c..cadd913aa6b 100644
--- a/library/alloc/src/raw_vec/tests.rs
+++ b/library/alloc/src/raw_vec/tests.rs
@@ -20,12 +20,12 @@ fn allocator_param() {
         fuel: usize,
     }
     unsafe impl AllocRef for BoundedAlloc {
-        fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
+        fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
             let size = layout.size();
             if size > self.fuel {
                 return Err(AllocErr);
             }
-            match Global.alloc(layout, init) {
+            match Global.alloc(layout) {
                 ok @ Ok(_) => {
                     self.fuel -= size;
                     ok
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 116df63f94b..d0a47ccea0a 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -250,7 +250,7 @@ use core::pin::Pin;
 use core::ptr::{self, NonNull};
 use core::slice::from_raw_parts_mut;
 
-use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout};
+use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout};
 use crate::borrow::{Cow, ToOwned};
 use crate::string::String;
 use crate::vec::Vec;
@@ -928,12 +928,10 @@ impl<T: ?Sized> Rc<T> {
         let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align();
 
         // Allocate for the layout.
-        let mem = Global
-            .alloc(layout, AllocInit::Uninitialized)
-            .unwrap_or_else(|_| handle_alloc_error(layout));
+        let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the RcBox
-        let inner = mem_to_rcbox(mem.ptr.as_ptr());
+        let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr());
         unsafe {
             debug_assert_eq!(Layout::for_value(&*inner), layout);
 
@@ -2101,7 +2099,7 @@ impl<T: ?Sized> Unpin for Rc<T> {}
 ///
 /// - This function is safe for any argument if `T` is sized, and
 /// - if `T` is unsized, the pointer must have appropriate pointer metadata
-///   aquired from the real instance that you are getting this offset for.
+///   acquired from the real instance that you are getting this offset for.
 unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
     // Align the unsized value to the end of the `RcBox`.
     // Because it is ?Sized, it will always be the last field in memory.
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 58cab9c5c63..b3763303137 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -23,7 +23,7 @@ use core::slice::from_raw_parts_mut;
 use core::sync::atomic;
 use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
 
-use crate::alloc::{box_free, handle_alloc_error, AllocInit, AllocRef, Global, Layout};
+use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout};
 use crate::borrow::{Cow, ToOwned};
 use crate::boxed::Box;
 use crate::rc::is_dangling;
@@ -883,12 +883,10 @@ impl<T: ?Sized> Arc<T> {
         // reference (see #54908).
         let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();
 
-        let mem = Global
-            .alloc(layout, AllocInit::Uninitialized)
-            .unwrap_or_else(|_| handle_alloc_error(layout));
+        let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
 
         // Initialize the ArcInner
-        let inner = mem_to_arcinner(mem.ptr.as_ptr());
+        let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr());
         debug_assert_eq!(unsafe { Layout::for_value(&*inner) }, layout);
 
         unsafe {
@@ -988,7 +986,7 @@ impl<T> Arc<[T]> {
                     let slice = from_raw_parts_mut(self.elems, self.n_elems);
                     ptr::drop_in_place(slice);
 
-                    Global.dealloc(self.mem.cast(), self.layout);
+                    Global.dealloc(self.mem, self.layout);
                 }
             }
         }
@@ -2255,7 +2253,7 @@ impl<T: ?Sized> Unpin for Arc<T> {}
 ///
 /// - This function is safe for any argument if `T` is sized, and
 /// - if `T` is unsized, the pointer must have appropriate pointer metadata
-///   aquired from the real instance that you are getting this offset for.
+///   acquired from the real instance that you are getting this offset for.
 unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
     // Align the unsized value to the end of the `ArcInner`.
     // Because it is `?Sized`, it will always be the last field in memory.
diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs
index 5377485da8f..851ca17a365 100644
--- a/library/alloc/tests/boxed.rs
+++ b/library/alloc/tests/boxed.rs
@@ -37,7 +37,7 @@ fn box_clone_and_clone_from_equivalence() {
 /// This test might give a false positive in case the box realocates, but the alocator keeps the
 /// original pointer.
 ///
-/// On the other hand it won't give a false negative, if it fails than the memory was definitly not
+/// On the other hand it won't give a false negative, if it fails than the memory was definitely not
 /// reused
 #[test]
 fn box_clone_from_ptr_stability() {
diff --git a/library/alloc/tests/heap.rs b/library/alloc/tests/heap.rs
index 62f062b83d7..cbde2a7e28e 100644
--- a/library/alloc/tests/heap.rs
+++ b/library/alloc/tests/heap.rs
@@ -1,4 +1,4 @@
-use std::alloc::{AllocInit, AllocRef, Global, Layout, System};
+use std::alloc::{AllocRef, Global, Layout, System};
 
 /// Issue #45955 and #62251.
 #[test]
@@ -20,18 +20,12 @@ fn check_overalign_requests<T: AllocRef>(mut allocator: T) {
             unsafe {
                 let pointers: Vec<_> = (0..iterations)
                     .map(|_| {
-                        allocator
-                            .alloc(
-                                Layout::from_size_align(size, align).unwrap(),
-                                AllocInit::Uninitialized,
-                            )
-                            .unwrap()
-                            .ptr
+                        allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
                     })
                     .collect();
                 for &ptr in &pointers {
                     assert_eq!(
-                        (ptr.as_ptr() as usize) % align,
+                        (ptr.as_non_null_ptr().as_ptr() as usize) % align,
                         0,
                         "Got a pointer less aligned than requested"
                     )
@@ -39,7 +33,10 @@ fn check_overalign_requests<T: AllocRef>(mut allocator: T) {
 
                 // Clean up
                 for &ptr in &pointers {
-                    allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
+                    allocator.dealloc(
+                        ptr.as_non_null_ptr(),
+                        Layout::from_size_align(size, align).unwrap(),
+                    )
                 }
             }
         }
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index fa20a466715..c680a3fc25b 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -13,6 +13,7 @@
 #![feature(associated_type_bounds)]
 #![feature(binary_heap_into_iter_sorted)]
 #![feature(binary_heap_drain_sorted)]
+#![feature(slice_ptr_get)]
 #![feature(split_inclusive)]
 #![feature(binary_heap_retain)]
 
diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs
index 75b76bb73ed..147f7f7d0c7 100644
--- a/library/alloc/tests/slice.rs
+++ b/library/alloc/tests/slice.rs
@@ -1721,8 +1721,8 @@ fn panic_safe() {
 
     let mut rng = thread_rng();
 
-    // Miri is too slow
-    let lens = if cfg!(miri) { (1..10).chain(20..21) } else { (1..20).chain(70..MAX_LEN) };
+    // Miri is too slow (but still need to `chain` to make the types match)
+    let lens = if cfg!(miri) { (1..10).chain(0..0) } else { (1..20).chain(70..MAX_LEN) };
     let moduli: &[u32] = if cfg!(miri) { &[5] } else { &[5, 20, 50] };
 
     for len in lens {
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index be4e051b1ca..2833768f213 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -29,92 +29,6 @@ impl fmt::Display for AllocErr {
     }
 }
 
-/// A desired initial state for allocated memory.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-#[unstable(feature = "allocator_api", issue = "32838")]
-pub enum AllocInit {
-    /// The contents of the new memory are uninitialized.
-    Uninitialized,
-    /// The new memory is guaranteed to be zeroed.
-    Zeroed,
-}
-
-impl AllocInit {
-    /// Initialize the specified memory block.
-    ///
-    /// This behaves like calling [`AllocInit::init_offset(memory, 0)`][off].
-    ///
-    /// [off]: AllocInit::init_offset
-    ///
-    /// # Safety
-    ///
-    /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes.
-    ///
-    /// [valid]: ../../core/ptr/index.html#safety
-    #[inline]
-    #[unstable(feature = "allocator_api", issue = "32838")]
-    pub unsafe fn init(self, memory: MemoryBlock) {
-        // SAFETY: the safety contract for `init_offset` must be
-        // upheld by the caller.
-        unsafe { self.init_offset(memory, 0) }
-    }
-
-    /// Initialize the memory block like specified by `init` at the specified `offset`.
-    ///
-    /// This is a no-op for [`AllocInit::Uninitialized`][] and writes zeroes for
-    /// [`AllocInit::Zeroed`][] at `ptr + offset` until `ptr + layout.size()`.
-    ///
-    /// # Safety
-    ///
-    /// * `memory.ptr` must be [valid] for writes of `memory.size` bytes.
-    /// * `offset` must be smaller than or equal to `memory.size`
-    ///
-    /// [valid]: ../../core/ptr/index.html#safety
-    #[inline]
-    #[unstable(feature = "allocator_api", issue = "32838")]
-    pub unsafe fn init_offset(self, memory: MemoryBlock, offset: usize) {
-        debug_assert!(
-            offset <= memory.size,
-            "`offset` must be smaller than or equal to `memory.size`"
-        );
-        match self {
-            AllocInit::Uninitialized => (),
-            AllocInit::Zeroed => {
-                // SAFETY: the caller must guarantee that `offset` is smaller than or equal to `memory.size`,
-                // so the memory from `memory.ptr + offset` of length `memory.size - offset`
-                // is guaranteed to be contaned in `memory` and thus valid for writes.
-                unsafe { memory.ptr.as_ptr().add(offset).write_bytes(0, memory.size - offset) }
-            }
-        }
-    }
-}
-
-/// Represents a block of allocated memory returned by an allocator.
-#[derive(Debug, Copy, Clone)]
-#[unstable(feature = "allocator_api", issue = "32838")]
-pub struct MemoryBlock {
-    pub ptr: NonNull<u8>,
-    pub size: usize,
-}
-
-/// A placement constraint when growing or shrinking an existing allocation.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-#[unstable(feature = "allocator_api", issue = "32838")]
-pub enum ReallocPlacement {
-    /// The allocator is allowed to move the allocation to a different memory address.
-    // FIXME(wg-allocators#46): Add a section to the module documentation "What is a legal
-    //                          allocator" and link it at "valid location".
-    ///
-    /// If the allocation _does_ move, it's the responsibility of the allocator
-    /// to also move the data from the previous location to the new location.
-    MayMove,
-    /// The address of the new memory must not change.
-    ///
-    /// If the allocation would have to be moved to a new location to fit, the
-    /// reallocation request will fail.
-    InPlace,
-}
-
 /// An implementation of `AllocRef` can allocate, grow, shrink, and deallocate arbitrary blocks of
 /// data described via [`Layout`][].
 ///
@@ -175,12 +89,12 @@ pub enum ReallocPlacement {
 pub unsafe trait AllocRef {
     /// Attempts to allocate a block of memory.
     ///
-    /// On success, returns a [`MemoryBlock`][] meeting the size and alignment guarantees of `layout`.
+    /// On success, returns a [`NonNull<[u8]>`] meeting the size and alignment guarantees of `layout`.
     ///
-    /// The returned block may have a larger size than specified by `layout.size()` and is
-    /// initialized as specified by [`init`], all the way up to the returned size of the block.
+    /// The returned block may have a larger size than specified by `layout.size()`, and may or may
+    /// not have its contents initialized.
     ///
-    /// [`init`]: AllocInit
+    /// [`NonNull<[u8]>`]: NonNull
     ///
     /// # Errors
     ///
@@ -195,7 +109,29 @@ pub unsafe trait AllocRef {
     /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
     ///
     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr>;
+    fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr>;
+
+    /// Behaves like `alloc`, but also ensures that the returned memory is zero-initialized.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
+    /// allocator's size or alignment constraints.
+    ///
+    /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
+    /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
+    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an allocation error are encouraged to
+    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+        let ptr = self.alloc(layout)?;
+        // SAFETY: `alloc` returns a valid memory block
+        unsafe { ptr.as_non_null_ptr().as_ptr().write_bytes(0, ptr.len()) }
+        Ok(ptr)
+    }
 
     /// Deallocates the memory referenced by `ptr`.
     ///
@@ -210,44 +146,100 @@ pub unsafe trait AllocRef {
 
     /// Attempts to extend the memory block.
     ///
-    /// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated
+    /// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated
     /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
     /// alignment and a size given by `new_size`. To accomplish this, the allocator may extend the
-    /// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is
-    /// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`.
-    ///
-    /// If [`MayMove`] is used then ownership of the memory block referenced by `ptr`
-    /// is transferred to this allocator. The memory may or may not be freed, and should be
-    /// considered unusable (unless of course it is transferred back to the caller again via the
-    /// return value of this method).
+    /// allocation referenced by `ptr` to fit the new layout.
     ///
     /// If this method returns `Err`, then ownership of the memory block has not been transferred to
     /// this allocator, and the contents of the memory block are unaltered.
     ///
-    /// The memory block will contain the following contents after a successful call to `grow`:
+    /// [`NonNull<[u8]>`]: NonNull
+    ///
+    /// # Safety
+    ///
+    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
+    /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.),
+    /// * `new_size` must be greater than or equal to `layout.size()`, and
+    /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
+    ///   (i.e., the rounded value must be less than or equal to `usize::MAX`).
+    // Note: We can't require that `new_size` is strictly greater than `layout.size()` because of ZSTs.
+    // alternative: `new_size` must be strictly greater than `layout.size()` or both are zero
+    ///
+    /// [*currently allocated*]: #currently-allocated-memory
+    /// [*fit*]: #memory-fitting
+    ///
+    /// # Errors
+    ///
+    /// Returns `Err` if the new layout does not meet the allocator's size and alignment
+    /// constraints of the allocator, or if growing otherwise fails.
+    ///
+    /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
+    /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
+    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an allocation error are encouraged to
+    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
+    ///
+    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
+    unsafe fn grow(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size >= size,
+            "`new_size` must be greater than or equal to `layout.size()`"
+        );
+
+        if size == new_size {
+            return Ok(NonNull::slice_from_raw_parts(ptr, size));
+        }
+
+        let new_layout =
+            // SAFETY: the caller must ensure that the `new_size` does not overflow.
+            // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
+            // The caller must ensure that `new_size` is greater than or equal to zero. If it's equal
+            // to zero, it's catched beforehand.
+            unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
+        let new_ptr = self.alloc(new_layout)?;
+
+        // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new
+        // memory allocation are valid for reads and writes for `size` bytes. Also, because the old
+        // allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to
+        // `copy_nonoverlapping` is safe.
+        // The safety contract for `dealloc` must be upheld by the caller.
+        unsafe {
+            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_non_null_ptr().as_ptr(), size);
+            self.dealloc(ptr, layout);
+            Ok(new_ptr)
+        }
+    }
+
+    /// Behaves like `grow`, but also ensures that the new contents are set to zero before being
+    /// returned.
+    ///
+    /// The memory block will contain the following contents after a successful call to
+    /// `grow_zeroed`:
     ///   * Bytes `0..layout.size()` are preserved from the original allocation.
-    ///   * Bytes `layout.size()..old_size` will either be preserved or initialized according to
-    ///     [`init`], depending on the allocator implementation. `old_size` refers to the size of
-    ///     the `MemoryBlock` prior to the `grow` call, which may be larger than the size
+    ///   * Bytes `layout.size()..old_size` will either be preserved or zeroed,
+    ///     depending on the allocator implementation. `old_size` refers to the size of
+    ///     the `MemoryBlock` prior to the `grow_zeroed` call, which may be larger than the size
     ///     that was originally requested when it was allocated.
-    ///   * Bytes `old_size..new_size` are initialized according to [`init`]. `new_size` refers to
+    ///   * Bytes `old_size..new_size` are zeroed. `new_size` refers to
     ///     the size of the `MemoryBlock` returned by the `grow` call.
     ///
-    /// [`InPlace`]: ReallocPlacement::InPlace
-    /// [`MayMove`]: ReallocPlacement::MayMove
-    /// [`placement`]: ReallocPlacement
-    /// [`init`]: AllocInit
-    ///
     /// # Safety
     ///
     /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
     /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.),
-    // We can't require that `new_size` is strictly greater than `memory.size` because of ZSTs.
-    // An alternative would be
-    // * `new_size must be strictly greater than `memory.size` or both are zero
     /// * `new_size` must be greater than or equal to `layout.size()`, and
     /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow
     ///   (i.e., the rounded value must be less than or equal to `usize::MAX`).
+    // Note: We can't require that `new_size` is strictly greater than `layout.size()` because of ZSTs.
+    // alternative: `new_size` must be strictly greater than `layout.size()` or both are zero
     ///
     /// [*currently allocated*]: #currently-allocated-memory
     /// [*fit*]: #memory-fitting
@@ -265,55 +257,48 @@ pub unsafe trait AllocRef {
     /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
     ///
     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
-    unsafe fn grow(
+    unsafe fn grow_zeroed(
         &mut self,
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-        init: AllocInit,
-    ) -> Result<MemoryBlock, AllocErr> {
-        match placement {
-            ReallocPlacement::InPlace => Err(AllocErr),
-            ReallocPlacement::MayMove => {
-                let size = layout.size();
-                debug_assert!(
-                    new_size >= size,
-                    "`new_size` must be greater than or equal to `layout.size()`"
-                );
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size >= size,
+            "`new_size` must be greater than or equal to `layout.size()`"
+        );
 
-                if new_size == size {
-                    return Ok(MemoryBlock { ptr, size });
-                }
+        if size == new_size {
+            return Ok(NonNull::slice_from_raw_parts(ptr, size));
+        }
 
-                let new_layout =
-                    // SAFETY: the caller must ensure that the `new_size` does not overflow.
-                    // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
-                    // The caller must ensure that `new_size` is greater than zero.
-                    unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
-                let new_memory = self.alloc(new_layout, init)?;
+        let new_layout =
+            // SAFETY: the caller must ensure that the `new_size` does not overflow.
+            // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
+            // The caller must ensure that `new_size` is greater than or equal to zero. If it's equal
+            // to zero, it's caught beforehand.
+            unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
+        let new_ptr = self.alloc_zeroed(new_layout)?;
 
-                // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new
-                // memory allocation are valid for reads and writes for `size` bytes. Also, because the old
-                // allocation wasn't yet deallocated, it cannot overlap `new_memory`. Thus, the call to
-                // `copy_nonoverlapping` is safe.
-                // The safety contract for `dealloc` must be upheld by the caller.
-                unsafe {
-                    ptr::copy_nonoverlapping(ptr.as_ptr(), new_memory.ptr.as_ptr(), size);
-                    self.dealloc(ptr, layout);
-                    Ok(new_memory)
-                }
-            }
+        // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new
+        // memory allocation are valid for reads and writes for `size` bytes. Also, because the old
+        // allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to
+        // `copy_nonoverlapping` is safe.
+        // The safety contract for `dealloc` must be upheld by the caller.
+        unsafe {
+            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_non_null_ptr().as_ptr(), size);
+            self.dealloc(ptr, layout);
+            Ok(new_ptr)
         }
     }
 
     /// Attempts to shrink the memory block.
     ///
-    /// Returns a new [`MemoryBlock`][] containing a pointer and the actual size of the allocated
+    /// Returns a new [`NonNull<[u8]>`] containing a pointer and the actual size of the allocated
     /// memory. The pointer is suitable for holding data described by a new layout with `layout`’s
     /// alignment and a size given by `new_size`. To accomplish this, the allocator may shrink the
-    /// allocation referenced by `ptr` to fit the new layout. If the [`placement`] is
-    /// [`InPlace`], the returned pointer is guaranteed to be the same as the passed `ptr`.
+    /// allocation referenced by `ptr` to fit the new layout.
     ///
     /// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
     /// transferred to this allocator. The memory may or may not have been freed, and should be
@@ -323,19 +308,15 @@ pub unsafe trait AllocRef {
     /// If this method returns `Err`, then ownership of the memory block has not been transferred to
     /// this allocator, and the contents of the memory block are unaltered.
     ///
-    /// The behavior of how the allocator tries to shrink the memory is specified by [`placement`].
-    ///
-    /// [`InPlace`]: ReallocPlacement::InPlace
-    /// [`placement`]: ReallocPlacement
+    /// [`NonNull<[u8]>`]: NonNull
     ///
     /// # Safety
     ///
     /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator,
     /// * `layout` must [*fit*] that block of memory (The `new_size` argument need not fit it.), and
-    // We can't require that `new_size` is strictly smaller than `memory.size` because of ZSTs.
-    // An alternative would be
-    // * `new_size must be strictly smaller than `memory.size` or both are zero
     /// * `new_size` must be smaller than or equal to `layout.size()`.
+    // Note: We can't require that `new_size` is strictly smaller than `layout.size()` because of ZSTs.
+    // alternative: `new_size` must be smaller than `layout.size()` or both are zero
     ///
     /// [*currently allocated*]: #currently-allocated-memory
     /// [*fit*]: #memory-fitting
@@ -358,39 +339,33 @@ pub unsafe trait AllocRef {
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-    ) -> Result<MemoryBlock, AllocErr> {
-        match placement {
-            ReallocPlacement::InPlace => Err(AllocErr),
-            ReallocPlacement::MayMove => {
-                let size = layout.size();
-                debug_assert!(
-                    new_size <= size,
-                    "`new_size` must be smaller than or equal to `layout.size()`"
-                );
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        let size = layout.size();
+        debug_assert!(
+            new_size <= size,
+            "`new_size` must be smaller than or equal to `layout.size()`"
+        );
 
-                if new_size == size {
-                    return Ok(MemoryBlock { ptr, size });
-                }
+        if size == new_size {
+            return Ok(NonNull::slice_from_raw_parts(ptr, size));
+        }
 
-                let new_layout =
-                // SAFETY: the caller must ensure that the `new_size` does not overflow.
-                // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
-                // The caller must ensure that `new_size` is greater than zero.
-                    unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
-                let new_memory = self.alloc(new_layout, AllocInit::Uninitialized)?;
+        let new_layout =
+        // SAFETY: the caller must ensure that the `new_size` does not overflow.
+        // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
+        // The caller must ensure that `new_size` is greater than zero.
+            unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
+        let new_ptr = self.alloc(new_layout)?;
 
-                // SAFETY: because `new_size` must be lower than or equal to `size`, both the old and new
-                // memory allocation are valid for reads and writes for `new_size` bytes. Also, because the
-                // old allocation wasn't yet deallocated, it cannot overlap `new_memory`. Thus, the call to
-                // `copy_nonoverlapping` is safe.
-                // The safety contract for `dealloc` must be upheld by the caller.
-                unsafe {
-                    ptr::copy_nonoverlapping(ptr.as_ptr(), new_memory.ptr.as_ptr(), new_size);
-                    self.dealloc(ptr, layout);
-                    Ok(new_memory)
-                }
-            }
+        // SAFETY: because `new_size` must be lower than or equal to `size`, both the old and new
+        // memory allocation are valid for reads and writes for `new_size` bytes. Also, because the
+        // old allocation wasn't yet deallocated, it cannot overlap `new_ptr`. Thus, the call to
+        // `copy_nonoverlapping` is safe.
+        // The safety contract for `dealloc` must be upheld by the caller.
+        unsafe {
+            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_non_null_ptr().as_ptr(), size);
+            self.dealloc(ptr, layout);
+            Ok(new_ptr)
         }
     }
 
@@ -409,8 +384,13 @@ where
     A: AllocRef + ?Sized,
 {
     #[inline]
-    fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
-        (**self).alloc(layout, init)
+    fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+        (**self).alloc(layout)
+    }
+
+    #[inline]
+    fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+        (**self).alloc_zeroed(layout)
     }
 
     #[inline]
@@ -425,11 +405,20 @@ where
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-        init: AllocInit,
-    ) -> Result<MemoryBlock, AllocErr> {
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        // SAFETY: the safety contract must be upheld by the caller
+        unsafe { (**self).grow(ptr, layout, new_size) }
+    }
+
+    #[inline]
+    unsafe fn grow_zeroed(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+    ) -> Result<NonNull<[u8]>, AllocErr> {
         // SAFETY: the safety contract must be upheld by the caller
-        unsafe { (**self).grow(ptr, layout, new_size, placement, init) }
+        unsafe { (**self).grow_zeroed(ptr, layout, new_size) }
     }
 
     #[inline]
@@ -438,9 +427,8 @@ where
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-    ) -> Result<MemoryBlock, AllocErr> {
+    ) -> Result<NonNull<[u8]>, AllocErr> {
         // SAFETY: the safety contract must be upheld by the caller
-        unsafe { (**self).shrink(ptr, layout, new_size, placement) }
+        unsafe { (**self).shrink(ptr, layout, new_size) }
     }
 }
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 51d9695687f..cbbfcb46113 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -788,6 +788,7 @@ impl<T: ?Sized> RefCell<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[track_caller]
     pub fn borrow(&self) -> Ref<'_, T> {
         self.try_borrow().expect("already mutably borrowed")
     }
@@ -863,6 +864,7 @@ impl<T: ?Sized> RefCell<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[track_caller]
     pub fn borrow_mut(&self) -> RefMut<'_, T> {
         self.try_borrow_mut().expect("already borrowed")
     }
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 44b86438f2a..3a28bc79eff 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1950,15 +1950,20 @@ extern "rust-intrinsic" {
     pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
 
     /// Internal placeholder for injecting code coverage counters when the "instrument-coverage"
-    /// option is enabled. The placeholder is replaced with `llvm.instrprof.increment` during code
-    /// generation.
+    /// option is enabled. The source code region information is extracted prior to code generation,
+    /// and added to the "coverage map", which is injected into the generated code as additional
+    /// data. This intrinsic then triggers the generation of LLVM intrinsic call
+    /// `instrprof.increment`, using the remaining args (`function_source_hash` and `index`).
     #[cfg(not(bootstrap))]
     #[lang = "count_code_region"]
     pub fn count_code_region(
         function_source_hash: u64,
         index: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        file_name: &'static str,
+        start_line: u32,
+        start_col: u32,
+        end_line: u32,
+        end_col: u32,
     );
 
     /// Internal marker for code coverage expressions, injected into the MIR when the
@@ -1973,8 +1978,11 @@ extern "rust-intrinsic" {
         index: u32,
         left_index: u32,
         right_index: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        file_name: &'static str,
+        start_line: u32,
+        start_col: u32,
+        end_line: u32,
+        end_col: u32,
     );
 
     /// This marker identifies a code region and two other counters or counter expressions
@@ -1986,14 +1994,24 @@ extern "rust-intrinsic" {
         index: u32,
         left_index: u32,
         right_index: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        file_name: &'static str,
+        start_line: u32,
+        start_col: u32,
+        end_line: u32,
+        end_col: u32,
     );
 
     /// This marker identifies a code region to be added to the "coverage map" to indicate source
     /// code that can never be reached.
     /// (See `coverage_counter_add` for more information.)
-    pub fn coverage_unreachable(start_byte_pos: u32, end_byte_pos: u32);
+    #[cfg(not(bootstrap))]
+    pub fn coverage_unreachable(
+        file_name: &'static str,
+        start_line: u32,
+        start_col: u32,
+        end_line: u32,
+        end_col: u32,
+    );
 
     /// See documentation of `<*const T>::guaranteed_eq` for details.
     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 048c9c5ddaa..eb50dc28b9f 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -1602,6 +1602,29 @@ $EndFeature, "
         }
 
         doc_comment! {
+            concat!("Computes the absolute value of `self` without any wrapping
+or panicking.
+
+
+# Examples
+
+Basic usage:
+
+```
+", $Feature, "#![feature(unsigned_abs)]
+assert_eq!(100", stringify!($SelfT), ".unsigned_abs(), 100", stringify!($UnsignedT), ");
+assert_eq!((-100", stringify!($SelfT), ").unsigned_abs(), 100", stringify!($UnsignedT), ");
+assert_eq!((-128i8).unsigned_abs(), 128u8);",
+$EndFeature, "
+```"),
+            #[unstable(feature = "unsigned_abs", issue = "74913")]
+            #[inline]
+            pub const fn unsigned_abs(self) -> $UnsignedT {
+                 self.wrapping_abs() as $UnsignedT
+            }
+        }
+
+        doc_comment! {
             concat!("Wrapping (modular) exponentiation. Computes `self.pow(exp)`,
 wrapping around at the boundary of the type.
 
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 0c0e6d291bb..e68dbf5215f 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1145,7 +1145,6 @@ impl<T, E: Into<!>> Result<T, E> {
     }
 }
 
-#[unstable(feature = "inner_deref", issue = "50264")]
 impl<T: Deref, E> Result<T, E> {
     /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&<T as Deref>::Target, &E>`.
     ///
@@ -1155,7 +1154,6 @@ impl<T: Deref, E> Result<T, E> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(inner_deref)]
     /// let x: Result<String, u32> = Ok("hello".to_string());
     /// let y: Result<&str, &u32> = Ok("hello");
     /// assert_eq!(x.as_deref(), y);
@@ -1164,23 +1162,12 @@ impl<T: Deref, E> Result<T, E> {
     /// let y: Result<&str, &u32> = Err(&42);
     /// assert_eq!(x.as_deref(), y);
     /// ```
+    #[stable(feature = "inner_deref", since = "1.47.0")]
     pub fn as_deref(&self) -> Result<&T::Target, &E> {
         self.as_ref().map(|t| t.deref())
     }
 }
 
-#[unstable(feature = "inner_deref", issue = "50264")]
-impl<T, E: Deref> Result<T, E> {
-    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T, &<E as Deref>::Target>`.
-    ///
-    /// Coerces the [`Err`] variant of the original [`Result`] via [`Deref`](crate::ops::Deref)
-    /// and returns the new [`Result`].
-    pub fn as_deref_err(&self) -> Result<&T, &E::Target> {
-        self.as_ref().map_err(|e| e.deref())
-    }
-}
-
-#[unstable(feature = "inner_deref", issue = "50264")]
 impl<T: DerefMut, E> Result<T, E> {
     /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut <T as DerefMut>::Target, &mut E>`.
     ///
@@ -1190,7 +1177,6 @@ impl<T: DerefMut, E> Result<T, E> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(inner_deref)]
     /// let mut s = "HELLO".to_string();
     /// let mut x: Result<String, u32> = Ok("hello".to_string());
     /// let y: Result<&mut str, &mut u32> = Ok(&mut s);
@@ -1201,22 +1187,12 @@ impl<T: DerefMut, E> Result<T, E> {
     /// let y: Result<&mut str, &mut u32> = Err(&mut i);
     /// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
     /// ```
+    #[stable(feature = "inner_deref", since = "1.47.0")]
     pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> {
         self.as_mut().map(|t| t.deref_mut())
     }
 }
 
-#[unstable(feature = "inner_deref", issue = "50264")]
-impl<T, E: DerefMut> Result<T, E> {
-    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T, &mut <E as DerefMut>::Target>`.
-    ///
-    /// Coerces the [`Err`] variant of the original [`Result`] via [`DerefMut`](crate::ops::DerefMut)
-    /// and returns the new [`Result`].
-    pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> {
-        self.as_mut().map_err(|e| e.deref_mut())
-    }
-}
-
 impl<T, E> Result<Option<T>, E> {
     /// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
     ///
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 6b28a815f03..b4c299d3905 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -27,7 +27,6 @@
 #![feature(test)]
 #![feature(trusted_len)]
 #![feature(try_trait)]
-#![feature(inner_deref)]
 #![feature(slice_internals)]
 #![feature(slice_partition_dedup)]
 #![feature(int_error_matching)]
diff --git a/library/core/tests/num/flt2dec/random.rs b/library/core/tests/num/flt2dec/random.rs
index 0ebc0881f52..e5656eb204c 100644
--- a/library/core/tests/num/flt2dec/random.rs
+++ b/library/core/tests/num/flt2dec/random.rs
@@ -188,7 +188,7 @@ fn exact_f32_random_equivalence_test() {
 fn exact_f64_random_equivalence_test() {
     use core::num::flt2dec::strategy::dragon::format_exact as fallback;
     // Miri is too slow
-    let n = if cfg!(miri) { 3 } else { 1_000 };
+    let n = if cfg!(miri) { 2 } else { 1_000 };
 
     for k in 1..21 {
         f64_random_equivalence_test(
diff --git a/library/core/tests/num/flt2dec/strategy/grisu.rs b/library/core/tests/num/flt2dec/strategy/grisu.rs
index ff8373c6455..7e6c8add333 100644
--- a/library/core/tests/num/flt2dec/strategy/grisu.rs
+++ b/library/core/tests/num/flt2dec/strategy/grisu.rs
@@ -2,6 +2,7 @@ use super::super::*;
 use core::num::flt2dec::strategy::grisu::*;
 
 #[test]
+#[cfg_attr(miri, ignore)] // Miri is too slow
 fn test_cached_power() {
     assert_eq!(CACHED_POW10.first().unwrap().1, CACHED_POW10_FIRST_E);
     assert_eq!(CACHED_POW10.last().unwrap().1, CACHED_POW10_LAST_E);
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index c835313aae7..caa2d916cd7 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -250,24 +250,11 @@ fn test_result_as_deref() {
     let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
     assert_eq!(ref_ok.as_deref(), expected_result);
 
-    // &Result<T, E: Deref>::Err(T).as_deref_err() ->
-    //      Result<&T, &E::Deref::Target>::Err(&*E)
-    let ref_err = &Result::Err::<u8, &i32>(&41);
-    let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.as_deref_err(), expected_result);
-
-    let ref_err = &Result::Err::<u32, String>(String::from("an error"));
-    let expected_result = Result::Err::<&u32, &str>("an error");
-    assert_eq!(ref_err.as_deref_err(), expected_result);
-
-    let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
-    let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
-    assert_eq!(ref_err.as_deref_err(), expected_result);
-
-    // &Result<T: Deref, E: Deref>::Err(T).as_deref_err() ->
-    //      Result<&T, &E::Deref::Target>::Err(&*E)
-    let ref_err = &Result::Err::<&u8, &i32>(&41);
-    let expected_result = Result::Err::<&u8, &&i32>(&&41);
+    // &Result<T: Deref, E>::Err(T).as_deref() ->
+    //      Result<&T::Deref::Target, &E>::Err(&*E)
+    let val = 41;
+    let ref_err = &Result::Err::<&u8, i32>(val);
+    let expected_result = Result::Err::<&u8, &i32>(&val);
     assert_eq!(ref_err.as_deref(), expected_result);
 
     let s = String::from("an error");
@@ -279,46 +266,12 @@ fn test_result_as_deref() {
     let ref_err = &Result::Err::<&u32, Vec<i32>>(v.clone());
     let expected_result = Result::Err::<&u32, &Vec<i32>>(&v);
     assert_eq!(ref_err.as_deref(), expected_result);
-
-    // The following cases test calling `as_deref_*` with the wrong variant (i.e.
-    // `as_deref()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
-    // While uncommon, these cases are supported to ensure that an `as_deref_*`
-    // call can still be made even when one of the Result types does not implement
-    // `Deref` (for example, std::io::Error).
-
-    // &Result<T, E: Deref>::Ok(T).as_deref_err() ->
-    //      Result<&T, &E::Deref::Target>::Ok(&T)
-    let ref_ok = &Result::Ok::<i32, &u8>(42);
-    let expected_result = Result::Ok::<&i32, &u8>(&42);
-    assert_eq!(ref_ok.as_deref_err(), expected_result);
-
-    let ref_ok = &Result::Ok::<&str, &u32>("a result");
-    let expected_result = Result::Ok::<&&str, &u32>(&"a result");
-    assert_eq!(ref_ok.as_deref_err(), expected_result);
-
-    let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]);
-    let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
-    assert_eq!(ref_ok.as_deref_err(), expected_result);
-
-    // &Result<T: Deref, E>::Err(E).as_deref() ->
-    //      Result<&T::Deref::Target, &E>::Err(&E)
-    let ref_err = &Result::Err::<&u8, i32>(41);
-    let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.as_deref(), expected_result);
-
-    let ref_err = &Result::Err::<&u32, &str>("an error");
-    let expected_result = Result::Err::<&u32, &&str>(&"an error");
-    assert_eq!(ref_err.as_deref(), expected_result);
-
-    let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
-    let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
-    assert_eq!(ref_err.as_deref(), expected_result);
 }
 
 #[test]
 fn test_result_as_deref_mut() {
-    // &mut Result<T: Deref, E>::Ok(T).as_deref_mut() ->
-    //      Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T)
+    // &mut Result<T: DerefMut, E>::Ok(T).as_deref_mut() ->
+    //      Result<&mut T::DerefMut::Target, &mut E>::Ok(&mut *T)
     let mut val = 42;
     let mut expected_val = 42;
     let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val);
@@ -335,26 +288,8 @@ fn test_result_as_deref_mut() {
     let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
     assert_eq!(mut_ok.as_deref_mut(), expected_result);
 
-    // &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() ->
-    //      Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
-    let mut val = 41;
-    let mut expected_val = 41;
-    let mut_err = &mut Result::Err::<u8, &mut i32>(&mut val);
-    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
-    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
-
-    let mut expected_string = String::from("an error");
-    let mut_err = &mut Result::Err::<u32, String>(expected_string.clone());
-    let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut());
-    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
-
-    let mut expected_vec = vec![5, 4, 3, 2, 1];
-    let mut_err = &mut Result::Err::<u32, Vec<i32>>(expected_vec.clone());
-    let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
-    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
-
-    // &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() ->
-    //      Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
+    // &mut Result<T: DerefMut, E>::Err(T).as_deref_mut() ->
+    //      Result<&mut T, &mut E>::Err(&mut *E)
     let mut val = 41;
     let mut_err = &mut Result::Err::<&mut u8, i32>(val);
     let expected_result = Result::Err::<&mut u8, &mut i32>(&mut val);
@@ -369,48 +304,4 @@ fn test_result_as_deref_mut() {
     let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone());
     let expected_result = Result::Err::<&mut u32, &mut Vec<i32>>(&mut expected_vec);
     assert_eq!(mut_err.as_deref_mut(), expected_result);
-
-    // The following cases test calling `as_deref_mut_*` with the wrong variant (i.e.
-    // `as_deref_mut()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
-    // While uncommon, these cases are supported to ensure that an `as_deref_mut_*`
-    // call can still be made even when one of the Result types does not implement
-    // `Deref` (for example, std::io::Error).
-
-    // &mut Result<T, E: Deref>::Ok(T).as_deref_mut_err() ->
-    //      Result<&mut T, &mut E::Deref::Target>::Ok(&mut T)
-    let mut expected_val = 42;
-    let mut_ok = &mut Result::Ok::<i32, &mut u8>(expected_val.clone());
-    let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
-    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
-
-    let string = String::from("a result");
-    let expected_string = string.clone();
-    let mut ref_str = expected_string.as_ref();
-    let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str());
-    let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str);
-    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
-
-    let mut expected_arr = [1, 2, 3, 4, 5];
-    let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone());
-    let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr);
-    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
-
-    // &mut Result<T: Deref, E>::Err(E).as_deref_mut() ->
-    //      Result<&mut T::Deref::Target, &mut E>::Err(&mut E)
-    let mut expected_val = 41;
-    let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone());
-    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
-    assert_eq!(mut_err.as_deref_mut(), expected_result);
-
-    let string = String::from("an error");
-    let expected_string = string.clone();
-    let mut ref_str = expected_string.as_ref();
-    let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str());
-    let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str);
-    assert_eq!(mut_err.as_deref_mut(), expected_result);
-
-    let mut expected_arr = [5, 4, 3, 2, 1];
-    let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone());
-    let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr);
-    assert_eq!(mut_err.as_deref_mut(), expected_result);
 }
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 27cc7fce1da..42b483f33ba 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -1358,15 +1358,15 @@ fn sort_unstable() {
     use core::slice::heapsort;
     use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng};
 
-    // Miri is too slow
-    let large_range = if cfg!(miri) { 0..0 } else { 500..510 };
+    // Miri is too slow (but still need to `chain` to make the types match)
+    let lens = if cfg!(miri) { (2..20).chain(0..0) } else { (2..25).chain(500..510) };
     let rounds = if cfg!(miri) { 1 } else { 100 };
 
     let mut v = [0; 600];
     let mut tmp = [0; 600];
     let mut rng = StdRng::from_entropy();
 
-    for len in (2..25).chain(large_range) {
+    for len in lens {
         let v = &mut v[0..len];
         let tmp = &mut tmp[0..len];
 
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index c050a3c591c..de3866d92fc 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -24,7 +24,6 @@
 #![feature(decl_macro)]
 #![feature(extern_types)]
 #![feature(in_band_lifetimes)]
-#![feature(inner_deref)]
 #![feature(negative_impls)]
 #![feature(optin_builtin_traits)]
 #![feature(restricted_std)]
@@ -849,7 +848,7 @@ impl Ident {
     /// Creates a new `Ident` with the given `string` as well as the specified
     /// `span`.
     /// The `string` argument must be a valid identifier permitted by the
-    /// language, otherwise the function will panic.
+    /// language (including keywords, e.g. `self` or `fn`). Otherwise, the function will panic.
     ///
     /// Note that `span`, currently in rustc, configures the hygiene information
     /// for this identifier.
@@ -871,7 +870,10 @@ impl Ident {
     }
 
     /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
-    #[unstable(feature = "proc_macro_raw_ident", issue = "54723")]
+    /// The `string` argument be a valid identifier permitted by the language
+    /// (including keywords, e.g. `fn`). Keywords which are usable in path segments
+    /// (e.g. `self`, `super`) are not supported, and will cause a panic.
+    #[stable(feature = "proc_macro_raw_ident", since = "1.47.0")]
     pub fn new_raw(string: &str, span: Span) -> Ident {
         Ident(bridge::client::Ident::new(string, span.0, true))
     }
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index ecfaaeace51..4712cc95b4a 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -140,28 +140,35 @@ pub struct System;
 #[unstable(feature = "allocator_api", issue = "32838")]
 unsafe impl AllocRef for System {
     #[inline]
-    fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> {
-        unsafe {
-            let size = layout.size();
-            if size == 0 {
-                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
-            } else {
-                let raw_ptr = match init {
-                    AllocInit::Uninitialized => GlobalAlloc::alloc(self, layout),
-                    AllocInit::Zeroed => GlobalAlloc::alloc_zeroed(self, layout),
-                };
-                let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
-                Ok(MemoryBlock { ptr, size })
-            }
-        }
+    fn alloc(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+        let size = layout.size();
+        let ptr = if size == 0 {
+            layout.dangling()
+        } else {
+            // SAFETY: `layout` is non-zero in size,
+            unsafe { NonNull::new(GlobalAlloc::alloc(&System, layout)).ok_or(AllocErr)? }
+        };
+        Ok(NonNull::slice_from_raw_parts(ptr, size))
+    }
+
+    #[inline]
+    fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<[u8]>, AllocErr> {
+        let size = layout.size();
+        let ptr = if size == 0 {
+            layout.dangling()
+        } else {
+            // SAFETY: `layout` is non-zero in size,
+            unsafe { NonNull::new(GlobalAlloc::alloc_zeroed(&System, layout)).ok_or(AllocErr)? }
+        };
+        Ok(NonNull::slice_from_raw_parts(ptr, size))
     }
 
     #[inline]
     unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
         if layout.size() != 0 {
-            // SAFETY: The safety guarantees are explained in the documentation
-            // for the `GlobalAlloc` trait and its `dealloc` method.
-            unsafe { GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) }
+            // SAFETY: `layout` is non-zero in size,
+            // other conditions must be upheld by the caller
+            unsafe { GlobalAlloc::dealloc(&System, ptr.as_ptr(), layout) }
         }
     }
 
@@ -171,53 +178,59 @@ unsafe impl AllocRef for System {
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-        init: AllocInit,
-    ) -> Result<MemoryBlock, AllocErr> {
-        let size = layout.size();
+    ) -> Result<NonNull<[u8]>, AllocErr> {
         debug_assert!(
-            new_size >= size,
-            "`new_size` must be greater than or equal to `memory.size()`"
+            new_size >= layout.size(),
+            "`new_size` must be greater than or equal to `layout.size()`"
         );
 
-        if size == new_size {
-            return Ok(MemoryBlock { ptr, size });
+        // SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+        // Other conditions must be upheld by the caller
+        unsafe {
+            match layout.size() {
+                old_size if old_size == new_size => {
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
+                }
+                0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
+                old_size => {
+                    // `realloc` probably checks for `new_size > size` or something similar.
+                    intrinsics::assume(new_size > old_size);
+                    let raw_ptr = GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size);
+                    let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
+                }
+            }
         }
+    }
 
-        match placement {
-            ReallocPlacement::InPlace => Err(AllocErr),
-            ReallocPlacement::MayMove if layout.size() == 0 => {
-                let new_layout =
-                    // SAFETY: The new size and layout alignement guarantees
-                    // are transfered to the caller (they come from parameters).
-                    //
-                    // See the preconditions for `Layout::from_size_align` to
-                    // see what must be checked.
-                    unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
-                self.alloc(new_layout, init)
-            }
-            ReallocPlacement::MayMove => {
-                // SAFETY:
-                //
-                // The safety guarantees are explained in the documentation
-                // for the `GlobalAlloc` trait and its `dealloc` method.
-                //
-                // `realloc` probably checks for `new_size > size` or something
-                // similar.
-                //
-                // For the guarantees about `init_offset`, see its documentation:
-                // `ptr` is assumed valid (and checked for non-NUL) and
-                // `memory.size` is set to `new_size` so the offset being `size`
-                // is valid.
-                let memory = unsafe {
-                    intrinsics::assume(new_size > size);
-                    let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size);
-                    let memory =
-                        MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
-                    init.init_offset(memory, size);
-                    memory
-                };
-                Ok(memory)
+    #[inline]
+    unsafe fn grow_zeroed(
+        &mut self,
+        ptr: NonNull<u8>,
+        layout: Layout,
+        new_size: usize,
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        debug_assert!(
+            new_size >= layout.size(),
+            "`new_size` must be greater than or equal to `layout.size()`"
+        );
+
+        // SAFETY: `new_size` must be non-zero, which is checked in the match expression.
+        // Other conditions must be upheld by the caller
+        unsafe {
+            match layout.size() {
+                old_size if old_size == new_size => {
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
+                }
+                0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())),
+                old_size => {
+                    // `realloc` probably checks for `new_size > size` or something similar.
+                    intrinsics::assume(new_size > old_size);
+                    let raw_ptr = GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size);
+                    raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+                    let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
+                    Ok(NonNull::slice_from_raw_parts(ptr, new_size))
+                }
             }
         }
     }
@@ -228,45 +241,34 @@ unsafe impl AllocRef for System {
         ptr: NonNull<u8>,
         layout: Layout,
         new_size: usize,
-        placement: ReallocPlacement,
-    ) -> Result<MemoryBlock, AllocErr> {
-        let size = layout.size();
+    ) -> Result<NonNull<[u8]>, AllocErr> {
+        let old_size = layout.size();
         debug_assert!(
-            new_size <= size,
-            "`new_size` must be smaller than or equal to `memory.size()`"
+            new_size <= old_size,
+            "`new_size` must be smaller than or equal to `layout.size()`"
         );
 
-        if size == new_size {
-            return Ok(MemoryBlock { ptr, size });
-        }
-
-        match placement {
-            ReallocPlacement::InPlace => Err(AllocErr),
-            ReallocPlacement::MayMove if new_size == 0 => {
-                // SAFETY: see `GlobalAlloc::dealloc` for the guarantees that
-                // must be respected. `ptr` and `layout` are parameters and so
-                // those guarantees must be checked by the caller.
-                unsafe { self.dealloc(ptr, layout) };
-                Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
+        let ptr = if new_size == old_size {
+            ptr
+        } else if new_size == 0 {
+            // SAFETY: `layout` is non-zero in size as `old_size` != `new_size`
+            // Other conditions must be upheld by the caller
+            unsafe {
+                self.dealloc(ptr, layout);
             }
-            ReallocPlacement::MayMove => {
-                // SAFETY:
-                //
-                // See `GlobalAlloc::realloc` for more informations about the
-                // guarantees expected by this method. `ptr`, `layout` and
-                // `new_size` are parameters and the responsability for their
-                // correctness is left to the caller.
-                //
-                // `realloc` probably checks for `new_size < size` or something
-                // similar.
-                let memory = unsafe {
-                    intrinsics::assume(new_size < size);
-                    let ptr = GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size);
-                    MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size }
-                };
-                Ok(memory)
-            }
-        }
+            layout.dangling()
+        } else {
+            // SAFETY: new_size is not zero,
+            // Other conditions must be upheld by the caller
+            let raw_ptr = unsafe {
+                // `realloc` probably checks for `new_size < old_size` or something similar.
+                intrinsics::assume(new_size < old_size);
+                GlobalAlloc::realloc(&System, ptr.as_ptr(), layout, new_size)
+            };
+            NonNull::new(raw_ptr).ok_or(AllocErr)?
+        };
+
+        Ok(NonNull::slice_from_raw_parts(ptr, new_size))
     }
 }
 static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 1fa438747c1..c98008688ab 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1363,7 +1363,7 @@ mod self_upper_keyword {}
 ///
 /// let r1 = &FOO as *const _;
 /// let r2 = &FOO as *const _;
-/// // With a strictly read-only static, references will have the same adress
+/// // With a strictly read-only static, references will have the same address
 /// assert_eq!(r1, r2);
 /// // A static item can be used just like a variable in many cases
 /// println!("{:?}", FOO);
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index c81b949af65..0569e46241a 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -291,6 +291,7 @@
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(nll)]
+#![feature(nonnull_slice_from_raw_parts)]
 #![feature(once_cell)]
 #![feature(optin_builtin_traits)]
 #![feature(or_patterns)]
@@ -308,6 +309,8 @@
 #![feature(shrink_to)]
 #![feature(slice_concat_ext)]
 #![feature(slice_internals)]
+#![feature(slice_ptr_get)]
+#![feature(slice_ptr_len)]
 #![feature(slice_strip)]
 #![feature(staged_api)]
 #![feature(std_internals)]
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index 64260990824..714ec3e8786 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -81,7 +81,7 @@
 //   see the changes to drop the `Waiter` struct correctly.
 // * There is one place where the two atomics `Once.state_and_queue` and
 //   `Waiter.signaled` come together, and might be reordered by the compiler or
-//   processor. Because both use Aquire ordering such a reordering is not
+//   processor. Because both use Acquire ordering such a reordering is not
 //   allowed, so no need for SeqCst.
 
 use crate::cell::Cell;
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index 84c4d662161..e36a53084ba 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -3,6 +3,8 @@
 use crate::cmp;
 use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read};
 use crate::mem;
+#[cfg(not(any(target_os = "redox", target_env = "newlib")))]
+use crate::sync::atomic::{AtomicUsize, Ordering};
 use crate::sys::cvt;
 use crate::sys_common::AsInner;
 
@@ -26,6 +28,27 @@ const READ_LIMIT: usize = c_int::MAX as usize - 1;
 #[cfg(not(target_os = "macos"))]
 const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
 
+#[cfg(not(any(target_os = "redox", target_env = "newlib")))]
+fn max_iov() -> usize {
+    static LIM: AtomicUsize = AtomicUsize::new(0);
+
+    let mut lim = LIM.load(Ordering::Relaxed);
+    if lim == 0 {
+        let ret = unsafe { libc::sysconf(libc::_SC_IOV_MAX) };
+
+        // 16 is the minimum value required by POSIX.
+        lim = if ret > 0 { ret as usize } else { 16 };
+        LIM.store(lim, Ordering::Relaxed);
+    }
+
+    lim
+}
+
+#[cfg(any(target_os = "redox", target_env = "newlib"))]
+fn max_iov() -> usize {
+    16 // The minimum value required by POSIX.
+}
+
 impl FileDesc {
     pub fn new(fd: c_int) -> FileDesc {
         FileDesc { fd }
@@ -54,7 +77,7 @@ impl FileDesc {
             libc::readv(
                 self.fd,
                 bufs.as_ptr() as *const libc::iovec,
-                cmp::min(bufs.len(), c_int::MAX as usize) as c_int,
+                cmp::min(bufs.len(), max_iov()) as c_int,
             )
         })?;
         Ok(ret as usize)
@@ -111,7 +134,7 @@ impl FileDesc {
             libc::writev(
                 self.fd,
                 bufs.as_ptr() as *const libc::iovec,
-                cmp::min(bufs.len(), c_int::MAX as usize) as c_int,
+                cmp::min(bufs.len(), max_iov()) as c_int,
             )
         })?;
         Ok(ret as usize)
@@ -256,3 +279,16 @@ impl Drop for FileDesc {
         let _ = unsafe { libc::close(self.fd) };
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::{FileDesc, IoSlice};
+
+    #[test]
+    fn limit_vector_count() {
+        let stdout = FileDesc { fd: 1 };
+        let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>();
+
+        assert!(stdout.write_vectored(&bufs).is_ok());
+    }
+}
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 2eed9e436a9..6782d845bb0 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -331,6 +331,7 @@ impl OpenOptions {
         // FIXME: some of these should probably be read-only or write-only...
         base |= wasi::RIGHTS_FD_ADVISE;
         base |= wasi::RIGHTS_FD_FDSTAT_SET_FLAGS;
+        base |= wasi::RIGHTS_FD_FILESTAT_GET;
         base |= wasi::RIGHTS_FD_FILESTAT_SET_TIMES;
         base |= wasi::RIGHTS_FD_SEEK;
         base |= wasi::RIGHTS_FD_SYNC;
diff --git a/library/stdarch b/library/stdarch
-Subproject 311d56cd91609c1c1c0370cbd2ece8e3048653a
+Subproject 78891cdf292c23278ca8723bd54310024915960
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index d6649d0521c..4dd71ebade1 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -171,7 +171,9 @@ fn main() {
         // note: everything below here is unreachable. do not put code that
         // should run on success, after this block.
     }
-    println!("\nDid not run successfully: {}\n{:?}\n-------------", status, cmd);
+    if verbose > 0 {
+        println!("\nDid not run successfully: {}\n{:?}\n-------------", status, cmd);
+    }
 
     if let Some(mut on_fail) = on_fail {
         on_fail.status().expect("Could not run the on_fail command");
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 144e146685f..e13a5f24653 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1037,7 +1037,7 @@ impl<'a> Builder<'a> {
             }
         }
 
-        // FIXME: Don't use LLD if we're compiling libtest, since it fails to link it.
+        // FIXME: Don't use LLD with MSVC if we're compiling libtest, since it fails to link it.
         // See https://github.com/rust-lang/rust/issues/68647.
         let can_use_lld = mode != Mode::Std;
 
@@ -1049,6 +1049,11 @@ impl<'a> Builder<'a> {
             let target = crate::envify(&target.triple);
             cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
         }
+
+        if self.config.use_lld && !target.contains("msvc") {
+            rustflags.arg("-Clink-args=-fuse-ld=lld");
+        }
+
         if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
             cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
         }
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index a4a1d5193b9..98b6be29c07 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1355,7 +1355,7 @@ pub struct RustAnalyzer {
 }
 
 impl Step for RustAnalyzer {
-    type Output = PathBuf;
+    type Output = Option<PathBuf>;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1373,11 +1373,17 @@ impl Step for RustAnalyzer {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
 
+        if target.contains("riscv64") {
+            // riscv64 currently has an LLVM bug that makes rust-analyzer unable
+            // to build. See #74813 for details.
+            return None;
+        }
+
         let src = builder.src.join("src/tools/rust-analyzer");
         let release_num = builder.release_num("rust-analyzer/crates/rust-analyzer");
         let name = pkgname(builder, "rust-analyzer");
@@ -1431,7 +1437,7 @@ impl Step for RustAnalyzer {
         builder.info(&format!("Dist rust-analyzer stage{} ({})", compiler.stage, target));
         let _time = timeit(builder);
         builder.run(&mut cmd);
-        distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))
+        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
     }
 }
 
@@ -1789,7 +1795,7 @@ impl Step for Extended {
         tarballs.push(rustc_installer);
         tarballs.push(cargo_installer);
         tarballs.extend(rls_installer.clone());
-        tarballs.push(rust_analyzer_installer.clone());
+        tarballs.extend(rust_analyzer_installer.clone());
         tarballs.push(clippy_installer);
         tarballs.extend(miri_installer.clone());
         tarballs.extend(rustfmt_installer.clone());
@@ -1867,7 +1873,9 @@ impl Step for Extended {
             if rls_installer.is_none() {
                 contents = filter(&contents, "rls");
             }
-            contents = filter(&contents, "rust-analyzer");
+            if rust_analyzer_installer.is_none() {
+                contents = filter(&contents, "rust-analyzer");
+            }
             if miri_installer.is_none() {
                 contents = filter(&contents, "miri");
             }
@@ -1914,7 +1922,9 @@ impl Step for Extended {
             if rls_installer.is_some() {
                 prepare("rls");
             }
-            prepare("rust-analyzer");
+            if rust_analyzer_installer.is_some() {
+                prepare("rust-analyzer");
+            }
             if miri_installer.is_some() {
                 prepare("miri");
             }
@@ -1976,7 +1986,9 @@ impl Step for Extended {
             if rls_installer.is_some() {
                 prepare("rls");
             }
-            prepare("rust-analyzer");
+            if rust_analyzer_installer.is_some() {
+                prepare("rust-analyzer");
+            }
             if miri_installer.is_some() {
                 prepare("miri");
             }
@@ -2076,23 +2088,25 @@ impl Step for Extended {
                         .arg(etc.join("msi/remove-duplicates.xsl")),
                 );
             }
-            builder.run(
-                Command::new(&heat)
-                    .current_dir(&exe)
-                    .arg("dir")
-                    .arg("rust-analyzer")
-                    .args(&heat_flags)
-                    .arg("-cg")
-                    .arg("RustAnalyzerGroup")
-                    .arg("-dr")
-                    .arg("RustAnalyzer")
-                    .arg("-var")
-                    .arg("var.RustAnalyzerDir")
-                    .arg("-out")
-                    .arg(exe.join("RustAnalyzerGroup.wxs"))
-                    .arg("-t")
-                    .arg(etc.join("msi/remove-duplicates.xsl")),
-            );
+            if rust_analyzer_installer.is_some() {
+                builder.run(
+                    Command::new(&heat)
+                        .current_dir(&exe)
+                        .arg("dir")
+                        .arg("rust-analyzer")
+                        .args(&heat_flags)
+                        .arg("-cg")
+                        .arg("RustAnalyzerGroup")
+                        .arg("-dr")
+                        .arg("RustAnalyzer")
+                        .arg("-var")
+                        .arg("var.RustAnalyzerDir")
+                        .arg("-out")
+                        .arg(exe.join("RustAnalyzerGroup.wxs"))
+                        .arg("-t")
+                        .arg(etc.join("msi/remove-duplicates.xsl")),
+                );
+            }
             builder.run(
                 Command::new(&heat)
                     .current_dir(&exe)
@@ -2186,7 +2200,9 @@ impl Step for Extended {
                 if rls_installer.is_some() {
                     cmd.arg("-dRlsDir=rls");
                 }
-                cmd.arg("-dRustAnalyzerDir=rust-analyzer");
+                if rust_analyzer_installer.is_some() {
+                    cmd.arg("-dRustAnalyzerDir=rust-analyzer");
+                }
                 if miri_installer.is_some() {
                     cmd.arg("-dMiriDir=miri");
                 }
@@ -2206,7 +2222,9 @@ impl Step for Extended {
             if rls_installer.is_some() {
                 candle("RlsGroup.wxs".as_ref());
             }
-            candle("RustAnalyzerGroup.wxs".as_ref());
+            if rust_analyzer_installer.is_some() {
+                candle("RustAnalyzerGroup.wxs".as_ref());
+            }
             if miri_installer.is_some() {
                 candle("MiriGroup.wxs".as_ref());
             }
@@ -2244,7 +2262,9 @@ impl Step for Extended {
             if rls_installer.is_some() {
                 cmd.arg("RlsGroup.wixobj");
             }
-            cmd.arg("RustAnalyzerGroup.wixobj");
+            if rust_analyzer_installer.is_some() {
+                cmd.arg("RustAnalyzerGroup.wixobj");
+            }
             if miri_installer.is_some() {
                 cmd.arg("MiriGroup.wixobj");
             }
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 2ead5d0a37f..bb5b9296c0a 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1158,13 +1158,19 @@ impl Step for Compiletest {
             cmd.arg("--quiet");
         }
 
+        let mut llvm_components_passed = false;
+        let mut copts_passed = false;
         if builder.config.llvm_enabled() {
             let llvm_config = builder.ensure(native::Llvm { target: builder.config.build });
             if !builder.config.dry_run {
                 let llvm_version = output(Command::new(&llvm_config).arg("--version"));
+                let llvm_components = output(Command::new(&llvm_config).arg("--components"));
                 // Remove trailing newline from llvm-config output.
-                let llvm_version = llvm_version.trim_end();
-                cmd.arg("--llvm-version").arg(llvm_version);
+                cmd.arg("--llvm-version")
+                    .arg(llvm_version.trim())
+                    .arg("--llvm-components")
+                    .arg(llvm_components.trim());
+                llvm_components_passed = true;
             }
             if !builder.is_rust_llvm(target) {
                 cmd.arg("--system-llvm");
@@ -1182,15 +1188,13 @@ impl Step for Compiletest {
             // Only pass correct values for these flags for the `run-make` suite as it
             // requires that a C++ compiler was configured which isn't always the case.
             if !builder.config.dry_run && suite == "run-make-fulldeps" {
-                let llvm_components = output(Command::new(&llvm_config).arg("--components"));
                 cmd.arg("--cc")
                     .arg(builder.cc(target))
                     .arg("--cxx")
                     .arg(builder.cxx(target).unwrap())
                     .arg("--cflags")
-                    .arg(builder.cflags(target, GitRepo::Rustc).join(" "))
-                    .arg("--llvm-components")
-                    .arg(llvm_components.trim());
+                    .arg(builder.cflags(target, GitRepo::Rustc).join(" "));
+                copts_passed = true;
                 if let Some(ar) = builder.ar(target) {
                     cmd.arg("--ar").arg(ar);
                 }
@@ -1220,15 +1224,11 @@ impl Step for Compiletest {
             }
         }
 
-        if suite != "run-make-fulldeps" {
-            cmd.arg("--cc")
-                .arg("")
-                .arg("--cxx")
-                .arg("")
-                .arg("--cflags")
-                .arg("")
-                .arg("--llvm-components")
-                .arg("");
+        if !llvm_components_passed {
+            cmd.arg("--llvm-components").arg("");
+        }
+        if !copts_passed {
+            cmd.arg("--cc").arg("").arg("--cxx").arg("").arg("--cflags").arg("");
         }
 
         if builder.remote_tested(target) {
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index a7c1987e8b1..0ff77de003d 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -84,6 +84,9 @@ x--expand-yaml-anchors--remove:
     os: windows-latest-xl
     <<: *base-job
 
+  - &job-aarch64-linux
+    os: [self-hosted, ARM64, linux]
+
   - &step
     if: success() && !env.SKIP_JOB
 
@@ -584,8 +587,16 @@ jobs:
       <<: [*shared-ci-variables, *dummy-variables]
     if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'
     strategy:
+      fail-fast: false
       matrix:
         include:
+          #############################
+          #   Linux/Docker builders   #
+          #############################
+
+          - name: aarch64-gnu
+            <<: *job-aarch64-linux
+
           ####################
           #  macOS Builders  #
           ####################
diff --git a/src/ci/scripts/symlink-build-dir.sh b/src/ci/scripts/symlink-build-dir.sh
index 50178b9c33e..28d8aa3b6e7 100755
--- a/src/ci/scripts/symlink-build-dir.sh
+++ b/src/ci/scripts/symlink-build-dir.sh
@@ -12,7 +12,7 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
 if isWindows && isAzurePipelines; then
     cmd //c "mkdir c:\\MORE_SPACE"
     cmd //c "mklink /J build c:\\MORE_SPACE"
-elif isLinux && isGitHubActions; then
+elif isLinux && isGitHubActions && ! isSelfHostedGitHubActions; then
     sudo mkdir -p /mnt/more-space
     sudo chown -R "$(whoami):" /mnt/more-space
 
diff --git a/src/ci/shared.sh b/src/ci/shared.sh
index 206065d7072..8222758ed6d 100644
--- a/src/ci/shared.sh
+++ b/src/ci/shared.sh
@@ -38,6 +38,11 @@ function isGitHubActions {
     [[ "${GITHUB_ACTIONS-false}" = "true" ]]
 }
 
+
+function isSelfHostedGitHubActions {
+    [[ "${RUST_GHA_SELF_HOSTED-false}" = "true" ]]
+}
+
 function isMacOS {
     [[ "${OSTYPE}" = "darwin"* ]]
 }
diff --git a/src/doc/book b/src/doc/book
-Subproject a914f2c7e5cdb771fa465de142381a51c53b580
+Subproject 363293c1c5ce9e84ea3935a5e29ce8624801208
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 94d9ea8460bcbbbfef1877b47cb930260b5849a
+Subproject b5256448a2a4c1bec68b93c0847066f92f2ff5a
diff --git a/src/doc/reference b/src/doc/reference
-Subproject b329ce37424874ad4db94f829a55807c6e21d2c
+Subproject c9b2736a059469043177e1e4ed41a55d7c63ac2
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 229c6945a26a53a751ffa4f9cb418388c00029d
+Subproject 2e9271981adc32613365810f3428334c0709521
diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs
index 9d4b6dbed98..809fda86542 100644
--- a/src/librustc_ast/attr/mod.rs
+++ b/src/librustc_ast/attr/mod.rs
@@ -100,8 +100,8 @@ impl NestedMetaItem {
     }
 
     /// Returns `true` if this list item is a MetaItem with a name of `name`.
-    pub fn check_name(&self, name: Symbol) -> bool {
-        self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
+    pub fn has_name(&self, name: Symbol) -> bool {
+        self.meta_item().map_or(false, |meta_item| meta_item.has_name(name))
     }
 
     /// For a single-segment meta item, returns its name; otherwise, returns `None`.
@@ -173,8 +173,13 @@ impl Attribute {
         }
     }
 
-    /// Returns `true` if the attribute's path matches the argument. If it matches, then the
-    /// attribute is marked as used.
+    /// Returns `true` if the attribute's path matches the argument.
+    /// If it matches, then the attribute is marked as used.
+    /// Should only be used by rustc, other tools can use `has_name` instead,
+    /// because only rustc is supposed to report the `unused_attributes` lint.
+    /// `MetaItem` and `NestedMetaItem` are produced by "lowering" an `Attribute`
+    /// and don't have identity, so they only has the `has_name` method,
+    /// and you need to mark the original `Attribute` as used when necessary.
     pub fn check_name(&self, name: Symbol) -> bool {
         let matches = self.has_name(name);
         if matches {
@@ -278,7 +283,7 @@ impl MetaItem {
         }
     }
 
-    pub fn check_name(&self, name: Symbol) -> bool {
+    pub fn has_name(&self, name: Symbol) -> bool {
         self.path == name
     }
 
@@ -405,7 +410,7 @@ pub fn mk_doc_comment(style: AttrStyle, comment: Symbol, span: Span) -> Attribut
 }
 
 pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
-    items.iter().any(|item| item.check_name(name))
+    items.iter().any(|item| item.has_name(name))
 }
 
 pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs
index 173ea5e48d6..e1c94ddf782 100644
--- a/src/librustc_ast/token.rs
+++ b/src/librustc_ast/token.rs
@@ -673,62 +673,6 @@ impl Token {
 
         Some(Token::new(kind, self.span.to(joint.span)))
     }
-
-    // See comments in `Nonterminal::to_tokenstream` for why we care about
-    // *probably* equal here rather than actual equality
-    crate fn probably_equal_for_proc_macro(&self, other: &Token) -> bool {
-        if mem::discriminant(&self.kind) != mem::discriminant(&other.kind) {
-            return false;
-        }
-        match (&self.kind, &other.kind) {
-            (&Eq, &Eq)
-            | (&Lt, &Lt)
-            | (&Le, &Le)
-            | (&EqEq, &EqEq)
-            | (&Ne, &Ne)
-            | (&Ge, &Ge)
-            | (&Gt, &Gt)
-            | (&AndAnd, &AndAnd)
-            | (&OrOr, &OrOr)
-            | (&Not, &Not)
-            | (&Tilde, &Tilde)
-            | (&At, &At)
-            | (&Dot, &Dot)
-            | (&DotDot, &DotDot)
-            | (&DotDotDot, &DotDotDot)
-            | (&DotDotEq, &DotDotEq)
-            | (&Comma, &Comma)
-            | (&Semi, &Semi)
-            | (&Colon, &Colon)
-            | (&ModSep, &ModSep)
-            | (&RArrow, &RArrow)
-            | (&LArrow, &LArrow)
-            | (&FatArrow, &FatArrow)
-            | (&Pound, &Pound)
-            | (&Dollar, &Dollar)
-            | (&Question, &Question)
-            | (&Whitespace, &Whitespace)
-            | (&Comment, &Comment)
-            | (&Eof, &Eof) => true,
-
-            (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b,
-
-            (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b,
-
-            (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b,
-
-            (&Literal(a), &Literal(b)) => a == b,
-
-            (&Lifetime(a), &Lifetime(b)) => a == b,
-            (&Ident(a, b), &Ident(c, d)) => {
-                b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate)
-            }
-
-            (&Interpolated(..), &Interpolated(..)) => false,
-
-            _ => panic!("forgot to add a token?"),
-        }
-    }
 }
 
 impl PartialEq<TokenKind> for Token {
@@ -760,6 +704,67 @@ pub enum Nonterminal {
 #[cfg(target_arch = "x86_64")]
 rustc_data_structures::static_assert_size!(Nonterminal, 40);
 
+#[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)]
+pub enum NonterminalKind {
+    Item,
+    Block,
+    Stmt,
+    Pat,
+    Expr,
+    Ty,
+    Ident,
+    Lifetime,
+    Literal,
+    Meta,
+    Path,
+    Vis,
+    TT,
+}
+
+impl NonterminalKind {
+    pub fn from_symbol(symbol: Symbol) -> Option<NonterminalKind> {
+        Some(match symbol {
+            sym::item => NonterminalKind::Item,
+            sym::block => NonterminalKind::Block,
+            sym::stmt => NonterminalKind::Stmt,
+            sym::pat => NonterminalKind::Pat,
+            sym::expr => NonterminalKind::Expr,
+            sym::ty => NonterminalKind::Ty,
+            sym::ident => NonterminalKind::Ident,
+            sym::lifetime => NonterminalKind::Lifetime,
+            sym::literal => NonterminalKind::Literal,
+            sym::meta => NonterminalKind::Meta,
+            sym::path => NonterminalKind::Path,
+            sym::vis => NonterminalKind::Vis,
+            sym::tt => NonterminalKind::TT,
+            _ => return None,
+        })
+    }
+    fn symbol(self) -> Symbol {
+        match self {
+            NonterminalKind::Item => sym::item,
+            NonterminalKind::Block => sym::block,
+            NonterminalKind::Stmt => sym::stmt,
+            NonterminalKind::Pat => sym::pat,
+            NonterminalKind::Expr => sym::expr,
+            NonterminalKind::Ty => sym::ty,
+            NonterminalKind::Ident => sym::ident,
+            NonterminalKind::Lifetime => sym::lifetime,
+            NonterminalKind::Literal => sym::literal,
+            NonterminalKind::Meta => sym::meta,
+            NonterminalKind::Path => sym::path,
+            NonterminalKind::Vis => sym::vis,
+            NonterminalKind::TT => sym::tt,
+        }
+    }
+}
+
+impl fmt::Display for NonterminalKind {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.symbol())
+    }
+}
+
 impl Nonterminal {
     fn span(&self) -> Span {
         match self {
diff --git a/src/librustc_ast/tokenstream.rs b/src/librustc_ast/tokenstream.rs
index 15ae12ebf10..9d0199078fa 100644
--- a/src/librustc_ast/tokenstream.rs
+++ b/src/librustc_ast/tokenstream.rs
@@ -21,8 +21,6 @@ use rustc_macros::HashStable_Generic;
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 
-use log::debug;
-
 use std::{iter, mem};
 
 /// When the main rust parser encounters a syntax-extension invocation, it
@@ -68,23 +66,6 @@ impl TokenTree {
         }
     }
 
-    // See comments in `Nonterminal::to_tokenstream` for why we care about
-    // *probably* equal here rather than actual equality
-    //
-    // This is otherwise the same as `eq_unspanned`, only recursing with a
-    // different method.
-    pub fn probably_equal_for_proc_macro(&self, other: &TokenTree) -> bool {
-        match (self, other) {
-            (TokenTree::Token(token), TokenTree::Token(token2)) => {
-                token.probably_equal_for_proc_macro(token2)
-            }
-            (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
-                delim == delim2 && tts.probably_equal_for_proc_macro(&tts2)
-            }
-            _ => false,
-        }
-    }
-
     /// Retrieves the TokenTree's span.
     pub fn span(&self) -> Span {
         match self {
@@ -307,112 +288,6 @@ impl TokenStream {
         t1.next().is_none() && t2.next().is_none()
     }
 
-    // See comments in `Nonterminal::to_tokenstream` for why we care about
-    // *probably* equal here rather than actual equality
-    //
-    // This is otherwise the same as `eq_unspanned`, only recursing with a
-    // different method.
-    pub fn probably_equal_for_proc_macro(&self, other: &TokenStream) -> bool {
-        // When checking for `probably_eq`, we ignore certain tokens that aren't
-        // preserved in the AST. Because they are not preserved, the pretty
-        // printer arbitrarily adds or removes them when printing as token
-        // streams, making a comparison between a token stream generated from an
-        // AST and a token stream which was parsed into an AST more reliable.
-        fn semantic_tree(tree: &TokenTree) -> bool {
-            if let TokenTree::Token(token) = tree {
-                if let
-                    // The pretty printer tends to add trailing commas to
-                    // everything, and in particular, after struct fields.
-                    | token::Comma
-                    // The pretty printer emits `NoDelim` as whitespace.
-                    | token::OpenDelim(DelimToken::NoDelim)
-                    | token::CloseDelim(DelimToken::NoDelim)
-                    // The pretty printer collapses many semicolons into one.
-                    | token::Semi
-                    // The pretty printer collapses whitespace arbitrarily and can
-                    // introduce whitespace from `NoDelim`.
-                    | token::Whitespace
-                    // The pretty printer can turn `$crate` into `::crate_name`
-                    | token::ModSep = token.kind {
-                    return false;
-                }
-            }
-            true
-        }
-
-        // When comparing two `TokenStream`s, we ignore the `IsJoint` information.
-        //
-        // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will
-        // use `Token.glue` on adjacent tokens with the proper `IsJoint`.
-        // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`)
-        // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent
-        // when determining if two `TokenStream`s are 'probably equal'.
-        //
-        // Therefore, we use `break_two_token_op` to convert all tokens
-        // to the 'unglued' form (if it exists). This ensures that two
-        // `TokenStream`s which differ only in how their tokens are glued
-        // will be considered 'probably equal', which allows us to keep spans.
-        //
-        // This is important when the original `TokenStream` contained
-        // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces
-        // will be omitted when we pretty-print, which can cause the original
-        // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`,
-        // leading to some tokens being 'glued' together in one stream but not
-        // the other. See #68489 for more details.
-        fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> {
-            // In almost all cases, we should have either zero or one levels
-            // of 'unglueing'. However, in some unusual cases, we may need
-            // to iterate breaking tokens mutliple times. For example:
-            // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]'
-            let mut token_trees: SmallVec<[_; 2]>;
-            if let TokenTree::Token(token) = &tree {
-                let mut out = SmallVec::<[_; 2]>::new();
-                out.push(token.clone());
-                // Iterate to fixpoint:
-                // * We start off with 'out' containing our initial token, and `temp` empty
-                // * If we are able to break any tokens in `out`, then `out` will have
-                //   at least one more element than 'temp', so we will try to break tokens
-                //   again.
-                // * If we cannot break any tokens in 'out', we are done
-                loop {
-                    let mut temp = SmallVec::<[_; 2]>::new();
-                    let mut changed = false;
-
-                    for token in out.into_iter() {
-                        if let Some((first, second)) = token.kind.break_two_token_op() {
-                            temp.push(Token::new(first, DUMMY_SP));
-                            temp.push(Token::new(second, DUMMY_SP));
-                            changed = true;
-                        } else {
-                            temp.push(token);
-                        }
-                    }
-                    out = temp;
-                    if !changed {
-                        break;
-                    }
-                }
-                token_trees = out.into_iter().map(TokenTree::Token).collect();
-                if token_trees.len() != 1 {
-                    debug!("break_tokens: broke {:?} to {:?}", tree, token_trees);
-                }
-            } else {
-                token_trees = SmallVec::new();
-                token_trees.push(tree);
-            }
-            token_trees.into_iter()
-        }
-
-        let mut t1 = self.trees().filter(semantic_tree).flat_map(break_tokens);
-        let mut t2 = other.trees().filter(semantic_tree).flat_map(break_tokens);
-        for (t1, t2) in t1.by_ref().zip(t2.by_ref()) {
-            if !t1.probably_equal_for_proc_macro(&t2) {
-                return false;
-            }
-        }
-        t1.next().is_none() && t2.next().is_none()
-    }
-
     pub fn map_enumerated<F: FnMut(usize, TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
         TokenStream(Lrc::new(
             self.0
diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml
index 51f34a1b78e..bf7e69a31ab 100644
--- a/src/librustc_ast_lowering/Cargo.toml
+++ b/src/librustc_ast_lowering/Cargo.toml
@@ -11,7 +11,7 @@ doctest = false
 
 [dependencies]
 rustc_arena = { path = "../librustc_arena" }
-log = { package = "tracing", version = "0.1" }
+tracing = "0.1"
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_hir = { path = "../librustc_hir" }
 rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index dd5e658102f..5414e584290 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -17,9 +17,9 @@ use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 use rustc_target::spec::abi;
 
-use log::debug;
 use smallvec::{smallvec, SmallVec};
 use std::collections::BTreeSet;
+use tracing::debug;
 
 pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
     pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 1c70eef3bf5..9df7ad2a9ac 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -64,10 +64,10 @@ use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 
-use log::{debug, trace};
 use smallvec::{smallvec, SmallVec};
 use std::collections::BTreeMap;
 use std::mem;
+use tracing::{debug, trace};
 
 macro_rules! arena_vec {
     ($this:expr; $($x:expr),*) => ({
diff --git a/src/librustc_ast_lowering/pat.rs b/src/librustc_ast_lowering/pat.rs
index 55c1f802663..171856e7e63 100644
--- a/src/librustc_ast_lowering/pat.rs
+++ b/src/librustc_ast_lowering/pat.rs
@@ -112,7 +112,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 // Found a sub-tuple pattern `$binding_mode $ident @ ..`.
                 // This is not allowed as a sub-tuple pattern
                 PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => {
-                    rest = Some((idx, pat.span));
                     let sp = pat.span;
                     self.diagnostic()
                         .struct_span_err(
@@ -128,7 +127,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             Applicability::MaybeIncorrect,
                         )
                         .emit();
-                    break;
                 }
                 _ => {}
             }
diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs
index e5ce51f8d2d..2541d6824fe 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/src/librustc_ast_lowering/path.rs
@@ -12,8 +12,8 @@ use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
-use log::debug;
 use smallvec::smallvec;
+use tracing::debug;
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
     crate fn lower_qpath(
diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml
index c53089a4afc..6db9bce3164 100644
--- a/src/librustc_ast_passes/Cargo.toml
+++ b/src/librustc_ast_passes/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 
 [dependencies]
 itertools = "0.8"
-log = { package = "tracing", version = "0.1" }
+tracing = "0.1"
 rustc_ast_pretty = { path = "../librustc_ast_pretty" }
 rustc_attr = { path = "../librustc_attr" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs
index b424c8afb34..22eaca4f071 100644
--- a/src/librustc_ast_passes/feature_gate.rs
+++ b/src/librustc_ast_passes/feature_gate.rs
@@ -10,7 +10,7 @@ use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 
-use log::debug;
+use tracing::debug;
 
 macro_rules! gate_feature_fn {
     ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
@@ -243,7 +243,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         if attr.check_name(sym::doc) {
             for nested_meta in attr.meta_item_list().unwrap_or_default() {
                 macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
-                    $(if nested_meta.check_name(sym::$name) {
+                    $(if nested_meta.has_name(sym::$name) {
                         let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental");
                         gate_feature_post!(self, $feature, attr.span, msg);
                     })*
@@ -314,7 +314,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             ast::ItemKind::Struct(..) => {
                 for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-                        if item.check_name(sym::simd) {
+                        if item.has_name(sym::simd) {
                             gate_feature_post!(
                                 &self,
                                 repr_simd,
diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml
index 4035346d354..d26205c791d 100644
--- a/src/librustc_ast_pretty/Cargo.toml
+++ b/src/librustc_ast_pretty/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 doctest = false
 
 [dependencies]
-log = { package = "tracing", version = "0.1" }
+tracing = "0.1"
 rustc_span = { path = "../librustc_span" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_ast_pretty/pp.rs b/src/librustc_ast_pretty/pp.rs
index 4bb806a923e..ca7f127ced6 100644
--- a/src/librustc_ast_pretty/pp.rs
+++ b/src/librustc_ast_pretty/pp.rs
@@ -132,10 +132,10 @@
 //! methods called `Printer::scan_*`, and the 'PRINT' process is the
 //! method called `Printer::print`.
 
-use log::debug;
 use std::borrow::Cow;
 use std::collections::VecDeque;
 use std::fmt;
+use tracing::debug;
 
 /// How to break. Described in more detail in the module docs.
 #[derive(Clone, Copy, PartialEq)]
diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs
index b0edb1ca41d..4b228629ad7 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/src/librustc_ast_pretty/pprust.rs
@@ -450,7 +450,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
     fn print_comment(&mut self, cmnt: &comments::Comment) {
         match cmnt.style {
             comments::Mixed => {
-                self.zerobreak();
+                if !self.is_beginning_of_line() {
+                    self.zerobreak();
+                }
                 if let Some((last, lines)) = cmnt.lines.split_last() {
                     self.ibox(0);
 
diff --git a/src/librustc_attr/builtin.rs b/src/librustc_attr/builtin.rs
index 1e088b52dcc..983202aafab 100644
--- a/src/librustc_attr/builtin.rs
+++ b/src/librustc_attr/builtin.rs
@@ -92,9 +92,9 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
             if let Some(meta) = attr.meta() {
                 if let MetaItemKind::List(items) = meta.kind {
                     if items.len() == 1 {
-                        if items[0].check_name(sym::allowed) {
+                        if items[0].has_name(sym::allowed) {
                             return Some(UnwindAttr::Allowed);
-                        } else if items[0].check_name(sym::aborts) {
+                        } else if items[0].has_name(sym::aborts) {
                             return Some(UnwindAttr::Aborts);
                         }
                     }
@@ -168,7 +168,7 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool
         item.check_name(sym::feature)
             && item
                 .meta_item_list()
-                .map(|list| list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name)))
+                .map(|list| list.iter().any(|mi| mi.is_word() && mi.has_name(feature_name)))
                 .unwrap_or(false)
     })
 }
@@ -505,7 +505,7 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
 }
 
 fn try_gate_cfg(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) {
-    let gate = find_gated_cfg(|sym| cfg.check_name(sym));
+    let gate = find_gated_cfg(|sym| cfg.has_name(sym));
     if let (Some(feats), Some(gated_cfg)) = (features, gate) {
         gate_cfg(&gated_cfg, cfg.span, sess, feats);
     }
@@ -898,7 +898,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
                     }
                 } else {
                     if let Some(meta_item) = item.meta_item() {
-                        if meta_item.check_name(sym::align) {
+                        if meta_item.has_name(sym::align) {
                             if let MetaItemKind::NameValue(ref value) = meta_item.kind {
                                 recognised = true;
                                 let mut err = struct_span_err!(
diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs
index 173a823dc7d..87be6d1743a 100644
--- a/src/librustc_builtin_macros/lib.rs
+++ b/src/librustc_builtin_macros/lib.rs
@@ -5,7 +5,6 @@
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
-#![feature(inner_deref)]
 #![feature(nll)]
 #![feature(or_patterns)]
 #![feature(proc_macro_internals)]
diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs
index f044ce41e87..763bdca35eb 100644
--- a/src/librustc_builtin_macros/proc_macro_harness.rs
+++ b/src/librustc_builtin_macros/proc_macro_harness.rs
@@ -143,7 +143,7 @@ impl<'a> CollectProcMacros<'a> {
 
         let attributes_attr = list.get(1);
         let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
-            if !attr.check_name(sym::attributes) {
+            if !attr.has_name(sym::attributes) {
                 self.handler.span_err(attr.span(), "second argument must be `attributes`")
             }
             attr.meta_item_list()
diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs
index 26d627e6b30..de8f81bdadf 100644
--- a/src/librustc_builtin_macros/test.rs
+++ b/src/librustc_builtin_macros/test.rs
@@ -336,7 +336,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
                 Some(list) => {
                     let msg = list
                         .iter()
-                        .find(|mi| mi.check_name(sym::expected))
+                        .find(|mi| mi.has_name(sym::expected))
                         .and_then(|mi| mi.meta_item())
                         .and_then(|mi| mi.value_str());
                     if list.len() != 1 || msg.is_none() {
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index f1e06cd8ebf..1d0b810165a 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -703,11 +703,67 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         None
     }
 
+    fn fptosui_may_trap(&self, val: &'ll Value, dest_ty: &'ll Type) -> bool {
+        // Most of the time we'll be generating the `fptosi` or `fptoui`
+        // instruction for floating-point-to-integer conversions. These
+        // instructions by definition in LLVM do not trap. For the WebAssembly
+        // target, however, we'll lower in some cases to intrinsic calls instead
+        // which may trap. If we detect that this is a situation where we'll be
+        // using the intrinsics then we report that the call map trap, which
+        // callers might need to handle.
+        if !self.wasm_and_missing_nontrapping_fptoint() {
+            return false;
+        }
+        let src_ty = self.cx.val_ty(val);
+        let float_width = self.cx.float_width(src_ty);
+        let int_width = self.cx.int_width(dest_ty);
+        match (int_width, float_width) {
+            (32, 32) | (32, 64) | (64, 32) | (64, 64) => true,
+            _ => false,
+        }
+    }
+
     fn fptoui(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+        // When we can, use the native wasm intrinsics which have tighter
+        // codegen. Note that this has a semantic difference in that the
+        // intrinsic can trap whereas `fptoui` never traps. That difference,
+        // however, is handled by `fptosui_may_trap` above.
+        if self.wasm_and_missing_nontrapping_fptoint() {
+            let src_ty = self.cx.val_ty(val);
+            let float_width = self.cx.float_width(src_ty);
+            let int_width = self.cx.int_width(dest_ty);
+            let name = match (int_width, float_width) {
+                (32, 32) => Some("llvm.wasm.trunc.unsigned.i32.f32"),
+                (32, 64) => Some("llvm.wasm.trunc.unsigned.i32.f64"),
+                (64, 32) => Some("llvm.wasm.trunc.unsigned.i64.f32"),
+                (64, 64) => Some("llvm.wasm.trunc.unsigned.i64.f64"),
+                _ => None,
+            };
+            if let Some(name) = name {
+                let intrinsic = self.get_intrinsic(name);
+                return self.call(intrinsic, &[val], None);
+            }
+        }
         unsafe { llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED) }
     }
 
     fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
+        if self.wasm_and_missing_nontrapping_fptoint() {
+            let src_ty = self.cx.val_ty(val);
+            let float_width = self.cx.float_width(src_ty);
+            let int_width = self.cx.int_width(dest_ty);
+            let name = match (int_width, float_width) {
+                (32, 32) => Some("llvm.wasm.trunc.signed.i32.f32"),
+                (32, 64) => Some("llvm.wasm.trunc.signed.i32.f64"),
+                (64, 32) => Some("llvm.wasm.trunc.signed.i64.f32"),
+                (64, 64) => Some("llvm.wasm.trunc.signed.i64.f64"),
+                _ => None,
+            };
+            if let Some(name) = name {
+                let intrinsic = self.get_intrinsic(name);
+                return self.call(intrinsic, &[val], None);
+            }
+        }
         unsafe { llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty, UNNAMED) }
     }
 
@@ -1349,4 +1405,9 @@ impl Builder<'a, 'll, 'tcx> {
             llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
         }
     }
+
+    fn wasm_and_missing_nontrapping_fptoint(&self) -> bool {
+        self.sess().target.target.arch == "wasm32"
+            && !self.sess().target_features.contains(&sym::nontrapping_dash_fptoint)
+    }
 }
diff --git a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs
index c2984607184..5d1bfd810b2 100644
--- a/src/librustc_codegen_llvm/coverageinfo/mapgen.rs
+++ b/src/librustc_codegen_llvm/coverageinfo/mapgen.rs
@@ -92,7 +92,7 @@ impl CoverageMapGenerator {
     fn write_coverage_mappings(
         &mut self,
         expressions: Vec<CounterExpression>,
-        counter_regions: impl Iterator<Item = (Counter, &'a Region)>,
+        counter_regions: impl Iterator<Item = (Counter, &'tcx Region<'tcx>)>,
         coverage_mappings_buffer: &RustString,
     ) {
         let mut counter_regions = counter_regions.collect::<Vec<_>>();
@@ -102,7 +102,7 @@ impl CoverageMapGenerator {
 
         let mut virtual_file_mapping = Vec::new();
         let mut mapping_regions = Vec::new();
-        let mut current_file_path = None;
+        let mut current_file_name = None;
         let mut current_file_id = 0;
 
         // Convert the list of (Counter, Region) pairs to an array of `CounterMappingRegion`, sorted
@@ -112,22 +112,22 @@ impl CoverageMapGenerator {
         // `filenames` array.
         counter_regions.sort_unstable_by_key(|(_counter, region)| *region);
         for (counter, region) in counter_regions {
-            let (file_path, start_line, start_col, end_line, end_col) = region.file_start_and_end();
-            let same_file = current_file_path.as_ref().map_or(false, |p| p == file_path);
+            let Region { file_name, start_line, start_col, end_line, end_col } = *region;
+            let same_file = current_file_name.as_ref().map_or(false, |p| p == file_name);
             if !same_file {
-                if current_file_path.is_some() {
+                if current_file_name.is_some() {
                     current_file_id += 1;
                 }
-                current_file_path = Some(file_path.clone());
-                let filename = CString::new(file_path.to_string_lossy().to_string())
-                    .expect("null error converting filename to C string");
-                debug!("  file_id: {} = '{:?}'", current_file_id, filename);
-                let filenames_index = match self.filename_to_index.get(&filename) {
+                current_file_name = Some(file_name.to_string());
+                let c_filename =
+                    CString::new(file_name).expect("null error converting filename to C string");
+                debug!("  file_id: {} = '{:?}'", current_file_id, c_filename);
+                let filenames_index = match self.filename_to_index.get(&c_filename) {
                     Some(index) => *index,
                     None => {
                         let index = self.filenames.len() as u32;
-                        self.filenames.push(filename.clone());
-                        self.filename_to_index.insert(filename.clone(), index);
+                        self.filenames.push(c_filename.clone());
+                        self.filename_to_index.insert(c_filename.clone(), index);
                         index
                     }
                 };
diff --git a/src/librustc_codegen_llvm/coverageinfo/mod.rs b/src/librustc_codegen_llvm/coverageinfo/mod.rs
index 0073e83dedb..4d51f8b0591 100644
--- a/src/librustc_codegen_llvm/coverageinfo/mod.rs
+++ b/src/librustc_codegen_llvm/coverageinfo/mod.rs
@@ -5,7 +5,7 @@ use crate::common::CodegenCx;
 
 use libc::c_uint;
 use llvm::coverageinfo::CounterMappingRegion;
-use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage};
+use rustc_codegen_ssa::coverageinfo::map::{CounterExpression, ExprKind, FunctionCoverage, Region};
 use rustc_codegen_ssa::traits::{
     BaseTypeMethods, CoverageInfoBuilderMethods, CoverageInfoMethods, StaticMethods,
 };
@@ -49,19 +49,18 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         instance: Instance<'tcx>,
         function_source_hash: u64,
         id: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        region: Region<'tcx>,
     ) {
         debug!(
             "adding counter to coverage_regions: instance={:?}, function_source_hash={}, id={}, \
-             byte range {}..{}",
-            instance, function_source_hash, id, start_byte_pos, end_byte_pos,
+             at {:?}",
+            instance, function_source_hash, id, region,
         );
         let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut();
         coverage_regions
             .entry(instance)
             .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
-            .add_counter(function_source_hash, id, start_byte_pos, end_byte_pos);
+            .add_counter(function_source_hash, id, region);
     }
 
     fn add_counter_expression_region(
@@ -71,43 +70,30 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         lhs: u32,
         op: ExprKind,
         rhs: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        region: Region<'tcx>,
     ) {
         debug!(
             "adding counter expression to coverage_regions: instance={:?}, id={}, {} {:?} {}, \
-             byte range {}..{}",
-            instance, id_descending_from_max, lhs, op, rhs, start_byte_pos, end_byte_pos,
+             at {:?}",
+            instance, id_descending_from_max, lhs, op, rhs, region,
         );
         let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut();
         coverage_regions
             .entry(instance)
             .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
-            .add_counter_expression(
-                id_descending_from_max,
-                lhs,
-                op,
-                rhs,
-                start_byte_pos,
-                end_byte_pos,
-            );
+            .add_counter_expression(id_descending_from_max, lhs, op, rhs, region);
     }
 
-    fn add_unreachable_region(
-        &mut self,
-        instance: Instance<'tcx>,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
-    ) {
+    fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: Region<'tcx>) {
         debug!(
-            "adding unreachable code to coverage_regions: instance={:?}, byte range {}..{}",
-            instance, start_byte_pos, end_byte_pos,
+            "adding unreachable code to coverage_regions: instance={:?}, at {:?}",
+            instance, region,
         );
         let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut();
         coverage_regions
             .entry(instance)
             .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
-            .add_unreachable_region(start_byte_pos, end_byte_pos);
+            .add_unreachable_region(region);
     }
 }
 
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 0b54284f594..8d6b3f9ccb6 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -13,7 +13,7 @@ use rustc_ast::ast;
 use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh};
 use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
-use rustc_codegen_ssa::coverageinfo::ExprKind;
+use rustc_codegen_ssa::coverageinfo;
 use rustc_codegen_ssa::glue;
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::PlaceRef;
@@ -93,64 +93,64 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         let mut is_codegen_intrinsic = true;
         // Set `is_codegen_intrinsic` to `false` to bypass `codegen_intrinsic_call()`.
 
-        if self.tcx.sess.opts.debugging_opts.instrument_coverage {
-            // If the intrinsic is from the local MIR, add the coverage information to the Codegen
-            // context, to be encoded into the local crate's coverage map.
-            if caller_instance.def_id().is_local() {
-                // FIXME(richkadel): Make sure to add coverage analysis tests on a crate with
-                // external crate dependencies, where:
-                //   1. Both binary and dependent crates are compiled with `-Zinstrument-coverage`
-                //   2. Only binary is compiled with `-Zinstrument-coverage`
-                //   3. Only dependent crates are compiled with `-Zinstrument-coverage`
-                match intrinsic {
-                    sym::count_code_region => {
-                        use coverage::count_code_region_args::*;
-                        self.add_counter_region(
-                            caller_instance,
-                            op_to_u64(&args[FUNCTION_SOURCE_HASH]),
-                            op_to_u32(&args[COUNTER_ID]),
-                            op_to_u32(&args[START_BYTE_POS]),
-                            op_to_u32(&args[END_BYTE_POS]),
-                        );
-                    }
-                    sym::coverage_counter_add | sym::coverage_counter_subtract => {
-                        use coverage::coverage_counter_expression_args::*;
-                        self.add_counter_expression_region(
-                            caller_instance,
-                            op_to_u32(&args[EXPRESSION_ID]),
-                            op_to_u32(&args[LEFT_ID]),
-                            if intrinsic == sym::coverage_counter_add {
-                                ExprKind::Add
-                            } else {
-                                ExprKind::Subtract
-                            },
-                            op_to_u32(&args[RIGHT_ID]),
-                            op_to_u32(&args[START_BYTE_POS]),
-                            op_to_u32(&args[END_BYTE_POS]),
-                        );
-                    }
-                    sym::coverage_unreachable => {
-                        use coverage::coverage_unreachable_args::*;
-                        self.add_unreachable_region(
-                            caller_instance,
-                            op_to_u32(&args[START_BYTE_POS]),
-                            op_to_u32(&args[END_BYTE_POS]),
-                        );
-                    }
-                    _ => {}
-                }
+        // FIXME(richkadel): Make sure to add coverage analysis tests on a crate with
+        // external crate dependencies, where:
+        //   1. Both binary and dependent crates are compiled with `-Zinstrument-coverage`
+        //   2. Only binary is compiled with `-Zinstrument-coverage`
+        //   3. Only dependent crates are compiled with `-Zinstrument-coverage`
+        match intrinsic {
+            sym::count_code_region => {
+                use coverage::count_code_region_args::*;
+                self.add_counter_region(
+                    caller_instance,
+                    op_to_u64(&args[FUNCTION_SOURCE_HASH]),
+                    op_to_u32(&args[COUNTER_ID]),
+                    coverageinfo::Region::new(
+                        op_to_str_slice(&args[FILE_NAME]),
+                        op_to_u32(&args[START_LINE]),
+                        op_to_u32(&args[START_COL]),
+                        op_to_u32(&args[END_LINE]),
+                        op_to_u32(&args[END_COL]),
+                    ),
+                );
             }
-
-            // Only the `count_code_region` coverage intrinsic is translated into an actual LLVM
-            // intrinsic call (local or not); otherwise, set `is_codegen_intrinsic` to `false`.
-            match intrinsic {
-                sym::coverage_counter_add
-                | sym::coverage_counter_subtract
-                | sym::coverage_unreachable => {
-                    is_codegen_intrinsic = false;
-                }
-                _ => {}
+            sym::coverage_counter_add | sym::coverage_counter_subtract => {
+                is_codegen_intrinsic = false;
+                use coverage::coverage_counter_expression_args::*;
+                self.add_counter_expression_region(
+                    caller_instance,
+                    op_to_u32(&args[EXPRESSION_ID]),
+                    op_to_u32(&args[LEFT_ID]),
+                    if intrinsic == sym::coverage_counter_add {
+                        coverageinfo::ExprKind::Add
+                    } else {
+                        coverageinfo::ExprKind::Subtract
+                    },
+                    op_to_u32(&args[RIGHT_ID]),
+                    coverageinfo::Region::new(
+                        op_to_str_slice(&args[FILE_NAME]),
+                        op_to_u32(&args[START_LINE]),
+                        op_to_u32(&args[START_COL]),
+                        op_to_u32(&args[END_LINE]),
+                        op_to_u32(&args[END_COL]),
+                    ),
+                );
             }
+            sym::coverage_unreachable => {
+                is_codegen_intrinsic = false;
+                use coverage::coverage_unreachable_args::*;
+                self.add_unreachable_region(
+                    caller_instance,
+                    coverageinfo::Region::new(
+                        op_to_str_slice(&args[FILE_NAME]),
+                        op_to_u32(&args[START_LINE]),
+                        op_to_u32(&args[START_COL]),
+                        op_to_u32(&args[END_LINE]),
+                        op_to_u32(&args[END_COL]),
+                    ),
+                );
+            }
+            _ => {}
         }
         is_codegen_intrinsic
     }
@@ -215,9 +215,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 self.call(llfn, &[], None)
             }
             sym::count_code_region => {
-                // FIXME(richkadel): The current implementation assumes the MIR for the given
-                // caller_instance represents a single function. Validate and/or correct if inlining
-                // and/or monomorphization invalidates these assumptions.
                 let coverageinfo = tcx.coverageinfo(caller_instance.def_id());
                 let mangled_fn = tcx.symbol_name(caller_instance);
                 let (mangled_fn_name, _len_val) = self.const_str(Symbol::intern(mangled_fn.name));
@@ -634,22 +631,19 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
             }
 
             sym::float_to_int_unchecked => {
-                let float_width = match float_type_width(arg_tys[0]) {
-                    Some(width) => width,
-                    None => {
-                        span_invalid_monomorphization_error(
-                            tcx.sess,
-                            span,
-                            &format!(
-                                "invalid monomorphization of `float_to_int_unchecked` \
+                if float_type_width(arg_tys[0]).is_none() {
+                    span_invalid_monomorphization_error(
+                        tcx.sess,
+                        span,
+                        &format!(
+                            "invalid monomorphization of `float_to_int_unchecked` \
                                   intrinsic: expected basic float type, \
                                   found `{}`",
-                                arg_tys[0]
-                            ),
-                        );
-                        return;
-                    }
-                };
+                            arg_tys[0]
+                        ),
+                    );
+                    return;
+                }
                 let (width, signed) = match int_type_width_signed(ret_ty, self.cx) {
                     Some(pair) => pair,
                     None => {
@@ -666,48 +660,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                         return;
                     }
                 };
-
-                // The LLVM backend can reorder and speculate `fptosi` and
-                // `fptoui`, so on WebAssembly the codegen for this instruction
-                // is quite heavyweight. To avoid this heavyweight codegen we
-                // instead use the raw wasm intrinsics which will lower to one
-                // instruction in WebAssembly (`iNN.trunc_fMM_{s,u}`). This one
-                // instruction will trap if the operand is out of bounds, but
-                // that's ok since this intrinsic is UB if the operands are out
-                // of bounds, so the behavior can be different on WebAssembly
-                // than other targets.
-                //
-                // Note, however, that when the `nontrapping-fptoint` feature is
-                // enabled in LLVM then LLVM will lower `fptosi` to
-                // `iNN.trunc_sat_fMM_{s,u}`, so if that's the case we don't
-                // bother with intrinsics.
-                let mut result = None;
-                if self.sess().target.target.arch == "wasm32"
-                    && !self.sess().target_features.contains(&sym::nontrapping_dash_fptoint)
-                {
-                    let name = match (width, float_width, signed) {
-                        (32, 32, true) => Some("llvm.wasm.trunc.signed.i32.f32"),
-                        (32, 64, true) => Some("llvm.wasm.trunc.signed.i32.f64"),
-                        (64, 32, true) => Some("llvm.wasm.trunc.signed.i64.f32"),
-                        (64, 64, true) => Some("llvm.wasm.trunc.signed.i64.f64"),
-                        (32, 32, false) => Some("llvm.wasm.trunc.unsigned.i32.f32"),
-                        (32, 64, false) => Some("llvm.wasm.trunc.unsigned.i32.f64"),
-                        (64, 32, false) => Some("llvm.wasm.trunc.unsigned.i64.f32"),
-                        (64, 64, false) => Some("llvm.wasm.trunc.unsigned.i64.f64"),
-                        _ => None,
-                    };
-                    if let Some(name) = name {
-                        let intrinsic = self.get_intrinsic(name);
-                        result = Some(self.call(intrinsic, &[args[0].immediate()], None));
-                    }
+                if signed {
+                    self.fptosi(args[0].immediate(), self.cx.type_ix(width))
+                } else {
+                    self.fptoui(args[0].immediate(), self.cx.type_ix(width))
                 }
-                result.unwrap_or_else(|| {
-                    if signed {
-                        self.fptosi(args[0].immediate(), self.cx.type_ix(width))
-                    } else {
-                        self.fptoui(args[0].immediate(), self.cx.type_ix(width))
-                    }
-                })
             }
 
             sym::discriminant_value => {
@@ -2283,6 +2240,10 @@ fn float_type_width(ty: Ty<'_>) -> Option<u64> {
     }
 }
 
+fn op_to_str_slice<'tcx>(op: &Operand<'tcx>) -> &'tcx str {
+    Operand::value_from_const(op).try_to_str_slice().expect("Value is &str")
+}
+
 fn op_to_u32<'tcx>(op: &Operand<'tcx>) -> u32 {
     Operand::scalar_from_const(op).to_u32().expect("Scalar is u32")
 }
diff --git a/src/librustc_codegen_ssa/coverageinfo/map.rs b/src/librustc_codegen_ssa/coverageinfo/map.rs
index 72138065a90..7f6841f9daa 100644
--- a/src/librustc_codegen_ssa/coverageinfo/map.rs
+++ b/src/librustc_codegen_ssa/coverageinfo/map.rs
@@ -3,12 +3,8 @@ pub use super::ffi::*;
 use rustc_index::vec::IndexVec;
 use rustc_middle::ty::Instance;
 use rustc_middle::ty::TyCtxt;
-use rustc_span::source_map::{Pos, SourceMap};
-use rustc_span::{BytePos, FileName, Loc, RealFileName};
 
-use std::cmp::{Ord, Ordering};
-use std::fmt;
-use std::path::PathBuf;
+use std::cmp::Ord;
 
 rustc_index::newtype_index! {
     pub struct ExpressionOperandId {
@@ -38,127 +34,35 @@ rustc_index::newtype_index! {
     }
 }
 
-#[derive(Clone, Debug)]
-pub struct Region {
-    start: Loc,
-    end: Loc,
-}
-
-impl Ord for Region {
-    fn cmp(&self, other: &Self) -> Ordering {
-        (&self.start.file.name, &self.start.line, &self.start.col, &self.end.line, &self.end.col)
-            .cmp(&(
-                &other.start.file.name,
-                &other.start.line,
-                &other.start.col,
-                &other.end.line,
-                &other.end.col,
-            ))
-    }
-}
-
-impl PartialOrd for Region {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl PartialEq for Region {
-    fn eq(&self, other: &Self) -> bool {
-        self.start.file.name == other.start.file.name
-            && self.start.line == other.start.line
-            && self.start.col == other.start.col
-            && self.end.line == other.end.line
-            && self.end.col == other.end.col
-    }
-}
-
-impl Eq for Region {}
-
-impl fmt::Display for Region {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let (file_path, start_line, start_col, end_line, end_col) = self.file_start_and_end();
-        write!(f, "{:?}:{}:{} - {}:{}", file_path, start_line, start_col, end_line, end_col)
-    }
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Region<'tcx> {
+    pub file_name: &'tcx str,
+    pub start_line: u32,
+    pub start_col: u32,
+    pub end_line: u32,
+    pub end_col: u32,
 }
 
-impl Region {
-    pub fn new(source_map: &SourceMap, start_byte_pos: u32, end_byte_pos: u32) -> Self {
-        let start = source_map.lookup_char_pos(BytePos::from_u32(start_byte_pos));
-        let end = source_map.lookup_char_pos(BytePos::from_u32(end_byte_pos));
-        assert_eq!(
-            start.file.name, end.file.name,
-            "Region start ({} -> {:?}) and end ({} -> {:?}) don't come from the same source file!",
-            start_byte_pos, start, end_byte_pos, end
-        );
-        Self { start, end }
-    }
-
-    pub fn file_start_and_end<'a>(&'a self) -> (&'a PathBuf, u32, u32, u32, u32) {
-        let start = &self.start;
-        let end = &self.end;
-        match &start.file.name {
-            FileName::Real(RealFileName::Named(path)) => (
-                path,
-                start.line as u32,
-                start.col.to_u32() + 1,
-                end.line as u32,
-                end.col.to_u32() + 1,
-            ),
-            _ => {
-                bug!("start.file.name should be a RealFileName, but it was: {:?}", start.file.name)
-            }
-        }
+impl<'tcx> Region<'tcx> {
+    pub fn new(
+        file_name: &'tcx str,
+        start_line: u32,
+        start_col: u32,
+        end_line: u32,
+        end_col: u32,
+    ) -> Self {
+        Self { file_name, start_line, start_col, end_line, end_col }
     }
 }
 
 #[derive(Clone, Debug)]
-pub struct ExpressionRegion {
+pub struct ExpressionRegion<'tcx> {
     lhs: ExpressionOperandId,
     op: ExprKind,
     rhs: ExpressionOperandId,
-    region: Region,
+    region: Region<'tcx>,
 }
 
-// FIXME(richkadel): There seems to be a problem computing the file location in
-// some cases. I need to investigate this more. When I generate and show coverage
-// for the example binary in the crates.io crate `json5format`, I had a couple of
-// notable problems:
-//
-//   1. I saw a lot of coverage spans in `llvm-cov show` highlighting regions in
-//      various comments (not corresponding to rustdoc code), indicating a possible
-//      problem with the byte_pos-to-source-map implementation.
-//
-//   2. And (perhaps not related) when I build the aforementioned example binary with:
-//      `RUST_FLAGS="-Zinstrument-coverage" cargo build --example formatjson5`
-//      and then run that binary with
-//      `LLVM_PROFILE_FILE="formatjson5.profraw" ./target/debug/examples/formatjson5 \
-//      some.json5` for some reason the binary generates *TWO* `.profraw` files. One
-//      named `default.profraw` and the other named `formatjson5.profraw` (the expected
-//      name, in this case).
-//
-//   3. I think that if I eliminate regions within a function, their region_ids,
-//      referenced in expressions, will be wrong? I think the ids are implied by their
-//      array position in the final coverage map output (IIRC).
-//
-//   4. I suspect a problem (if not the only problem) is the SourceMap is wrong for some
-//      region start/end byte positions. Just like I couldn't get the function hash at
-//      intrinsic codegen time for external crate functions, I think the SourceMap I
-//      have here only applies to the local crate, and I know I have coverages that
-//      reference external crates.
-//
-//          I still don't know if I fixed the hash problem correctly. If external crates
-//          implement the function, can't I use the coverage counters already compiled
-//          into those external crates? (Maybe not for generics and/or maybe not for
-//          macros... not sure. But I need to understand this better.)
-//
-// If the byte range conversion is wrong, fix it. But if it
-// is right, then it is possible for the start and end to be in different files.
-// Can I do something other than ignore coverages that span multiple files?
-//
-// If I can resolve this, remove the "Option<>" result type wrapper
-// `regions_in_file_order()` accordingly.
-
 /// Collects all of the coverage regions associated with (a) injected counters, (b) counter
 /// expressions (additions or subtraction), and (c) unreachable regions (always counted as zero),
 /// for a given Function. Counters and counter expressions have non-overlapping `id`s because they
@@ -171,19 +75,17 @@ pub struct ExpressionRegion {
 /// only whitespace or comments). According to LLVM Code Coverage Mapping documentation, "A count
 /// for a gap area is only used as the line execution count if there are no other regions on a
 /// line."
-pub struct FunctionCoverage<'a> {
-    source_map: &'a SourceMap,
+pub struct FunctionCoverage<'tcx> {
     source_hash: u64,
-    counters: IndexVec<CounterValueReference, Option<Region>>,
-    expressions: IndexVec<InjectedExpressionIndex, Option<ExpressionRegion>>,
-    unreachable_regions: Vec<Region>,
+    counters: IndexVec<CounterValueReference, Option<Region<'tcx>>>,
+    expressions: IndexVec<InjectedExpressionIndex, Option<ExpressionRegion<'tcx>>>,
+    unreachable_regions: Vec<Region<'tcx>>,
 }
 
-impl<'a> FunctionCoverage<'a> {
-    pub fn new<'tcx: 'a>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
+impl<'tcx> FunctionCoverage<'tcx> {
+    pub fn new(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
         let coverageinfo = tcx.coverageinfo(instance.def_id());
         Self {
-            source_map: tcx.sess.source_map(),
             source_hash: 0, // will be set with the first `add_counter()`
             counters: IndexVec::from_elem_n(None, coverageinfo.num_counters as usize),
             expressions: IndexVec::from_elem_n(None, coverageinfo.num_expressions as usize),
@@ -194,20 +96,14 @@ impl<'a> FunctionCoverage<'a> {
     /// Adds a code region to be counted by an injected counter intrinsic.
     /// The source_hash (computed during coverage instrumentation) should also be provided, and
     /// should be the same for all counters in a given function.
-    pub fn add_counter(
-        &mut self,
-        source_hash: u64,
-        id: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
-    ) {
+    pub fn add_counter(&mut self, source_hash: u64, id: u32, region: Region<'tcx>) {
         if self.source_hash == 0 {
             self.source_hash = source_hash;
         } else {
             debug_assert_eq!(source_hash, self.source_hash);
         }
         self.counters[CounterValueReference::from(id)]
-            .replace(Region::new(self.source_map, start_byte_pos, end_byte_pos))
+            .replace(region)
             .expect_none("add_counter called with duplicate `id`");
     }
 
@@ -231,8 +127,7 @@ impl<'a> FunctionCoverage<'a> {
         lhs: u32,
         op: ExprKind,
         rhs: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        region: Region<'tcx>,
     ) {
         let expression_id = ExpressionOperandId::from(id_descending_from_max);
         let lhs = ExpressionOperandId::from(lhs);
@@ -240,18 +135,13 @@ impl<'a> FunctionCoverage<'a> {
 
         let expression_index = self.expression_index(expression_id);
         self.expressions[expression_index]
-            .replace(ExpressionRegion {
-                lhs,
-                op,
-                rhs,
-                region: Region::new(self.source_map, start_byte_pos, end_byte_pos),
-            })
+            .replace(ExpressionRegion { lhs, op, rhs, region })
             .expect_none("add_counter_expression called with duplicate `id_descending_from_max`");
     }
 
     /// Add a region that will be marked as "unreachable", with a constant "zero counter".
-    pub fn add_unreachable_region(&mut self, start_byte_pos: u32, end_byte_pos: u32) {
-        self.unreachable_regions.push(Region::new(self.source_map, start_byte_pos, end_byte_pos));
+    pub fn add_unreachable_region(&mut self, region: Region<'tcx>) {
+        self.unreachable_regions.push(region)
     }
 
     /// Return the source hash, generated from the HIR node structure, and used to indicate whether
@@ -264,8 +154,8 @@ impl<'a> FunctionCoverage<'a> {
     /// associated `Regions` (from which the LLVM-specific `CoverageMapGenerator` will create
     /// `CounterMappingRegion`s.
     pub fn get_expressions_and_counter_regions(
-        &'a self,
-    ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'a Region)>) {
+        &'tcx self,
+    ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'tcx Region<'tcx>)>) {
         assert!(self.source_hash != 0);
 
         let counter_regions = self.counter_regions();
@@ -277,7 +167,7 @@ impl<'a> FunctionCoverage<'a> {
         (counter_expressions, counter_regions)
     }
 
-    fn counter_regions(&'a self) -> impl Iterator<Item = (Counter, &'a Region)> {
+    fn counter_regions(&'tcx self) -> impl Iterator<Item = (Counter, &'tcx Region<'tcx>)> {
         self.counters.iter_enumerated().filter_map(|(index, entry)| {
             // Option::map() will return None to filter out missing counters. This may happen
             // if, for example, a MIR-instrumented counter is removed during an optimization.
@@ -288,8 +178,8 @@ impl<'a> FunctionCoverage<'a> {
     }
 
     fn expressions_with_regions(
-        &'a self,
-    ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'a Region)>) {
+        &'tcx self,
+    ) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &'tcx Region<'tcx>)>) {
         let mut counter_expressions = Vec::with_capacity(self.expressions.len());
         let mut expression_regions = Vec::with_capacity(self.expressions.len());
         let mut new_indexes =
@@ -350,7 +240,7 @@ impl<'a> FunctionCoverage<'a> {
         (counter_expressions, expression_regions.into_iter())
     }
 
-    fn unreachable_regions(&'a self) -> impl Iterator<Item = (Counter, &'a Region)> {
+    fn unreachable_regions(&'tcx self) -> impl Iterator<Item = (Counter, &'tcx Region<'tcx>)> {
         self.unreachable_regions.iter().map(|region| (Counter::zero(), region))
     }
 
diff --git a/src/librustc_codegen_ssa/coverageinfo/mod.rs b/src/librustc_codegen_ssa/coverageinfo/mod.rs
index 1f0ffd289b1..ff794a75c36 100644
--- a/src/librustc_codegen_ssa/coverageinfo/mod.rs
+++ b/src/librustc_codegen_ssa/coverageinfo/mod.rs
@@ -2,3 +2,4 @@ pub mod ffi;
 pub mod map;
 
 pub use map::ExprKind;
+pub use map::Region;
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 9c108998bc9..77e94fe3d0a 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -11,7 +11,7 @@ use rustc_apfloat::{ieee, Float, Round, Status};
 use rustc_hir::lang_items::ExchangeMallocFnLangItem;
 use rustc_middle::mir;
 use rustc_middle::ty::cast::{CastTy, IntTy};
-use rustc_middle::ty::layout::HasTyCtxt;
+use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
 use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
 use rustc_span::source_map::{Span, DUMMY_SP};
 use rustc_span::symbol::sym;
@@ -369,10 +369,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 bx.inttoptr(usize_llval, ll_t_out)
                             }
                             (CastTy::Float, CastTy::Int(IntTy::I)) => {
-                                cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out)
+                                cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out, cast)
                             }
                             (CastTy::Float, CastTy::Int(_)) => {
-                                cast_float_to_int(&mut bx, false, llval, ll_t_in, ll_t_out)
+                                cast_float_to_int(&mut bx, false, llval, ll_t_in, ll_t_out, cast)
                             }
                             _ => bug!("unsupported cast: {:?} to {:?}", operand.layout.ty, cast.ty),
                         };
@@ -772,6 +772,7 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     x: Bx::Value,
     float_ty: Bx::Type,
     int_ty: Bx::Type,
+    int_layout: TyAndLayout<'tcx>,
 ) -> Bx::Value {
     if let Some(false) = bx.cx().sess().opts.debugging_opts.saturating_float_casts {
         return if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) };
@@ -782,8 +783,6 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         return try_sat_result;
     }
 
-    let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) };
-
     let int_width = bx.cx().int_width(int_ty);
     let float_width = bx.cx().float_width(float_ty);
     // LLVM's fpto[su]i returns undef when the input x is infinite, NaN, or does not fit into the
@@ -870,36 +869,138 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     //     int_ty::MIN and therefore the return value of int_ty::MIN is correct.
     // QED.
 
-    // Step 1 was already performed above.
-
-    // Step 2: We use two comparisons and two selects, with %s1 being the result:
-    //     %less_or_nan = fcmp ult %x, %f_min
-    //     %greater = fcmp olt %x, %f_max
-    //     %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result
-    //     %s1 = select %greater, int_ty::MAX, %s0
-    // Note that %less_or_nan uses an *unordered* comparison. This comparison is true if the
-    // operands are not comparable (i.e., if x is NaN). The unordered comparison ensures that s1
-    // becomes int_ty::MIN if x is NaN.
-    // Performance note: Unordered comparison can be lowered to a "flipped" comparison and a
-    // negation, and the negation can be merged into the select. Therefore, it not necessarily any
-    // more expensive than a ordered ("normal") comparison. Whether these optimizations will be
-    // performed is ultimately up to the backend, but at least x86 does perform them.
-    let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min);
-    let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max);
     let int_max = bx.cx().const_uint_big(int_ty, int_max(signed, int_width));
     let int_min = bx.cx().const_uint_big(int_ty, int_min(signed, int_width) as u128);
-    let s0 = bx.select(less_or_nan, int_min, fptosui_result);
-    let s1 = bx.select(greater, int_max, s0);
-
-    // Step 3: NaN replacement.
-    // For unsigned types, the above step already yielded int_ty::MIN == 0 if x is NaN.
-    // Therefore we only need to execute this step for signed integer types.
-    if signed {
-        // LLVM has no isNaN predicate, so we use (x == x) instead
-        let zero = bx.cx().const_uint(int_ty, 0);
-        let cmp = bx.fcmp(RealPredicate::RealOEQ, x, x);
-        bx.select(cmp, s1, zero)
+    let zero = bx.cx().const_uint(int_ty, 0);
+
+    // The codegen here differs quite a bit depending on whether our builder's
+    // `fptosi` and `fptoui` instructions may trap for out-of-bounds values. If
+    // they don't trap then we can start doing everything inline with a
+    // `select` instruction because it's ok to execute `fptosi` and `fptoui`
+    // even if we don't use the results.
+    if !bx.fptosui_may_trap(x, int_ty) {
+        // Step 1 ...
+        let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) };
+        let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min);
+        let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max);
+
+        // Step 2: We use two comparisons and two selects, with %s1 being the
+        // result:
+        //     %less_or_nan = fcmp ult %x, %f_min
+        //     %greater = fcmp olt %x, %f_max
+        //     %s0 = select %less_or_nan, int_ty::MIN, %fptosi_result
+        //     %s1 = select %greater, int_ty::MAX, %s0
+        // Note that %less_or_nan uses an *unordered* comparison. This
+        // comparison is true if the operands are not comparable (i.e., if x is
+        // NaN). The unordered comparison ensures that s1 becomes int_ty::MIN if
+        // x is NaN.
+        //
+        // Performance note: Unordered comparison can be lowered to a "flipped"
+        // comparison and a negation, and the negation can be merged into the
+        // select. Therefore, it not necessarily any more expensive than a
+        // ordered ("normal") comparison. Whether these optimizations will be
+        // performed is ultimately up to the backend, but at least x86 does
+        // perform them.
+        let s0 = bx.select(less_or_nan, int_min, fptosui_result);
+        let s1 = bx.select(greater, int_max, s0);
+
+        // Step 3: NaN replacement.
+        // For unsigned types, the above step already yielded int_ty::MIN == 0 if x is NaN.
+        // Therefore we only need to execute this step for signed integer types.
+        if signed {
+            // LLVM has no isNaN predicate, so we use (x == x) instead
+            let cmp = bx.fcmp(RealPredicate::RealOEQ, x, x);
+            bx.select(cmp, s1, zero)
+        } else {
+            s1
+        }
     } else {
-        s1
+        // In this case we cannot execute `fptosi` or `fptoui` and then later
+        // discard the result. The builder is telling us that these instructions
+        // will trap on out-of-bounds values, so we need to use basic blocks and
+        // control flow to avoid executing the `fptosi` and `fptoui`
+        // instructions.
+        //
+        // The general idea of what we're constructing here is, for f64 -> i32:
+        //
+        //      ;; block so far... %0 is the argument
+        //      %result = alloca i32, align 4
+        //      %inbound_lower = fcmp oge double %0, 0xC1E0000000000000
+        //      %inbound_upper = fcmp ole double %0, 0x41DFFFFFFFC00000
+        //      ;; match (inbound_lower, inbound_upper) {
+        //      ;;     (true, true) => %0 can be converted without trapping
+        //      ;;     (false, false) => %0 is a NaN
+        //      ;;     (true, false) => %0 is too large
+        //      ;;     (false, true) => %0 is too small
+        //      ;; }
+        //      ;;
+        //      ;; The (true, true) check, go to %convert if so.
+        //      %inbounds = and i1 %inbound_lower, %inbound_upper
+        //      br i1 %inbounds, label %convert, label %specialcase
+        //
+        //  convert:
+        //      %cvt = call i32 @llvm.wasm.trunc.signed.i32.f64(double %0)
+        //      store i32 %cvt, i32* %result, align 4
+        //      br label %done
+        //
+        //  specialcase:
+        //      ;; Handle the cases where the number is NaN, too large or too small
+        //
+        //      ;; Either (true, false) or (false, true)
+        //      %is_not_nan = or i1 %inbound_lower, %inbound_upper
+        //      ;; Figure out which saturated value we are interested in if not `NaN`
+        //      %saturated = select i1 %inbound_lower, i32 2147483647, i32 -2147483648
+        //      ;; Figure out between saturated and NaN representations
+        //      %result_nan = select i1 %is_not_nan, i32 %saturated, i32 0
+        //      store i32 %result_nan, i32* %result, align 4
+        //      br label %done
+        //
+        //  done:
+        //      %r = load i32, i32* %result, align 4
+        //      ;; ...
+        let done = bx.build_sibling_block("float_cast_done");
+        let mut convert = bx.build_sibling_block("float_cast_convert");
+        let mut specialcase = bx.build_sibling_block("float_cast_specialcase");
+
+        let result = PlaceRef::alloca(bx, int_layout);
+        result.storage_live(bx);
+
+        // Use control flow to figure out whether we can execute `fptosi` in a
+        // basic block, or whether we go to a different basic block to implement
+        // the saturating logic.
+        let inbound_lower = bx.fcmp(RealPredicate::RealOGE, x, f_min);
+        let inbound_upper = bx.fcmp(RealPredicate::RealOLE, x, f_max);
+        let inbounds = bx.and(inbound_lower, inbound_upper);
+        bx.cond_br(inbounds, convert.llbb(), specialcase.llbb());
+
+        // Translation of the `convert` basic block
+        let cvt = if signed { convert.fptosi(x, int_ty) } else { convert.fptoui(x, int_ty) };
+        convert.store(cvt, result.llval, result.align);
+        convert.br(done.llbb());
+
+        // Translation of the `specialcase` basic block. Note that like above
+        // we try to be a bit clever here for unsigned conversions. In those
+        // cases the `int_min` is zero so we don't need two select instructions,
+        // just one to choose whether we need `int_max` or not. If
+        // `inbound_lower` is true then we're guaranteed to not be `NaN` and
+        // since we're greater than zero we must be saturating to `int_max`. If
+        // `inbound_lower` is false then we're either NaN or less than zero, so
+        // we saturate to zero.
+        let result_nan = if signed {
+            let is_not_nan = specialcase.or(inbound_lower, inbound_upper);
+            let saturated = specialcase.select(inbound_lower, int_max, int_min);
+            specialcase.select(is_not_nan, saturated, zero)
+        } else {
+            specialcase.select(inbound_lower, int_max, int_min)
+        };
+        specialcase.store(result_nan, result.llval, result.align);
+        specialcase.br(done.llbb());
+
+        // Translation of the `done` basic block, positioning ourselves to
+        // continue from that point as well.
+        *bx = done;
+        let ret = bx.load(result.llval, result.align);
+        result.storage_dead(bx);
+        ret
     }
 }
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index 65eb70e173e..4e11ef5fd6e 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -160,6 +160,7 @@ pub trait BuilderMethods<'a, 'tcx>:
     fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
     fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option<Self::Value>;
     fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option<Self::Value>;
+    fn fptosui_may_trap(&self, val: Self::Value, dest_ty: Self::Type) -> bool;
     fn fptoui(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
     fn fptosi(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
     fn uitofp(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
diff --git a/src/librustc_codegen_ssa/traits/coverageinfo.rs b/src/librustc_codegen_ssa/traits/coverageinfo.rs
index db1d86c974e..2b5878f46bc 100644
--- a/src/librustc_codegen_ssa/traits/coverageinfo.rs
+++ b/src/librustc_codegen_ssa/traits/coverageinfo.rs
@@ -1,5 +1,5 @@
 use super::BackendTypes;
-use crate::coverageinfo::ExprKind;
+use crate::coverageinfo::{ExprKind, Region};
 use rustc_middle::ty::Instance;
 
 pub trait CoverageInfoMethods: BackendTypes {
@@ -12,8 +12,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
         instance: Instance<'tcx>,
         function_source_hash: u64,
         index: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        region: Region<'tcx>,
     );
 
     fn add_counter_expression_region(
@@ -23,14 +22,8 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
         lhs: u32,
         op: ExprKind,
         rhs: u32,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
+        region: Region<'tcx>,
     );
 
-    fn add_unreachable_region(
-        &mut self,
-        instance: Instance<'tcx>,
-        start_byte_pos: u32,
-        end_byte_pos: u32,
-    );
+    fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: Region<'tcx>);
 }
diff --git a/src/librustc_error_codes/error_codes/E0733.md b/src/librustc_error_codes/error_codes/E0733.md
index 0bda7a7d682..051b75148e5 100644
--- a/src/librustc_error_codes/error_codes/E0733.md
+++ b/src/librustc_error_codes/error_codes/E0733.md
@@ -1,4 +1,6 @@
-Recursion in an `async fn` requires boxing. For example, this will not compile:
+An [`async`] function used recursion without boxing.
+
+Erroneous code example:
 
 ```edition2018,compile_fail,E0733
 async fn foo(n: usize) {
@@ -8,8 +10,8 @@ async fn foo(n: usize) {
 }
 ```
 
-To achieve async recursion, the `async fn` needs to be desugared
-such that the `Future` is explicit in the return type:
+To perform async recursion, the `async fn` needs to be desugared such that the
+`Future` is explicit in the return type:
 
 ```edition2018,compile_fail,E0720
 use std::future::Future;
@@ -36,5 +38,7 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
 }
 ```
 
-The `Box<...>` ensures that the result is of known size,
-and the pin is required to keep it in the same place in memory.
+The `Box<...>` ensures that the result is of known size, and the pin is
+required to keep it in the same place in memory.
+
+[`async`]: https://doc.rust-lang.org/std/keyword.async.html
diff --git a/src/librustc_error_codes/error_codes/E0744.md b/src/librustc_error_codes/error_codes/E0744.md
index 56b947a8282..14cff3613e0 100644
--- a/src/librustc_error_codes/error_codes/E0744.md
+++ b/src/librustc_error_codes/error_codes/E0744.md
@@ -1,7 +1,6 @@
-Control-flow expressions are not allowed inside a const context.
+A control-flow expression was used inside a const context.
 
-At the moment, `if` and `match`, as well as the looping constructs `for`,
-`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`.
+Erroneous code example:
 
 ```compile_fail,E0744
 const _: i32 = {
@@ -13,6 +12,9 @@ const _: i32 = {
 };
 ```
 
+At the moment, `if` and `match`, as well as the looping constructs `for`,
+`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`.
+
 This will be allowed at some point in the future, but the implementation is not
 yet complete. See the tracking issue for [conditionals] or [loops] in a const
 context for the current status.
diff --git a/src/librustc_error_codes/error_codes/E0745.md b/src/librustc_error_codes/error_codes/E0745.md
index 6595691ce78..23ee7af30f4 100644
--- a/src/librustc_error_codes/error_codes/E0745.md
+++ b/src/librustc_error_codes/error_codes/E0745.md
@@ -1,20 +1,23 @@
-Cannot take address of temporary value.
+The address of temporary value was taken.
 
 Erroneous code example:
 
 ```compile_fail,E0745
 # #![feature(raw_ref_op)]
 fn temp_address() {
-    let ptr = &raw const 2;   // ERROR
+    let ptr = &raw const 2; // error!
 }
 ```
 
-To avoid the error, first bind the temporary to a named local variable.
+In this example, `2` is destroyed right after the assignment, which means that
+`ptr` now points to an unavailable location.
+
+To avoid this error, first bind the temporary to a named local variable:
 
 ```
 # #![feature(raw_ref_op)]
 fn temp_address() {
     let val = 2;
-    let ptr = &raw const val;
+    let ptr = &raw const val; // ok!
 }
 ```
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 1362a1155bc..cca8b47c781 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -362,7 +362,7 @@ pub trait Emitter {
                         format!(
                             "in this expansion of `{}`{}",
                             trace.kind.descr(),
-                            if macro_backtrace.len() > 2 {
+                            if macro_backtrace.len() > 1 {
                                 // if macro_backtrace.len() == 1 it'll be
                                 // pointed at by "in this macro invocation"
                                 format!(" (#{})", i + 1)
@@ -393,7 +393,7 @@ pub trait Emitter {
                         trace.call_site,
                         format!(
                             "in this macro invocation{}",
-                            if macro_backtrace.len() > 2 && always_backtrace {
+                            if macro_backtrace.len() > 1 && always_backtrace {
                                 // only specify order when the macro
                                 // backtrace is multiple levels deep
                                 format!(" (#{})", i + 1)
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index e4c0fcaa298..0cc340c205a 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -1644,14 +1644,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         }
 
         if let Some(list) = at.meta_item_list() {
-            if !list.iter().any(|it| it.check_name(sym::include)) {
+            if !list.iter().any(|it| it.has_name(sym::include)) {
                 return noop_visit_attribute(at, self);
             }
 
             let mut items = vec![];
 
             for mut it in list {
-                if !it.check_name(sym::include) {
+                if !it.has_name(sym::include) {
                     items.push({
                         noop_visit_meta_list_item(&mut it, self);
                         it
diff --git a/src/librustc_expand/mbe.rs b/src/librustc_expand/mbe.rs
index a728261d711..6f2daaa81c0 100644
--- a/src/librustc_expand/mbe.rs
+++ b/src/librustc_expand/mbe.rs
@@ -9,7 +9,7 @@ crate mod macro_rules;
 crate mod quoted;
 crate mod transcribe;
 
-use rustc_ast::token::{self, Token, TokenKind};
+use rustc_ast::token::{self, NonterminalKind, Token, TokenKind};
 use rustc_ast::tokenstream::DelimSpan;
 
 use rustc_span::symbol::Ident;
@@ -84,7 +84,7 @@ enum TokenTree {
     /// e.g., `$var`
     MetaVar(Span, Ident),
     /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros.
-    MetaVarDecl(Span, Ident /* name to bind */, Ident /* kind of nonterminal */),
+    MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>),
 }
 
 impl TokenTree {
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs
index 3c15a81c67f..d2fe7fe10a8 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/src/librustc_expand/mbe/macro_parser.rs
@@ -76,15 +76,11 @@ use TokenTreeOrTokenTreeSlice::*;
 
 use crate::mbe::{self, TokenTree};
 
-use rustc_ast::ptr::P;
 use rustc_ast::token::{self, DocComment, Nonterminal, Token};
-use rustc_ast_pretty::pprust;
-use rustc_parse::parser::{FollowedByType, Parser, PathStyle};
+use rustc_parse::parser::Parser;
 use rustc_session::parse::ParseSess;
-use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol};
+use rustc_span::symbol::MacroRulesNormalizedIdent;
 
-use rustc_errors::PResult;
-use rustc_span::Span;
 use smallvec::{smallvec, SmallVec};
 
 use rustc_data_structures::fx::FxHashMap;
@@ -382,7 +378,7 @@ fn nameize<I: Iterator<Item = NamedMatch>>(
                     n_rec(sess, next_m, res.by_ref(), ret_val)?;
                 }
             }
-            TokenTree::MetaVarDecl(span, _, id) if id.name == kw::Invalid => {
+            TokenTree::MetaVarDecl(span, _, None) => {
                 if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
                     return Err((span, "missing fragment specifier".to_string()));
                 }
@@ -565,7 +561,7 @@ fn inner_parse_loop<'root, 'tt>(
                 }
 
                 // We need to match a metavar (but the identifier is invalid)... this is an error
-                TokenTree::MetaVarDecl(span, _, id) if id.name == kw::Invalid => {
+                TokenTree::MetaVarDecl(span, _, None) => {
                     if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
                         return Error(span, "missing fragment specifier".to_string());
                     }
@@ -573,10 +569,10 @@ fn inner_parse_loop<'root, 'tt>(
 
                 // We need to match a metavar with a valid ident... call out to the black-box
                 // parser by adding an item to `bb_items`.
-                TokenTree::MetaVarDecl(_, _, id) => {
+                TokenTree::MetaVarDecl(_, _, Some(kind)) => {
                     // Built-in nonterminals never start with these tokens,
                     // so we can eliminate them from consideration.
-                    if may_begin_with(token, id.name) {
+                    if Parser::nonterminal_may_begin_with(kind, token) {
                         bb_items.push(item);
                     }
                 }
@@ -706,7 +702,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
             let nts = bb_items
                 .iter()
                 .map(|item| match item.top_elts.get_tt(item.idx) {
-                    TokenTree::MetaVarDecl(_, bind, name) => format!("{} ('{}')", name, bind),
+                    TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind),
                     _ => panic!(),
                 })
                 .collect::<Vec<String>>()
@@ -736,10 +732,17 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
             assert_eq!(bb_items.len(), 1);
 
             let mut item = bb_items.pop().unwrap();
-            if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) {
+            if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) {
                 let match_cur = item.match_cur;
-                let nt = match parse_nt(parser.to_mut(), span, ident.name) {
-                    Err(()) => return ErrorReported,
+                let nt = match parser.to_mut().parse_nonterminal(kind) {
+                    Err(mut err) => {
+                        err.span_label(
+                            span,
+                            format!("while parsing argument for this `{}` macro fragment", kind),
+                        )
+                        .emit();
+                        return ErrorReported;
+                    }
                     Ok(nt) => nt,
                 };
                 item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
@@ -754,178 +757,3 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
         assert!(!cur_items.is_empty());
     }
 }
-
-/// The token is an identifier, but not `_`.
-/// We prohibit passing `_` to macros expecting `ident` for now.
-fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> {
-    token.ident().filter(|(ident, _)| ident.name != kw::Underscore)
-}
-
-/// Checks whether a non-terminal may begin with a particular token.
-///
-/// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
-/// token. Be conservative (return true) if not sure.
-fn may_begin_with(token: &Token, name: Symbol) -> bool {
-    /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
-    fn may_be_ident(nt: &token::Nonterminal) -> bool {
-        match *nt {
-            token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => false,
-            _ => true,
-        }
-    }
-
-    match name {
-        sym::expr => {
-            token.can_begin_expr()
-            // This exception is here for backwards compatibility.
-            && !token.is_keyword(kw::Let)
-        }
-        sym::ty => token.can_begin_type(),
-        sym::ident => get_macro_ident(token).is_some(),
-        sym::literal => token.can_begin_literal_maybe_minus(),
-        sym::vis => match token.kind {
-            // The follow-set of :vis + "priv" keyword + interpolated
-            token::Comma | token::Ident(..) | token::Interpolated(..) => true,
-            _ => token.can_begin_type(),
-        },
-        sym::block => match token.kind {
-            token::OpenDelim(token::Brace) => true,
-            token::Interpolated(ref nt) => match **nt {
-                token::NtItem(_)
-                | token::NtPat(_)
-                | token::NtTy(_)
-                | token::NtIdent(..)
-                | token::NtMeta(_)
-                | token::NtPath(_)
-                | token::NtVis(_) => false, // none of these may start with '{'.
-                _ => true,
-            },
-            _ => false,
-        },
-        sym::path | sym::meta => match token.kind {
-            token::ModSep | token::Ident(..) => true,
-            token::Interpolated(ref nt) => match **nt {
-                token::NtPath(_) | token::NtMeta(_) => true,
-                _ => may_be_ident(&nt),
-            },
-            _ => false,
-        },
-        sym::pat => match token.kind {
-            token::Ident(..) |               // box, ref, mut, and other identifiers (can stricten)
-            token::OpenDelim(token::Paren) |    // tuple pattern
-            token::OpenDelim(token::Bracket) |  // slice pattern
-            token::BinOp(token::And) |          // reference
-            token::BinOp(token::Minus) |        // negative literal
-            token::AndAnd |                     // double reference
-            token::Literal(..) |                // literal
-            token::DotDot |                     // range pattern (future compat)
-            token::DotDotDot |                  // range pattern (future compat)
-            token::ModSep |                     // path
-            token::Lt |                         // path (UFCS constant)
-            token::BinOp(token::Shl) => true,   // path (double UFCS)
-            token::Interpolated(ref nt) => may_be_ident(nt),
-            _ => false,
-        },
-        sym::lifetime => match token.kind {
-            token::Lifetime(_) => true,
-            token::Interpolated(ref nt) => match **nt {
-                token::NtLifetime(_) | token::NtTT(_) => true,
-                _ => false,
-            },
-            _ => false,
-        },
-        _ => match token.kind {
-            token::CloseDelim(_) => false,
-            _ => true,
-        },
-    }
-}
-
-/// A call to the "black-box" parser to parse some Rust non-terminal.
-///
-/// # Parameters
-///
-/// - `p`: the "black-box" parser to use
-/// - `sp`: the `Span` we want to parse
-/// - `name`: the name of the metavar _matcher_ we want to match (e.g., `tt`, `ident`, `block`,
-///   etc...)
-///
-/// # Returns
-///
-/// The parsed non-terminal.
-fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Result<Nonterminal, ()> {
-    // FIXME(Centril): Consider moving this to `parser.rs` to make
-    // the visibilities of the methods used below `pub(super)` at most.
-    if name == sym::tt {
-        return Ok(token::NtTT(p.parse_token_tree()));
-    }
-    parse_nt_inner(p, sp, name).map_err(|mut err| {
-        err.span_label(sp, format!("while parsing argument for this `{}` macro fragment", name))
-            .emit()
-    })
-}
-
-fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> {
-    // Any `Nonterminal` which stores its tokens (currently `NtItem` and `NtExpr`)
-    // needs to have them force-captured here.
-    // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro,
-    // which requires having captured tokens available. Since we cannot determine
-    // in advance whether or not a proc-macro will be (transitively) invoked,
-    // we always capture tokens for any `Nonterminal` which needs them.
-    Ok(match name {
-        sym::item => match p.collect_tokens(|this| this.parse_item())? {
-            (Some(mut item), tokens) => {
-                // If we captured tokens during parsing (due to outer attributes),
-                // use those.
-                if item.tokens.is_none() {
-                    item.tokens = Some(tokens);
-                }
-                token::NtItem(item)
-            }
-            (None, _) => return Err(p.struct_span_err(p.token.span, "expected an item keyword")),
-        },
-        sym::block => token::NtBlock(p.parse_block()?),
-        sym::stmt => match p.parse_stmt()? {
-            Some(s) => token::NtStmt(s),
-            None => return Err(p.struct_span_err(p.token.span, "expected a statement")),
-        },
-        sym::pat => token::NtPat(p.parse_pat(None)?),
-        sym::expr => {
-            let (mut expr, tokens) = p.collect_tokens(|this| this.parse_expr())?;
-            // If we captured tokens during parsing (due to outer attributes),
-            // use those.
-            if expr.tokens.is_none() {
-                expr.tokens = Some(tokens);
-            }
-            token::NtExpr(expr)
-        }
-        sym::literal => token::NtLiteral(p.parse_literal_maybe_minus()?),
-        sym::ty => token::NtTy(p.parse_ty()?),
-        // this could be handled like a token, since it is one
-        sym::ident => {
-            if let Some((ident, is_raw)) = get_macro_ident(&p.token) {
-                p.bump();
-                token::NtIdent(ident, is_raw)
-            } else {
-                let token_str = pprust::token_to_string(&p.token);
-                let msg = &format!("expected ident, found {}", &token_str);
-                return Err(p.struct_span_err(p.token.span, msg));
-            }
-        }
-        sym::path => token::NtPath(p.parse_path(PathStyle::Type)?),
-        sym::meta => token::NtMeta(P(p.parse_attr_item()?)),
-        sym::vis => token::NtVis(p.parse_visibility(FollowedByType::Yes)?),
-        sym::lifetime => {
-            if p.check_lifetime() {
-                token::NtLifetime(p.expect_lifetime().ident)
-            } else {
-                let token_str = pprust::token_to_string(&p.token);
-                let msg = &format!("expected a lifetime, found `{}`", &token_str);
-                return Err(p.struct_span_err(p.token.span, msg));
-            }
-        }
-        // this is not supposed to happen, since it has been checked
-        // when compiling the macro.
-        _ => p.span_bug(sp, "invalid fragment specifier"),
-    })
-}
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs
index 36b323df697..74d4023b410 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/src/librustc_expand/mbe/macro_rules.rs
@@ -9,7 +9,7 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq};
 use crate::mbe::transcribe::transcribe;
 
 use rustc_ast::ast;
-use rustc_ast::token::{self, NtTT, Token, TokenKind::*};
+use rustc_ast::token::{self, NonterminalKind, NtTT, Token, TokenKind::*};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
 use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, TransparencyError};
@@ -21,7 +21,7 @@ use rustc_parse::parser::Parser;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::Transparency;
-use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent};
 use rustc_span::Span;
 
 use log::debug;
@@ -29,10 +29,6 @@ use std::borrow::Cow;
 use std::collections::hash_map::Entry;
 use std::{mem, slice};
 
-const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
-                                        `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
-                                        `literal`, `path`, `meta`, `tt`, `item` and `vis`";
-
 crate struct ParserAnyMacro<'a> {
     parser: Parser<'a>,
 
@@ -403,7 +399,7 @@ pub fn compile_declarative_macro(
     let diag = &sess.span_diagnostic;
     let lhs_nm = Ident::new(sym::lhs, def.span);
     let rhs_nm = Ident::new(sym::rhs, def.span);
-    let tt_spec = Ident::new(sym::tt, def.span);
+    let tt_spec = Some(NonterminalKind::TT);
 
     // Parse the macro_rules! invocation
     let (macro_rules, body) = match &def.kind {
@@ -571,7 +567,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
             TokenTree::Sequence(span, ref seq) => {
                 if seq.separator.is_none()
                     && seq.tts.iter().all(|seq_tt| match *seq_tt {
-                        TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis,
+                        TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
                         TokenTree::Sequence(_, ref sub_seq) => {
                             sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
                                 || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
@@ -890,21 +886,7 @@ fn check_matcher_core(
         // of NT tokens that might end the sequence `... token`.
         match *token {
             TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => {
-                let can_be_followed_by_any;
-                if let Err(bad_frag) = has_legal_fragment_specifier(sess, features, attrs, token) {
-                    let msg = format!("invalid fragment specifier `{}`", bad_frag);
-                    sess.span_diagnostic
-                        .struct_span_err(token.span(), &msg)
-                        .help(VALID_FRAGMENT_NAMES_MSG)
-                        .emit();
-                    // (This eliminates false positives and duplicates
-                    // from error messages.)
-                    can_be_followed_by_any = true;
-                } else {
-                    can_be_followed_by_any = token_can_be_followed_by_any(token);
-                }
-
-                if can_be_followed_by_any {
+                if token_can_be_followed_by_any(token) {
                     // don't need to track tokens that work with any,
                     last.replace_with_irrelevant();
                     // ... and don't need to check tokens that can be
@@ -967,19 +949,10 @@ fn check_matcher_core(
 
         // Now `last` holds the complete set of NT tokens that could
         // end the sequence before SUFFIX. Check that every one works with `suffix`.
-        'each_last: for token in &last.tokens {
-            if let TokenTree::MetaVarDecl(_, name, frag_spec) = *token {
+        for token in &last.tokens {
+            if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token {
                 for next_token in &suffix_first.tokens {
-                    match is_in_follow(next_token, frag_spec.name) {
-                        IsInFollow::Invalid(msg, help) => {
-                            sess.span_diagnostic
-                                .struct_span_err(next_token.span(), &msg)
-                                .help(help)
-                                .emit();
-                            // don't bother reporting every source of
-                            // conflict for a particular element of `last`.
-                            continue 'each_last;
-                        }
+                    match is_in_follow(next_token, kind) {
                         IsInFollow::Yes => {}
                         IsInFollow::No(possible) => {
                             let may_be = if last.tokens.len() == 1 && suffix_first.tokens.len() == 1
@@ -996,22 +969,19 @@ fn check_matcher_core(
                                     "`${name}:{frag}` {may_be} followed by `{next}`, which \
                                      is not allowed for `{frag}` fragments",
                                     name = name,
-                                    frag = frag_spec,
+                                    frag = kind,
                                     next = quoted_tt_to_string(next_token),
                                     may_be = may_be
                                 ),
                             );
-                            err.span_label(
-                                sp,
-                                format!("not allowed after `{}` fragments", frag_spec),
-                            );
+                            err.span_label(sp, format!("not allowed after `{}` fragments", kind));
                             let msg = "allowed there are: ";
                             match possible {
                                 &[] => {}
                                 &[t] => {
                                     err.note(&format!(
                                         "only {} is allowed after `{}` fragments",
-                                        t, frag_spec,
+                                        t, kind,
                                     ));
                                 }
                                 ts => {
@@ -1038,8 +1008,8 @@ fn check_matcher_core(
 }
 
 fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
-    if let mbe::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok {
-        frag_can_be_followed_by_any(frag_spec.name)
+    if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok {
+        frag_can_be_followed_by_any(kind)
     } else {
         // (Non NT's can always be followed by anything in matchers.)
         true
@@ -1054,26 +1024,23 @@ fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
 /// specifier which consumes at most one token tree can be followed by
 /// a fragment specifier (indeed, these fragments can be followed by
 /// ANYTHING without fear of future compatibility hazards).
-fn frag_can_be_followed_by_any(frag: Symbol) -> bool {
-    match frag {
-        sym::item     | // always terminated by `}` or `;`
-        sym::block    | // exactly one token tree
-        sym::ident    | // exactly one token tree
-        sym::literal  | // exactly one token tree
-        sym::meta     | // exactly one token tree
-        sym::lifetime | // exactly one token tree
-        sym::tt =>   // exactly one token tree
-            true,
-
-        _ =>
-            false,
+fn frag_can_be_followed_by_any(kind: NonterminalKind) -> bool {
+    match kind {
+        NonterminalKind::Item           // always terminated by `}` or `;`
+        | NonterminalKind::Block        // exactly one token tree
+        | NonterminalKind::Ident        // exactly one token tree
+        | NonterminalKind::Literal      // exactly one token tree
+        | NonterminalKind::Meta         // exactly one token tree
+        | NonterminalKind::Lifetime     // exactly one token tree
+        | NonterminalKind::TT => true,  // exactly one token tree
+
+        _ => false,
     }
 }
 
 enum IsInFollow {
     Yes,
     No(&'static [&'static str]),
-    Invalid(String, &'static str),
 }
 
 /// Returns `true` if `frag` can legally be followed by the token `tok`. For
@@ -1084,7 +1051,7 @@ enum IsInFollow {
 /// break macros that were relying on that binary operator as a
 /// separator.
 // when changing this do not forget to update doc/book/macros.md!
-fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
+fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
     use mbe::TokenTree;
 
     if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok {
@@ -1092,18 +1059,18 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
         // iow, we always require that `(` and `)` match, etc.
         IsInFollow::Yes
     } else {
-        match frag {
-            sym::item => {
+        match kind {
+            NonterminalKind::Item => {
                 // since items *must* be followed by either a `;` or a `}`, we can
                 // accept anything after them
                 IsInFollow::Yes
             }
-            sym::block => {
+            NonterminalKind::Block => {
                 // anything can follow block, the braces provide an easy boundary to
                 // maintain
                 IsInFollow::Yes
             }
-            sym::stmt | sym::expr => {
+            NonterminalKind::Stmt | NonterminalKind::Expr => {
                 const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
                 match tok {
                     TokenTree::Token(token) => match token.kind {
@@ -1113,7 +1080,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            sym::pat => {
+            NonterminalKind::Pat => {
                 const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
                 match tok {
                     TokenTree::Token(token) => match token.kind {
@@ -1124,7 +1091,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            sym::path | sym::ty => {
+            NonterminalKind::Path | NonterminalKind::Ty => {
                 const TOKENS: &[&str] = &[
                     "`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`",
                     "`where`",
@@ -1146,26 +1113,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
                         }
                         _ => IsInFollow::No(TOKENS),
                     },
-                    TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::block => {
-                        IsInFollow::Yes
-                    }
+                    TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes,
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            sym::ident | sym::lifetime => {
+            NonterminalKind::Ident | NonterminalKind::Lifetime => {
                 // being a single token, idents and lifetimes are harmless
                 IsInFollow::Yes
             }
-            sym::literal => {
+            NonterminalKind::Literal => {
                 // literals may be of a single token, or two tokens (negative numbers)
                 IsInFollow::Yes
             }
-            sym::meta | sym::tt => {
+            NonterminalKind::Meta | NonterminalKind::TT => {
                 // being either a single token or a delimited sequence, tt is
                 // harmless
                 IsInFollow::Yes
             }
-            sym::vis => {
+            NonterminalKind::Vis => {
                 // Explicitly disallow `priv`, on the off chance it comes back.
                 const TOKENS: &[&str] = &["`,`", "an ident", "a type"];
                 match tok {
@@ -1180,78 +1145,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
                             }
                         }
                     },
-                    TokenTree::MetaVarDecl(_, _, frag)
-                        if frag.name == sym::ident
-                            || frag.name == sym::ty
-                            || frag.name == sym::path =>
-                    {
-                        IsInFollow::Yes
-                    }
+                    TokenTree::MetaVarDecl(
+                        _,
+                        _,
+                        Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path),
+                    ) => IsInFollow::Yes,
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            kw::Invalid => IsInFollow::Yes,
-            _ => IsInFollow::Invalid(
-                format!("invalid fragment specifier `{}`", frag),
-                VALID_FRAGMENT_NAMES_MSG,
-            ),
         }
     }
 }
 
-fn has_legal_fragment_specifier(
-    sess: &ParseSess,
-    features: &Features,
-    attrs: &[ast::Attribute],
-    tok: &mbe::TokenTree,
-) -> Result<(), String> {
-    debug!("has_legal_fragment_specifier({:?})", tok);
-    if let mbe::TokenTree::MetaVarDecl(_, _, ref frag_spec) = *tok {
-        let frag_span = tok.span();
-        if !is_legal_fragment_specifier(sess, features, attrs, frag_spec.name, frag_span) {
-            return Err(frag_spec.to_string());
-        }
-    }
-    Ok(())
-}
-
-fn is_legal_fragment_specifier(
-    _sess: &ParseSess,
-    _features: &Features,
-    _attrs: &[ast::Attribute],
-    frag_name: Symbol,
-    _frag_span: Span,
-) -> bool {
-    /*
-     * If new fragment specifiers are invented in nightly, `_sess`,
-     * `_features`, `_attrs`, and `_frag_span` will be useful here
-     * for checking against feature gates. See past versions of
-     * this function.
-     */
-    match frag_name {
-        sym::item
-        | sym::block
-        | sym::stmt
-        | sym::expr
-        | sym::pat
-        | sym::lifetime
-        | sym::path
-        | sym::ty
-        | sym::ident
-        | sym::meta
-        | sym::tt
-        | sym::vis
-        | sym::literal
-        | kw::Invalid => true,
-        _ => false,
-    }
-}
-
 fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
     match *tt {
         mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token),
         mbe::TokenTree::MetaVar(_, name) => format!("${}", name),
-        mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind),
+        mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind),
+        mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name),
         _ => panic!(
             "unexpected mbe::TokenTree::{{Sequence or Delimited}} \
              in follow set checker"
diff --git a/src/librustc_expand/mbe/quoted.rs b/src/librustc_expand/mbe/quoted.rs
index 09306f26ee0..774cc84afde 100644
--- a/src/librustc_expand/mbe/quoted.rs
+++ b/src/librustc_expand/mbe/quoted.rs
@@ -12,6 +12,10 @@ use rustc_span::Span;
 
 use rustc_data_structures::sync::Lrc;
 
+const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
+                                        `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
+                                        `literal`, `path`, `meta`, `tt`, `item` and `vis`";
+
 /// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
 /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
 /// collection of `TokenTree` for use in parsing a macro.
@@ -55,9 +59,21 @@ pub(super) fn parse(
                     Some(tokenstream::TokenTree::Token(Token { kind: token::Colon, span })) => {
                         match trees.next() {
                             Some(tokenstream::TokenTree::Token(token)) => match token.ident() {
-                                Some((kind, _)) => {
+                                Some((frag, _)) => {
                                     let span = token.span.with_lo(start_sp.lo());
-                                    result.push(TokenTree::MetaVarDecl(span, ident, kind));
+                                    let kind = token::NonterminalKind::from_symbol(frag.name)
+                                        .unwrap_or_else(|| {
+                                            let msg = format!(
+                                                "invalid fragment specifier `{}`",
+                                                frag.name
+                                            );
+                                            sess.span_diagnostic
+                                                .struct_span_err(span, &msg)
+                                                .help(VALID_FRAGMENT_NAMES_MSG)
+                                                .emit();
+                                            token::NonterminalKind::Ident
+                                        });
+                                    result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
                                     continue;
                                 }
                                 _ => token.span,
@@ -71,7 +87,7 @@ pub(super) fn parse(
                     // Macros loaded from other crates have dummy node ids.
                     sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id);
                 }
-                result.push(TokenTree::MetaVarDecl(span, ident, Ident::invalid()));
+                result.push(TokenTree::MetaVarDecl(span, ident, None));
             }
 
             // Not a metavar or no matchers allowed, so just return the tree
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index cd5da7a6768..d451d9a22a4 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -149,7 +149,7 @@ impl AssertModuleSource<'tcx> {
 
     fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-            if item.check_name(name) {
+            if item.has_name(name) {
                 if let Some(value) = item.value_str() {
                     return value;
                 } else {
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index d48810f1cf1..02f37f82352 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -231,7 +231,7 @@ impl DirtyCleanVisitor<'tcx> {
 
     fn labels(&self, attr: &Attribute) -> Option<Labels> {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-            if item.check_name(LABEL) {
+            if item.has_name(LABEL) {
                 let value = expect_associated_value(self.tcx, &item);
                 return Some(self.resolve_labels(&item, value));
             }
@@ -242,7 +242,7 @@ impl DirtyCleanVisitor<'tcx> {
     /// `except=` attribute value
     fn except(&self, attr: &Attribute) -> Labels {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-            if item.check_name(EXCEPT) {
+            if item.has_name(EXCEPT) {
                 let value = expect_associated_value(self.tcx, &item);
                 return self.resolve_labels(&item, value);
             }
@@ -474,15 +474,15 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
     debug!("check_config: config={:?}", config);
     let (mut cfg, mut except, mut label) = (None, false, false);
     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-        if item.check_name(CFG) {
+        if item.has_name(CFG) {
             let value = expect_associated_value(tcx, &item);
             debug!("check_config: searching for cfg {:?}", value);
             cfg = Some(config.contains(&(value, None)));
         }
-        if item.check_name(LABEL) {
+        if item.has_name(LABEL) {
             label = true;
         }
-        if item.check_name(EXCEPT) {
+        if item.has_name(EXCEPT) {
             except = true;
         }
     }
diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs
index b369be25218..e4b7c24a249 100644
--- a/src/librustc_index/bit_set.rs
+++ b/src/librustc_index/bit_set.rs
@@ -1034,6 +1034,30 @@ pub trait FiniteBitSetTy:
     fn checked_shr(self, rhs: u32) -> Option<Self>;
 }
 
+impl FiniteBitSetTy for u32 {
+    const DOMAIN_SIZE: u32 = 32;
+
+    const FILLED: Self = Self::MAX;
+    const EMPTY: Self = Self::MIN;
+
+    const ONE: Self = 1u32;
+    const ZERO: Self = 0u32;
+
+    fn checked_shl(self, rhs: u32) -> Option<Self> {
+        self.checked_shl(rhs)
+    }
+
+    fn checked_shr(self, rhs: u32) -> Option<Self> {
+        self.checked_shr(rhs)
+    }
+}
+
+impl std::fmt::Debug for FiniteBitSet<u32> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:032b}", self.0)
+    }
+}
+
 impl FiniteBitSetTy for u64 {
     const DOMAIN_SIZE: u32 = 64;
 
diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs
index 2dc803b9595..ea32a1ae5a5 100644
--- a/src/librustc_infer/infer/canonical/canonicalizer.rs
+++ b/src/librustc_infer/infer/canonical/canonicalizer.rs
@@ -199,8 +199,8 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse {
                 // rust-lang/rust#57464: `impl Trait` can leak local
                 // scopes (in manner violating typeck). Therefore, use
                 // `delay_span_bug` to allow type error over an ICE.
-                ty::tls::with_context(|c| {
-                    c.tcx.sess.delay_span_bug(
+                ty::tls::with(|tcx| {
+                    tcx.sess.delay_span_bug(
                         rustc_span::DUMMY_SP,
                         &format!("unexpected region in query response: `{:?}`", r),
                     );
diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs
index 5b4d91de3ca..133c4bf2db5 100644
--- a/src/librustc_infer/infer/combine.rs
+++ b/src/librustc_infer/infer/combine.rs
@@ -166,7 +166,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
                 return self.unify_const_variable(!a_is_expected, vid, a);
             }
             (ty::ConstKind::Unevaluated(..), _) if self.tcx.lazy_normalization() => {
-                // FIXME(#59490): Need to remove the leak check to accomodate
+                // FIXME(#59490): Need to remove the leak check to accommodate
                 // escaping bound variables here.
                 if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
                     relation.const_equate_obligation(a, b);
@@ -174,7 +174,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
                 return Ok(b);
             }
             (_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => {
-                // FIXME(#59490): Need to remove the leak check to accomodate
+                // FIXME(#59490): Need to remove the leak check to accommodate
                 // escaping bound variables here.
                 if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
                     relation.const_equate_obligation(a, b);
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 4fa6d9d2394..0125e0f48e8 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -195,7 +195,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             }
         }
         if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) {
-            // Provide a more targetted error code and description.
+            // Provide a more targeted error code and description.
             err.code(rustc_errors::error_code!(E0772));
             err.set_primary_message(&format!(
                 "{} has {} but calling `{}` introduces an implicit `'static` lifetime \
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index e50622a0053..ad30f5eda4d 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -17,7 +17,6 @@ use rustc_session::early_error;
 use rustc_session::lint;
 use rustc_session::parse::{CrateConfig, ParseSess};
 use rustc_session::{DiagnosticOutput, Session};
-use rustc_span::edition;
 use rustc_span::source_map::{FileLoader, FileName};
 use std::path::PathBuf;
 use std::result;
@@ -208,13 +207,3 @@ pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R
         || create_compiler_and_run(config, f),
     )
 }
-
-pub fn setup_callbacks_and_run_in_default_thread_pool_with_globals<R: Send>(
-    edition: edition::Edition,
-    f: impl FnOnce() -> R + Send,
-) -> R {
-    // the 1 here is duplicating code in config.opts.debugging_opts.threads
-    // which also defaults to 1; it ultimately doesn't matter as the default
-    // isn't threaded, and just ignores this parameter
-    util::setup_callbacks_and_run_in_thread_pool_with_globals(edition, 1, &None, f)
-}
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 125a020de37..3a562847d3e 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -752,7 +752,8 @@ impl<'tcx> QueryContext<'tcx> {
     where
         F: FnOnce(TyCtxt<'tcx>) -> R,
     {
-        ty::tls::enter_global(self.0, f)
+        let icx = ty::tls::ImplicitCtxt::new(self.0);
+        ty::tls::enter_context(&icx, |_| f(icx.tcx))
     }
 
     pub fn print_stats(&mut self) {
@@ -811,8 +812,9 @@ pub fn create_global_ctxt<'tcx>(
     });
 
     // Do some initialization of the DepGraph that can only be done with the tcx available.
-    ty::tls::enter_global(&gcx, |tcx| {
-        tcx.sess.time("dep_graph_tcx_init", || rustc_incremental::dep_graph_tcx_init(tcx));
+    let icx = ty::tls::ImplicitCtxt::new(&gcx);
+    ty::tls::enter_context(&icx, |_| {
+        icx.tcx.sess.time("dep_graph_tcx_init", || rustc_incremental::dep_graph_tcx_init(icx.tcx));
     });
 
     QueryContext(gcx)
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 5b648608b6b..bbb2f9d8b25 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -10,10 +10,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 #[cfg(parallel_compiler)]
 use rustc_data_structures::jobserver;
 use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::{Lock, Lrc};
+use rustc_data_structures::sync::Lrc;
 use rustc_errors::registry::Registry;
 use rustc_metadata::dynamic_lib::DynamicLibrary;
-use rustc_middle::ty;
 use rustc_resolve::{self, Resolver};
 use rustc_session as session;
 use rustc_session::config::{self, CrateType};
@@ -144,12 +143,10 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
 
     let main_handler = move || {
         rustc_ast::with_session_globals(edition, || {
-            ty::tls::GCX_PTR.set(&Lock::new(0), || {
-                if let Some(stderr) = stderr {
-                    io::set_panic(Some(box Sink(stderr.clone())));
-                }
-                f()
-            })
+            if let Some(stderr) = stderr {
+                io::set_panic(Some(box Sink(stderr.clone())));
+            }
+            f()
         })
     };
 
@@ -163,6 +160,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
     stderr: &Option<Arc<Mutex<Vec<u8>>>>,
     f: F,
 ) -> R {
+    use rustc_middle::ty;
     crate::callbacks::setup_callbacks();
 
     let mut config = rayon::ThreadPoolBuilder::new()
@@ -189,12 +187,10 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
                 let main_handler = move |thread: rayon::ThreadBuilder| {
                     rustc_ast::SESSION_GLOBALS.set(ast_session_globals, || {
                         rustc_span::SESSION_GLOBALS.set(span_session_globals, || {
-                            ty::tls::GCX_PTR.set(&Lock::new(0), || {
-                                if let Some(stderr) = stderr {
-                                    io::set_panic(Some(box Sink(stderr.clone())));
-                                }
-                                thread.run()
-                            })
+                            if let Some(stderr) = stderr {
+                                io::set_panic(Some(box Sink(stderr.clone())));
+                            }
+                            thread.run()
                         })
                     })
                 };
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index e32c8fbee68..6515708e115 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -330,7 +330,7 @@ fn has_doc(attr: &ast::Attribute) -> bool {
 
     if let Some(list) = attr.meta_item_list() {
         for meta in list {
-            if meta.check_name(sym::include) || meta.check_name(sym::hidden) {
+            if meta.has_name(sym::include) || meta.has_name(sym::hidden) {
                 return true;
             }
         }
diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs
index 84f5ea7bcda..31d30a264a5 100644
--- a/src/librustc_lint/context.rs
+++ b/src/librustc_lint/context.rs
@@ -573,7 +573,7 @@ pub trait LintContext: Sized {
                     }
                 }
                 BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
-                    stability::deprecation_suggestion(&mut db, suggestion, span)
+                    stability::deprecation_suggestion(&mut db, "macro", suggestion, span)
                 }
                 BuiltinLintDiagnostics::UnusedDocComment(span) => {
                     db.span_label(span, "rustdoc does not generate documentation for macro invocations");
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 8d8fb8c3c60..1e98ddbd7db 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -275,10 +275,26 @@ declare_lint_pass!(PathStatements => [PATH_STATEMENTS]);
 
 impl<'tcx> LateLintPass<'tcx> for PathStatements {
     fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
-        if let hir::StmtKind::Semi(ref expr) = s.kind {
+        if let hir::StmtKind::Semi(expr) = s.kind {
             if let hir::ExprKind::Path(_) = expr.kind {
                 cx.struct_span_lint(PATH_STATEMENTS, s.span, |lint| {
-                    lint.build("path statement with no effect").emit()
+                    let ty = cx.typeck_results().expr_ty(expr);
+                    if ty.needs_drop(cx.tcx, cx.param_env) {
+                        let mut lint = lint.build("path statement drops value");
+                        if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) {
+                            lint.span_suggestion(
+                                s.span,
+                                "use `drop` to clarify the intent",
+                                format!("drop({});", snippet),
+                                Applicability::MachineApplicable,
+                            );
+                        } else {
+                            lint.span_help(s.span, "use `drop` to clarify the intent");
+                        }
+                        lint.emit()
+                    } else {
+                        lint.build("path statement with no effect").emit()
+                    }
                 });
             }
         }
@@ -422,7 +438,7 @@ trait UnusedDelimLint {
         lhs_needs_parens
             || (followed_by_block
                 && match inner.kind {
-                    ExprKind::Ret(_) | ExprKind::Break(..) => true,
+                    ExprKind::Ret(_) | ExprKind::Break(..) | ExprKind::Yield(..) => true,
                     _ => parser::contains_exterior_struct_lit(&inner),
                 })
     }
@@ -520,7 +536,10 @@ trait UnusedDelimLint {
                 (cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right))
             }
 
-            While(ref cond, ref block, ..) => {
+            // Do not lint `unused_braces` in `while let` expressions.
+            While(ref cond, ref block, ..)
+                if !matches!(cond.kind, Let(_, _)) || Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX =>
+            {
                 let left = e.span.lo() + rustc_span::BytePos(5);
                 let right = block.span.lo();
                 (cond, UnusedDelimsCtx::WhileCond, true, Some(left), Some(right))
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index a4ccc8c74c8..9bc6c054e4d 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -13,7 +13,7 @@ use rustc_expand::base::SyntaxExtension;
 use rustc_hir::def_id::{CrateNum, LocalDefId, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_index::vec::IndexVec;
-use rustc_middle::middle::cstore::{CrateSource, DepKind, ExternCrate};
+use rustc_middle::middle::cstore::{CrateDepKind, CrateSource, ExternCrate};
 use rustc_middle::middle::cstore::{ExternCrateSource, MetadataLoaderDyn};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, CrateType, ExternLocation};
@@ -306,7 +306,7 @@ impl<'a> CrateLoader<'a> {
         host_lib: Option<Library>,
         root: Option<&CratePaths>,
         lib: Library,
-        dep_kind: DepKind,
+        dep_kind: CrateDepKind,
         name: Symbol,
     ) -> Result<CrateNum, CrateError> {
         let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
@@ -437,7 +437,7 @@ impl<'a> CrateLoader<'a> {
         &'b mut self,
         name: Symbol,
         span: Span,
-        dep_kind: DepKind,
+        dep_kind: CrateDepKind,
         dep: Option<(&'b CratePaths, &'b CrateDep)>,
     ) -> CrateNum {
         if dep.is_none() {
@@ -450,7 +450,7 @@ impl<'a> CrateLoader<'a> {
     fn maybe_resolve_crate<'b>(
         &'b mut self,
         name: Symbol,
-        mut dep_kind: DepKind,
+        mut dep_kind: CrateDepKind,
         dep: Option<(&'b CratePaths, &'b CrateDep)>,
     ) -> Result<CrateNum, CrateError> {
         info!("resolving crate `{}`", name);
@@ -487,7 +487,7 @@ impl<'a> CrateLoader<'a> {
             match self.load(&mut locator)? {
                 Some(res) => (res, None),
                 None => {
-                    dep_kind = DepKind::MacrosOnly;
+                    dep_kind = CrateDepKind::MacrosOnly;
                     match self.load_proc_macro(&mut locator, path_kind)? {
                         Some(res) => res,
                         None => return Err(locator.into_error()),
@@ -500,7 +500,7 @@ impl<'a> CrateLoader<'a> {
             (LoadResult::Previous(cnum), None) => {
                 let data = self.cstore.get_crate_data(cnum);
                 if data.is_proc_macro_crate() {
-                    dep_kind = DepKind::MacrosOnly;
+                    dep_kind = CrateDepKind::MacrosOnly;
                 }
                 data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind));
                 Ok(cnum)
@@ -560,7 +560,7 @@ impl<'a> CrateLoader<'a> {
         crate_root: &CrateRoot<'_>,
         metadata: &MetadataBlob,
         krate: CrateNum,
-        dep_kind: DepKind,
+        dep_kind: CrateDepKind,
     ) -> Result<CrateNumMap, CrateError> {
         debug!("resolving deps of external crate");
         if crate_root.is_proc_macro_crate() {
@@ -579,7 +579,7 @@ impl<'a> CrateLoader<'a> {
                 dep.name, dep.hash, dep.extra_filename
             );
             let dep_kind = match dep_kind {
-                DepKind::MacrosOnly => DepKind::MacrosOnly,
+                CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
                 _ => dep.kind,
             };
             let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((root, &dep)))?;
@@ -646,7 +646,7 @@ impl<'a> CrateLoader<'a> {
                 self.inject_dependency_if(cnum, "a panic runtime", &|data| {
                     data.needs_panic_runtime()
                 });
-                runtime_found = runtime_found || data.dep_kind() == DepKind::Explicit;
+                runtime_found = runtime_found || data.dep_kind() == CrateDepKind::Explicit;
             }
         });
 
@@ -675,7 +675,7 @@ impl<'a> CrateLoader<'a> {
         };
         info!("panic runtime not found -- loading {}", name);
 
-        let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
+        let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None);
         let data = self.cstore.get_crate_data(cnum);
 
         // Sanity check the loaded crate to ensure it is indeed a panic runtime
@@ -705,7 +705,7 @@ impl<'a> CrateLoader<'a> {
             info!("loading profiler");
 
             let name = sym::profiler_builtins;
-            let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None);
+            let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None);
             let data = self.cstore.get_crate_data(cnum);
 
             // Sanity check the loaded crate to ensure it is indeed a profiler runtime
@@ -901,9 +901,9 @@ impl<'a> CrateLoader<'a> {
                     None => item.ident.name,
                 };
                 let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
-                    DepKind::MacrosOnly
+                    CrateDepKind::MacrosOnly
                 } else {
-                    DepKind::Explicit
+                    CrateDepKind::Explicit
                 };
 
                 let cnum = self.resolve_crate(name, item.span, dep_kind, None);
@@ -925,7 +925,7 @@ impl<'a> CrateLoader<'a> {
     }
 
     pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum {
-        let cnum = self.resolve_crate(name, span, DepKind::Explicit, None);
+        let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit, None);
 
         self.update_extern_crate(
             cnum,
@@ -942,6 +942,6 @@ impl<'a> CrateLoader<'a> {
     }
 
     pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
-        self.maybe_resolve_crate(name, DepKind::Explicit, None).ok()
+        self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
     }
 }
diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs
index aa5fafcc614..bb5ae4d0557 100644
--- a/src/librustc_metadata/dependency_format.rs
+++ b/src/librustc_metadata/dependency_format.rs
@@ -56,7 +56,7 @@ use crate::creader::CStore;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::middle::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
-use rustc_middle::middle::cstore::{self, DepKind};
+use rustc_middle::middle::cstore::{self, CrateDepKind};
 use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::CrateType;
@@ -188,7 +188,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
         let src = tcx.used_crate_source(cnum);
         if src.dylib.is_none()
             && !formats.contains_key(&cnum)
-            && tcx.dep_kind(cnum) == DepKind::Explicit
+            && tcx.dep_kind(cnum) == CrateDepKind::Explicit
         {
             assert!(src.rlib.is_some() || src.rmeta.is_some());
             log::info!("adding staticlib: {}", tcx.crate_name(cnum));
@@ -284,7 +284,7 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
     let last_crate = tcx.crates().len();
     let mut ret = (1..last_crate + 1)
         .map(|cnum| {
-            if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
+            if tcx.dep_kind(CrateNum::new(cnum)) == CrateDepKind::Explicit {
                 Linkage::Static
             } else {
                 Linkage::NotLinked
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index fc4235a3eda..d01c598d059 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -58,7 +58,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
             let mut kind_specified = false;
 
             for item in items.iter() {
-                if item.check_name(sym::kind) {
+                if item.has_name(sym::kind) {
                     kind_specified = true;
                     let kind = match item.value_str() {
                         Some(name) => name,
@@ -84,9 +84,9 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
                             NativeLibKind::Unspecified
                         }
                     };
-                } else if item.check_name(sym::name) {
+                } else if item.has_name(sym::name) {
                     lib.name = item.value_str();
-                } else if item.check_name(sym::cfg) {
+                } else if item.has_name(sym::cfg) {
                     let cfg = match item.meta_item_list() {
                         Some(list) => list,
                         None => continue, // skip like historical compilers
@@ -98,7 +98,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
                     } else {
                         self.tcx.sess.span_err(cfg[0].span(), "invalid argument for `cfg(..)`");
                     }
-                } else if item.check_name(sym::wasm_import_module) {
+                } else if item.has_name(sym::wasm_import_module) {
                     match item.value_str() {
                         Some(s) => lib.wasm_import_module = Some(s),
                         None => {
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 414c3ad633e..9fb4e08e284 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -78,7 +78,8 @@ crate struct CrateMetadata {
     /// Trait impl data.
     /// FIXME: Used only from queries and can use query cache,
     /// so pre-decoding can probably be avoided.
-    trait_impls: FxHashMap<(u32, DefIndex), Lazy<[DefIndex]>>,
+    trait_impls:
+        FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>>,
     /// Proc macro descriptions for this crate, if it's a proc macro crate.
     raw_proc_macros: Option<&'static [ProcMacro]>,
     /// Source maps for code from the crate.
@@ -100,7 +101,7 @@ crate struct CrateMetadata {
     /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
     dependencies: Lock<Vec<CrateNum>>,
     /// How to link (or not link) this crate to the currently compiled crate.
-    dep_kind: Lock<DepKind>,
+    dep_kind: Lock<CrateDepKind>,
     /// Filesystem location of this crate.
     source: CrateSource,
     /// Whether or not this crate should be consider a private dependency
@@ -1150,7 +1151,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .decode((self, tcx))
     }
 
-    fn get_unused_generic_params(&self, id: DefIndex) -> FiniteBitSet<u64> {
+    fn get_unused_generic_params(&self, id: DefIndex) -> FiniteBitSet<u32> {
         self.root
             .tables
             .unused_generic_params
@@ -1289,7 +1290,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         &self,
         tcx: TyCtxt<'tcx>,
         filter: Option<DefId>,
-    ) -> &'tcx [DefId] {
+    ) -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
         if self.root.is_proc_macro_crate() {
             // proc-macro crates export no trait impls.
             return &[];
@@ -1305,16 +1306,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
         if let Some(filter) = filter {
             if let Some(impls) = self.trait_impls.get(&filter) {
-                tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx)))
+                tcx.arena.alloc_from_iter(
+                    impls.decode(self).map(|(idx, simplified_self_ty)| {
+                        (self.local_def_id(idx), simplified_self_ty)
+                    }),
+                )
             } else {
                 &[]
             }
         } else {
-            tcx.arena.alloc_from_iter(
-                self.trait_impls
-                    .values()
-                    .flat_map(|impls| impls.decode(self).map(|idx| self.local_def_id(idx))),
-            )
+            tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| {
+                impls
+                    .decode(self)
+                    .map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty))
+            }))
         }
     }
 
@@ -1669,7 +1674,7 @@ impl CrateMetadata {
         raw_proc_macros: Option<&'static [ProcMacro]>,
         cnum: CrateNum,
         cnum_map: CrateNumMap,
-        dep_kind: DepKind,
+        dep_kind: CrateDepKind,
         source: CrateSource,
         private_dep: bool,
         host_hash: Option<Svh>,
@@ -1727,11 +1732,11 @@ impl CrateMetadata {
         &self.source
     }
 
-    crate fn dep_kind(&self) -> DepKind {
+    crate fn dep_kind(&self) -> CrateDepKind {
         *self.dep_kind.lock()
     }
 
-    crate fn update_dep_kind(&self, f: impl FnOnce(DepKind) -> DepKind) {
+    crate fn update_dep_kind(&self, f: impl FnOnce(CrateDepKind) -> CrateDepKind) {
         self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
     }
 
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 49aaa845bc2..acae44e6bf7 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -267,7 +267,7 @@ impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> {
         // real code should never need to care about this.
         //
         // 2. Using `Span::def_site` or `Span::mixed_site` will not
-        // include any hygiene information associated with the defintion
+        // include any hygiene information associated with the definition
         // site. This means that a proc-macro cannot emit a `$crate`
         // identifier which resolves to one of its dependencies,
         // which also should never come up in practice.
@@ -1134,8 +1134,11 @@ impl EncodeContext<'a, 'tcx> {
         debug!("EntryBuilder::encode_mir({:?})", def_id);
         if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
             record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
-            record!(self.tables.unused_generic_params[def_id.to_def_id()] <-
-                    self.tcx.unused_generic_params(def_id));
+
+            let unused = self.tcx.unused_generic_params(def_id);
+            if !unused.is_empty() {
+                record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
+            }
         }
     }
 
@@ -1607,7 +1610,7 @@ impl EncodeContext<'a, 'tcx> {
             .into_iter()
             .map(|(trait_def_id, mut impls)| {
                 // Bring everything into deterministic order for hashing
-                impls.sort_by_cached_key(|&index| {
+                impls.sort_by_cached_key(|&(index, _)| {
                     tcx.hir().definitions().def_path_hash(LocalDefId { local_def_index: index })
                 });
 
@@ -1849,7 +1852,7 @@ impl EncodeContext<'a, 'tcx> {
 
 struct ImplVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    impls: FxHashMap<DefId, Vec<DefIndex>>,
+    impls: FxHashMap<DefId, Vec<(DefIndex, Option<ty::fast_reject::SimplifiedType>)>>,
 }
 
 impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
@@ -1857,7 +1860,13 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
         if let hir::ItemKind::Impl { .. } = item.kind {
             let impl_id = self.tcx.hir().local_def_id(item.hir_id);
             if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id.to_def_id()) {
-                self.impls.entry(trait_ref.def_id).or_default().push(impl_id.local_def_index);
+                let simplified_self_ty =
+                    ty::fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), false);
+
+                self.impls
+                    .entry(trait_ref.def_id)
+                    .or_default()
+                    .push((impl_id.local_def_index, simplified_self_ty));
             }
         }
     }
diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs
index 1837b86f4b5..1c287be9f6b 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, DefIndex};
 use rustc_hir::lang_items;
 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
 use rustc_middle::hir::exports::Export;
-use rustc_middle::middle::cstore::{DepKind, ForeignModule, LinkagePreference, NativeLib};
+use rustc_middle::middle::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc_middle::mir;
 use rustc_middle::ty::{self, ReprOptions, Ty};
@@ -226,14 +226,14 @@ crate struct CrateDep {
     pub name: Symbol,
     pub hash: Svh,
     pub host_hash: Option<Svh>,
-    pub kind: DepKind,
+    pub kind: CrateDepKind,
     pub extra_filename: String,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
 crate struct TraitImpls {
     trait_id: (u32, DefIndex),
-    impls: Lazy<[DefIndex]>,
+    impls: Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>,
 }
 
 /// Define `LazyTables` and `TableBuilders` at the same time.
@@ -285,7 +285,7 @@ define_tables! {
     super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
     mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
     promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
-    unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u64>>>,
+    unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml
index 678fcfe6539..03431cb5a88 100644
--- a/src/librustc_middle/Cargo.toml
+++ b/src/librustc_middle/Cargo.toml
@@ -12,7 +12,6 @@ doctest = false
 [dependencies]
 rustc_arena = { path = "../librustc_arena" }
 bitflags = "1.2.1"
-scoped-tls = "1.0"
 log = { package = "tracing", version = "0.1" }
 rustc-rayon-core = "0.3.0"
 polonius-engine = "0.12.0"
diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs
index b7dccb8d8ce..a49287840e1 100644
--- a/src/librustc_middle/lib.rs
+++ b/src/librustc_middle/lib.rs
@@ -55,8 +55,6 @@
 #[macro_use]
 extern crate bitflags;
 #[macro_use]
-extern crate scoped_tls;
-#[macro_use]
 extern crate rustc_macros;
 #[macro_use]
 extern crate rustc_data_structures;
diff --git a/src/librustc_middle/middle/cstore.rs b/src/librustc_middle/middle/cstore.rs
index 97e877df966..0a34c06adf0 100644
--- a/src/librustc_middle/middle/cstore.rs
+++ b/src/librustc_middle/middle/cstore.rs
@@ -40,7 +40,7 @@ impl CrateSource {
 
 #[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
 #[derive(HashStable)]
-pub enum DepKind {
+pub enum CrateDepKind {
     /// A dependency that is only used for its macros.
     MacrosOnly,
     /// A dependency that is always injected into the dependency list and so
@@ -51,11 +51,11 @@ pub enum DepKind {
     Explicit,
 }
 
-impl DepKind {
+impl CrateDepKind {
     pub fn macros_only(self) -> bool {
         match self {
-            DepKind::MacrosOnly => true,
-            DepKind::Implicit | DepKind::Explicit => false,
+            CrateDepKind::MacrosOnly => true,
+            CrateDepKind::Implicit | CrateDepKind::Explicit => false,
         }
     }
 }
diff --git a/src/librustc_middle/middle/stability.rs b/src/librustc_middle/middle/stability.rs
index 5f7ff54fd31..b913d7dd4ad 100644
--- a/src/librustc_middle/middle/stability.rs
+++ b/src/librustc_middle/middle/stability.rs
@@ -166,29 +166,31 @@ pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>)
 
 pub fn deprecation_suggestion(
     diag: &mut DiagnosticBuilder<'_>,
+    kind: &str,
     suggestion: Option<Symbol>,
     span: Span,
 ) {
     if let Some(suggestion) = suggestion {
         diag.span_suggestion(
             span,
-            "replace the use of the deprecated item",
+            &format!("replace the use of the deprecated {}", kind),
             suggestion.to_string(),
             Applicability::MachineApplicable,
         );
     }
 }
 
-pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) {
+pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) {
     let (message, lint) = if deprecation_in_effect(
         depr.is_since_rustc_version,
         depr.since.map(Symbol::as_str).as_deref(),
     ) {
-        (format!("use of deprecated item '{}'", path), DEPRECATED)
+        (format!("use of deprecated {} `{}`", kind, path), DEPRECATED)
     } else {
         (
             format!(
-                "use of item '{}' that will be deprecated in future version {}",
+                "use of {} `{}` that will be deprecated in future version {}",
+                kind,
                 path,
                 depr.since.unwrap()
             ),
@@ -224,6 +226,7 @@ fn late_report_deprecation(
     lint: &'static Lint,
     span: Span,
     hir_id: HirId,
+    def_id: DefId,
 ) {
     if span.in_derive_expansion() {
         return;
@@ -232,7 +235,8 @@ fn late_report_deprecation(
     tcx.struct_span_lint_hir(lint, hir_id, span, |lint| {
         let mut diag = lint.build(message);
         if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
-            deprecation_suggestion(&mut diag, suggestion, span);
+            let kind = tcx.def_kind(def_id).descr(def_id);
+            deprecation_suggestion(&mut diag, kind, suggestion, span);
         }
         diag.emit()
     });
@@ -304,8 +308,9 @@ impl<'tcx> TyCtxt<'tcx> {
                 // #[rustc_deprecated] however wants to emit down the whole
                 // hierarchy.
                 if !skip || depr_entry.attr.is_since_rustc_version {
-                    let (message, lint) =
-                        deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
+                    let path = &self.def_path_str(def_id);
+                    let kind = self.def_kind(def_id).descr(def_id);
+                    let (message, lint) = deprecation_message(&depr_entry.attr, kind, path);
                     late_report_deprecation(
                         self,
                         &message,
@@ -313,6 +318,7 @@ impl<'tcx> TyCtxt<'tcx> {
                         lint,
                         span,
                         id,
+                        def_id,
                     );
                 }
             };
diff --git a/src/librustc_middle/mir/coverage/mod.rs b/src/librustc_middle/mir/coverage/mod.rs
index 82365ef6a73..6b1514da644 100644
--- a/src/librustc_middle/mir/coverage/mod.rs
+++ b/src/librustc_middle/mir/coverage/mod.rs
@@ -4,8 +4,11 @@
 pub mod count_code_region_args {
     pub const FUNCTION_SOURCE_HASH: usize = 0;
     pub const COUNTER_ID: usize = 1;
-    pub const START_BYTE_POS: usize = 2;
-    pub const END_BYTE_POS: usize = 3;
+    pub const FILE_NAME: usize = 2;
+    pub const START_LINE: usize = 3;
+    pub const START_COL: usize = 4;
+    pub const END_LINE: usize = 5;
+    pub const END_COL: usize = 6;
 }
 
 /// Positional arguments to `libcore::coverage_counter_add()` and
@@ -14,12 +17,18 @@ pub mod coverage_counter_expression_args {
     pub const EXPRESSION_ID: usize = 0;
     pub const LEFT_ID: usize = 1;
     pub const RIGHT_ID: usize = 2;
-    pub const START_BYTE_POS: usize = 3;
-    pub const END_BYTE_POS: usize = 4;
+    pub const FILE_NAME: usize = 3;
+    pub const START_LINE: usize = 4;
+    pub const START_COL: usize = 5;
+    pub const END_LINE: usize = 6;
+    pub const END_COL: usize = 7;
 }
 
 /// Positional arguments to `libcore::coverage_unreachable()`
 pub mod coverage_unreachable_args {
-    pub const START_BYTE_POS: usize = 0;
-    pub const END_BYTE_POS: usize = 1;
+    pub const FILE_NAME: usize = 0;
+    pub const START_LINE: usize = 1;
+    pub const START_COL: usize = 2;
+    pub const END_LINE: usize = 3;
+    pub const END_COL: usize = 4;
 }
diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs
index 1d76bb525eb..c904cd83a78 100644
--- a/src/librustc_middle/mir/interpret/error.rs
+++ b/src/librustc_middle/mir/interpret/error.rs
@@ -27,7 +27,7 @@ pub enum ErrorHandled {
     TooGeneric,
 }
 
-CloneTypeFoldableImpls! {
+CloneTypeFoldableAndLiftImpls! {
     ErrorHandled,
 }
 
@@ -242,9 +242,9 @@ impl From<ErrorHandled> for InterpErrorInfo<'_> {
 
 impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
     fn from(kind: InterpError<'tcx>) -> Self {
-        let capture_backtrace = tls::with_context_opt(|ctxt| {
-            if let Some(ctxt) = ctxt {
-                *Lock::borrow(&ctxt.tcx.sess.ctfe_backtrace)
+        let capture_backtrace = tls::with_opt(|tcx| {
+            if let Some(tcx) = tcx {
+                *Lock::borrow(&tcx.sess.ctfe_backtrace)
             } else {
                 CtfeBacktrace::Disabled
             }
diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs
index 2c76f0b5ad0..b4e7a5b98e3 100644
--- a/src/librustc_middle/mir/interpret/value.rs
+++ b/src/librustc_middle/mir/interpret/value.rs
@@ -56,6 +56,15 @@ impl<'tcx> ConstValue<'tcx> {
         }
     }
 
+    pub fn try_to_str_slice(&self) -> Option<&'tcx str> {
+        if let ConstValue::Slice { data, start, end } = *self {
+            ::std::str::from_utf8(data.inspect_with_undef_and_ptr_outside_interpreter(start..end))
+                .ok()
+        } else {
+            None
+        }
+    }
+
     pub fn try_to_bits(&self, size: Size) -> Option<u128> {
         self.try_to_scalar()?.to_bits(size).ok()
     }
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 31b8de500e0..3b0c480f6d4 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -2,7 +2,7 @@
 //!
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
 
-use crate::mir::interpret::{GlobalAlloc, Scalar};
+use crate::mir::interpret::{Allocation, ConstValue, GlobalAlloc, Scalar};
 use crate::mir::visit::MirVisitable;
 use crate::ty::adjustment::PointerCast;
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@@ -1842,6 +1842,33 @@ impl<'tcx> Operand<'tcx> {
         }
     }
 
+    /// Convenience helper to make a literal-like constant from a given `&str` slice.
+    /// Since this is used to synthesize MIR, assumes `user_ty` is None.
+    pub fn const_from_str(tcx: TyCtxt<'tcx>, val: &str, span: Span) -> Operand<'tcx> {
+        let tcx = tcx;
+        let allocation = Allocation::from_byte_aligned_bytes(val.as_bytes());
+        let allocation = tcx.intern_const_alloc(allocation);
+        let const_val = ConstValue::Slice { data: allocation, start: 0, end: val.len() };
+        let ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.types.str_);
+        Operand::Constant(box Constant {
+            span,
+            user_ty: None,
+            literal: ty::Const::from_value(tcx, const_val, ty),
+        })
+    }
+
+    /// Convenience helper to make a `ConstValue` from the given `Operand`, assuming that `Operand`
+    /// wraps a constant value (such as a `&str` slice). Panics if this is not the case.
+    pub fn value_from_const(operand: &Operand<'tcx>) -> ConstValue<'tcx> {
+        match operand {
+            Operand::Constant(constant) => match constant.literal.val.try_to_value() {
+                Some(const_value) => const_value,
+                _ => panic!("{:?}: ConstValue expected", constant.literal.val),
+            },
+            _ => panic!("{:?}: Constant expected", operand),
+        }
+    }
+
     pub fn to_copy(&self) -> Self {
         match *self {
             Operand::Copy(_) | Operand::Constant(_) => self.clone(),
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index 69f1366abf8..a8f6723a356 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -1125,11 +1125,11 @@ rustc_queries! {
 
     TypeChecking {
         query implementations_of_trait(_: (CrateNum, DefId))
-            -> &'tcx [DefId] {
+            -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
             desc { "looking up implementations of a trait in a crate" }
         }
         query all_trait_implementations(_: CrateNum)
-            -> &'tcx [DefId] {
+            -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
             desc { "looking up all (?) trait implementations" }
         }
     }
@@ -1186,7 +1186,7 @@ rustc_queries! {
     }
 
     Other {
-        query dep_kind(_: CrateNum) -> DepKind {
+        query dep_kind(_: CrateNum) -> CrateDepKind {
             eval_always
             desc { "fetching what a dependency looks like" }
         }
@@ -1319,7 +1319,7 @@ rustc_queries! {
         query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
             desc { "codegen_unit" }
         }
-        query unused_generic_params(key: DefId) -> FiniteBitSet<u64> {
+        query unused_generic_params(key: DefId) -> FiniteBitSet<u32> {
             cache_on_disk_if { key.is_local() }
             desc {
                 |tcx| "determining which generic parameters are unused by `{}`",
diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs
index d2747e5fc65..585f29386a8 100644
--- a/src/librustc_middle/traits/mod.rs
+++ b/src/librustc_middle/traits/mod.rs
@@ -30,7 +30,6 @@ pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx
 
 pub use self::ImplSource::*;
 pub use self::ObligationCauseCode::*;
-pub use self::SelectionError::*;
 
 pub use self::chalk::{
     ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustInterner as ChalkRustInterner,
@@ -86,7 +85,7 @@ pub enum Reveal {
 ///
 /// We do not want to intern this as there are a lot of obligation causes which
 /// only live for a short period of time.
-#[derive(Clone, PartialEq, Eq, Hash)]
+#[derive(Clone, PartialEq, Eq, Hash, Lift)]
 pub struct ObligationCause<'tcx> {
     /// `None` for `ObligationCause::dummy`, `Some` otherwise.
     data: Option<Rc<ObligationCauseData<'tcx>>>,
@@ -111,7 +110,7 @@ impl Deref for ObligationCause<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
 pub struct ObligationCauseData<'tcx> {
     pub span: Span,
 
@@ -169,14 +168,14 @@ impl<'tcx> ObligationCause<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
 pub struct UnifyReceiverContext<'tcx> {
     pub assoc_item: ty::AssocItem,
     pub param_env: ty::ParamEnv<'tcx>,
     pub substs: SubstsRef<'tcx>,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
 pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from the span.
     MiscObligation,
@@ -343,7 +342,7 @@ impl ObligationCauseCode<'_> {
 #[cfg(target_arch = "x86_64")]
 static_assert_size!(ObligationCauseCode<'_>, 32);
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
 pub struct MatchExpressionArmCause<'tcx> {
     pub arm_span: Span,
     pub source: hir::MatchSource,
@@ -359,7 +358,7 @@ pub struct IfExpressionCause {
     pub semicolon: Option<Span>,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
 pub struct DerivedObligationCause<'tcx> {
     /// The trait reference of the parent obligation that led to the
     /// current obligation. Note that only trait obligations lead to
@@ -371,7 +370,7 @@ pub struct DerivedObligationCause<'tcx> {
     pub parent_code: Rc<ObligationCauseCode<'tcx>>,
 }
 
-#[derive(Clone, Debug, TypeFoldable)]
+#[derive(Clone, Debug, TypeFoldable, Lift)]
 pub enum SelectionError<'tcx> {
     Unimplemented,
     OutputTypeParameterMismatch(
@@ -427,7 +426,7 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
 /// ### The type parameter `N`
 ///
 /// See explanation on `ImplSourceUserDefinedData`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub enum ImplSource<'tcx, N> {
     /// ImplSource identifying a particular impl.
     ImplSourceUserDefined(ImplSourceUserDefinedData<'tcx, N>),
@@ -558,14 +557,14 @@ impl<'tcx, N> ImplSource<'tcx, N> {
 /// is `Obligation`, as one might expect. During codegen, however, this
 /// is `()`, because codegen only requires a shallow resolution of an
 /// impl, and nested obligations are satisfied later.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceUserDefinedData<'tcx, N> {
     pub impl_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceGeneratorData<'tcx, N> {
     pub generator_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
@@ -574,7 +573,7 @@ pub struct ImplSourceGeneratorData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceClosureData<'tcx, N> {
     pub closure_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
@@ -583,18 +582,18 @@ pub struct ImplSourceClosureData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceAutoImplData<N> {
     pub trait_def_id: DefId,
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceBuiltinData<N> {
     pub nested: Vec<N>,
 }
 
-#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceObjectData<'tcx, N> {
     /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
     pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
@@ -607,17 +606,17 @@ pub struct ImplSourceObjectData<'tcx, N> {
     pub nested: Vec<N>,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceFnPointerData<'tcx, N> {
     pub fn_ty: Ty<'tcx>,
     pub nested: Vec<N>,
 }
 
 // FIXME(@lcnr): This should be  refactored and merged with other builtin vtables.
-#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ImplSourceDiscriminantKindData;
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
 pub struct ImplSourceTraitAliasData<'tcx, N> {
     pub alias_def_id: DefId,
     pub substs: SubstsRef<'tcx>,
diff --git a/src/librustc_middle/traits/select.rs b/src/librustc_middle/traits/select.rs
index a12f5910b14..6ad514c6be2 100644
--- a/src/librustc_middle/traits/select.rs
+++ b/src/librustc_middle/traits/select.rs
@@ -6,29 +6,18 @@ use self::EvaluationResult::*;
 
 use super::{SelectionError, SelectionResult};
 
-use crate::dep_graph::DepNodeIndex;
-use crate::ty::{self, TyCtxt};
+use crate::ty;
 
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lock;
 use rustc_hir::def_id::DefId;
+use rustc_query_system::cache::Cache;
 
-#[derive(Clone, Default)]
-pub struct SelectionCache<'tcx> {
-    pub hashmap: Lock<
-        FxHashMap<
-            ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>,
-            WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>,
-        >,
-    >,
-}
+pub type SelectionCache<'tcx> = Cache<
+    ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>,
+    SelectionResult<'tcx, SelectionCandidate<'tcx>>,
+>;
 
-impl<'tcx> SelectionCache<'tcx> {
-    /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
-    pub fn clear(&self) {
-        *self.hashmap.borrow_mut() = Default::default();
-    }
-}
+pub type EvaluationCache<'tcx> =
+    Cache<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, EvaluationResult>;
 
 /// The selection process begins by considering all impls, where
 /// clauses, and so forth that might resolve an obligation. Sometimes
@@ -264,75 +253,3 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
         SelectionError::Overflow
     }
 }
-
-#[derive(Clone, Default)]
-pub struct EvaluationCache<'tcx> {
-    pub hashmap: Lock<
-        FxHashMap<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, WithDepNode<EvaluationResult>>,
-    >,
-}
-
-impl<'tcx> EvaluationCache<'tcx> {
-    /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
-    pub fn clear(&self) {
-        *self.hashmap.borrow_mut() = Default::default();
-    }
-}
-
-#[derive(Clone, Eq, PartialEq)]
-pub struct WithDepNode<T> {
-    dep_node: DepNodeIndex,
-    cached_value: T,
-}
-
-impl<T: Clone> WithDepNode<T> {
-    pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self {
-        WithDepNode { dep_node, cached_value }
-    }
-
-    pub fn get(&self, tcx: TyCtxt<'_>) -> T {
-        tcx.dep_graph.read_index(self.dep_node);
-        self.cached_value.clone()
-    }
-}
-
-#[derive(Clone, Debug)]
-pub enum IntercrateAmbiguityCause {
-    DownstreamCrate { trait_desc: String, self_desc: Option<String> },
-    UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
-    ReservationImpl { message: String },
-}
-
-impl IntercrateAmbiguityCause {
-    /// Emits notes when the overlap is caused by complex intercrate ambiguities.
-    /// See #23980 for details.
-    pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) {
-        err.note(&self.intercrate_ambiguity_hint());
-    }
-
-    pub fn intercrate_ambiguity_hint(&self) -> String {
-        match self {
-            &IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => {
-                let self_desc = if let &Some(ref ty) = self_desc {
-                    format!(" for type `{}`", ty)
-                } else {
-                    String::new()
-                };
-                format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc)
-            }
-            &IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => {
-                let self_desc = if let &Some(ref ty) = self_desc {
-                    format!(" for type `{}`", ty)
-                } else {
-                    String::new()
-                };
-                format!(
-                    "upstream crates may add a new impl of trait `{}`{} \
-                     in future versions",
-                    trait_desc, self_desc
-                )
-            }
-            &IntercrateAmbiguityCause::ReservationImpl { ref message } => message.clone(),
-        }
-    }
-}
diff --git a/src/librustc_middle/traits/structural_impls.rs b/src/librustc_middle/traits/structural_impls.rs
index 18b4371053a..d73fc628ceb 100644
--- a/src/librustc_middle/traits/structural_impls.rs
+++ b/src/librustc_middle/traits/structural_impls.rs
@@ -1,8 +1,6 @@
 use crate::traits;
-use crate::ty::{Lift, TyCtxt};
 
 use std::fmt;
-use std::rc::Rc;
 
 // Structural impls for the structs in `traits`.
 
@@ -107,222 +105,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx,
 ///////////////////////////////////////////////////////////////////////////
 // Lift implementations
 
-impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
-    type Lifted = traits::SelectionError<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            super::Unimplemented => Some(super::Unimplemented),
-            super::OutputTypeParameterMismatch(a, b, ref err) => {
-                tcx.lift(&(a, b)).and_then(|(a, b)| {
-                    tcx.lift(err).map(|err| super::OutputTypeParameterMismatch(a, b, err))
-                })
-            }
-            super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
-            super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)),
-            super::Overflow => Some(super::Overflow),
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
-    type Lifted = traits::ObligationCauseCode<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            super::ReturnNoExpression => Some(super::ReturnNoExpression),
-            super::MiscObligation => Some(super::MiscObligation),
-            super::SliceOrArrayElem => Some(super::SliceOrArrayElem),
-            super::TupleElem => Some(super::TupleElem),
-            super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
-            super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
-            super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)),
-            super::ReferenceOutlivesReferent(ty) => {
-                tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
-            }
-            super::ObjectTypeBound(ty, r) => {
-                tcx.lift(&ty).and_then(|ty| tcx.lift(&r).map(|r| super::ObjectTypeBound(ty, r)))
-            }
-            super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
-            super::Coercion { source, target } => {
-                Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? })
-            }
-            super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
-            super::TupleInitializerSized => Some(super::TupleInitializerSized),
-            super::StructInitializerSized => Some(super::StructInitializerSized),
-            super::VariableType(id) => Some(super::VariableType(id)),
-            super::ReturnValue(id) => Some(super::ReturnValue(id)),
-            super::ReturnType => Some(super::ReturnType),
-            super::SizedArgumentType(sp) => Some(super::SizedArgumentType(sp)),
-            super::SizedReturnType => Some(super::SizedReturnType),
-            super::SizedYieldType => Some(super::SizedYieldType),
-            super::InlineAsmSized => Some(super::InlineAsmSized),
-            super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)),
-            super::FieldSized { adt_kind, span, last } => {
-                Some(super::FieldSized { adt_kind, span, last })
-            }
-            super::ConstSized => Some(super::ConstSized),
-            super::ConstPatternStructural => Some(super::ConstPatternStructural),
-            super::SharedStatic => Some(super::SharedStatic),
-            super::BuiltinDerivedObligation(ref cause) => {
-                tcx.lift(cause).map(super::BuiltinDerivedObligation)
-            }
-            super::ImplDerivedObligation(ref cause) => {
-                tcx.lift(cause).map(super::ImplDerivedObligation)
-            }
-            super::DerivedObligation(ref cause) => tcx.lift(cause).map(super::DerivedObligation),
-            super::CompareImplConstObligation => Some(super::CompareImplConstObligation),
-            super::CompareImplMethodObligation {
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-            } => Some(super::CompareImplMethodObligation {
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-            }),
-            super::CompareImplTypeObligation { item_name, impl_item_def_id, trait_item_def_id } => {
-                Some(super::CompareImplTypeObligation {
-                    item_name,
-                    impl_item_def_id,
-                    trait_item_def_id,
-                })
-            }
-            super::ExprAssignable => Some(super::ExprAssignable),
-            super::MatchExpressionArm(box super::MatchExpressionArmCause {
-                arm_span,
-                source,
-                ref prior_arms,
-                last_ty,
-                scrut_hir_id,
-            }) => tcx.lift(&last_ty).map(|last_ty| {
-                super::MatchExpressionArm(box super::MatchExpressionArmCause {
-                    arm_span,
-                    source,
-                    prior_arms: prior_arms.clone(),
-                    last_ty,
-                    scrut_hir_id,
-                })
-            }),
-            super::Pattern { span, root_ty, origin_expr } => {
-                tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr })
-            }
-            super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => {
-                Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }))
-            }
-            super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
-            super::MainFunctionType => Some(super::MainFunctionType),
-            super::StartFunctionType => Some(super::StartFunctionType),
-            super::IntrinsicType => Some(super::IntrinsicType),
-            super::MethodReceiver => Some(super::MethodReceiver),
-            super::UnifyReceiver(ref ctxt) => tcx.lift(ctxt).map(|ctxt| super::UnifyReceiver(ctxt)),
-            super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
-            super::TrivialBound => Some(super::TrivialBound),
-        }
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::UnifyReceiverContext<'a> {
-    type Lifted = traits::UnifyReceiverContext<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.param_env).and_then(|param_env| {
-            tcx.lift(&self.substs).map(|substs| traits::UnifyReceiverContext {
-                assoc_item: self.assoc_item,
-                param_env,
-                substs,
-            })
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
-    type Lifted = traits::DerivedObligationCause<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
-            tcx.lift(&*self.parent_code).map(|code| traits::DerivedObligationCause {
-                parent_trait_ref: trait_ref,
-                parent_code: Rc::new(code),
-            })
-        })
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
-    type Lifted = traits::ObligationCause<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.code).map(|code| traits::ObligationCause::new(self.span, self.body_id, code))
-    }
-}
-
-// For codegen only.
-impl<'a, 'tcx> Lift<'tcx> for traits::ImplSource<'a, ()> {
-    type Lifted = traits::ImplSource<'tcx, ()>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        match self.clone() {
-            traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData {
-                impl_def_id,
-                substs,
-                nested,
-            }) => tcx.lift(&substs).map(|substs| {
-                traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData {
-                    impl_def_id,
-                    substs,
-                    nested,
-                })
-            }),
-            traits::ImplSourceAutoImpl(t) => Some(traits::ImplSourceAutoImpl(t)),
-            traits::ImplSourceGenerator(traits::ImplSourceGeneratorData {
-                generator_def_id,
-                substs,
-                nested,
-            }) => tcx.lift(&substs).map(|substs| {
-                traits::ImplSourceGenerator(traits::ImplSourceGeneratorData {
-                    generator_def_id,
-                    substs,
-                    nested,
-                })
-            }),
-            traits::ImplSourceClosure(traits::ImplSourceClosureData {
-                closure_def_id,
-                substs,
-                nested,
-            }) => tcx.lift(&substs).map(|substs| {
-                traits::ImplSourceClosure(traits::ImplSourceClosureData {
-                    closure_def_id,
-                    substs,
-                    nested,
-                })
-            }),
-            traits::ImplSourceFnPointer(traits::ImplSourceFnPointerData { fn_ty, nested }) => {
-                tcx.lift(&fn_ty).map(|fn_ty| {
-                    traits::ImplSourceFnPointer(traits::ImplSourceFnPointerData { fn_ty, nested })
-                })
-            }
-            traits::ImplSourceDiscriminantKind(traits::ImplSourceDiscriminantKindData) => {
-                Some(traits::ImplSourceDiscriminantKind(traits::ImplSourceDiscriminantKindData))
-            }
-            traits::ImplSourceParam(n) => Some(traits::ImplSourceParam(n)),
-            traits::ImplSourceBuiltin(n) => Some(traits::ImplSourceBuiltin(n)),
-            traits::ImplSourceObject(traits::ImplSourceObjectData {
-                upcast_trait_ref,
-                vtable_base,
-                nested,
-            }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| {
-                traits::ImplSourceObject(traits::ImplSourceObjectData {
-                    upcast_trait_ref: trait_ref,
-                    vtable_base,
-                    nested,
-                })
-            }),
-            traits::ImplSourceTraitAlias(traits::ImplSourceTraitAliasData {
-                alias_def_id,
-                substs,
-                nested,
-            }) => tcx.lift(&substs).map(|substs| {
-                traits::ImplSourceTraitAlias(traits::ImplSourceTraitAliasData {
-                    alias_def_id,
-                    substs,
-                    nested,
-                })
-            }),
-        }
-    }
+CloneTypeFoldableAndLiftImpls! {
+    super::IfExpressionCause,
+    super::ImplSourceDiscriminantKindData,
 }
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index 775d755444d..6cbf5db8373 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -1632,7 +1632,6 @@ pub mod tls {
     use crate::ty::query;
     use rustc_data_structures::sync::{self, Lock};
     use rustc_data_structures::thin_vec::ThinVec;
-    use rustc_data_structures::OnDrop;
     use rustc_errors::Diagnostic;
     use std::mem;
 
@@ -1649,8 +1648,7 @@ pub mod tls {
     /// in this module.
     #[derive(Clone)]
     pub struct ImplicitCtxt<'a, 'tcx> {
-        /// The current `TyCtxt`. Initially created by `enter_global` and updated
-        /// by `enter_local` with a new local interner.
+        /// The current `TyCtxt`.
         pub tcx: TyCtxt<'tcx>,
 
         /// The current query job, if any. This is updated by `JobOwner::start` in
@@ -1669,6 +1667,13 @@ pub mod tls {
         pub task_deps: Option<&'a Lock<TaskDeps>>,
     }
 
+    impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
+        pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
+            let tcx = TyCtxt { gcx };
+            ImplicitCtxt { tcx, query: None, diagnostics: None, layout_depth: 0, task_deps: None }
+        }
+    }
+
     /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
     /// to `value` during the call to `f`. It is restored to its previous value after.
     /// This is used to set the pointer to the new `ImplicitCtxt`.
@@ -1682,7 +1687,7 @@ pub mod tls {
     /// This is used to get the pointer to the current `ImplicitCtxt`.
     #[cfg(parallel_compiler)]
     #[inline]
-    fn get_tlv() -> usize {
+    pub fn get_tlv() -> usize {
         rayon_core::tlv::get()
     }
 
@@ -1699,7 +1704,7 @@ pub mod tls {
     #[inline]
     fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
         let old = get_tlv();
-        let _reset = OnDrop(move || TLV.with(|tlv| tlv.set(old)));
+        let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old)));
         TLV.with(|tlv| tlv.set(value));
         f()
     }
@@ -1720,50 +1725,6 @@ pub mod tls {
         set_tlv(context as *const _ as usize, || f(&context))
     }
 
-    /// Enters `GlobalCtxt` by setting up librustc_ast callbacks and
-    /// creating a initial `TyCtxt` and `ImplicitCtxt`.
-    /// This happens once per rustc session and `TyCtxt`s only exists
-    /// inside the `f` function.
-    pub fn enter_global<'tcx, F, R>(gcx: &'tcx GlobalCtxt<'tcx>, f: F) -> R
-    where
-        F: FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        // Update `GCX_PTR` to indicate there's a `GlobalCtxt` available.
-        GCX_PTR.with(|lock| {
-            *lock.lock() = gcx as *const _ as usize;
-        });
-        // Set `GCX_PTR` back to 0 when we exit.
-        let _on_drop = OnDrop(move || {
-            GCX_PTR.with(|lock| *lock.lock() = 0);
-        });
-
-        let tcx = TyCtxt { gcx };
-        let icx =
-            ImplicitCtxt { tcx, query: None, diagnostics: None, layout_depth: 0, task_deps: None };
-        enter_context(&icx, |_| f(tcx))
-    }
-
-    scoped_thread_local! {
-        /// Stores a pointer to the `GlobalCtxt` if one is available.
-        /// This is used to access the `GlobalCtxt` in the deadlock handler given to Rayon.
-        pub static GCX_PTR: Lock<usize>
-    }
-
-    /// Creates a `TyCtxt` and `ImplicitCtxt` based on the `GCX_PTR` thread local.
-    /// This is used in the deadlock handler.
-    pub unsafe fn with_global<F, R>(f: F) -> R
-    where
-        F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
-    {
-        let gcx = GCX_PTR.with(|lock| *lock.lock());
-        assert!(gcx != 0);
-        let gcx = &*(gcx as *const GlobalCtxt<'_>);
-        let tcx = TyCtxt { gcx };
-        let icx =
-            ImplicitCtxt { query: None, diagnostics: None, tcx, layout_depth: 0, task_deps: None };
-        enter_context(&icx, |_| f(tcx))
-    }
-
     /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
     #[inline]
     pub fn with_context_opt<F, R>(f: F) -> R
diff --git a/src/librustc_middle/ty/query/job.rs b/src/librustc_middle/ty/query/job.rs
index 60b93b3d44d..1811d945a1d 100644
--- a/src/librustc_middle/ty/query/job.rs
+++ b/src/librustc_middle/ty/query/job.rs
@@ -10,18 +10,20 @@ use std::thread;
 pub unsafe fn handle_deadlock() {
     let registry = rayon_core::Registry::current();
 
-    let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| gcx_ptr as *const _);
-    let gcx_ptr = &*gcx_ptr;
+    let context = tls::get_tlv();
+    assert!(context != 0);
+    rustc_data_structures::sync::assert_sync::<tls::ImplicitCtxt<'_, '_>>();
+    let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>);
 
     let span_session_globals = rustc_span::SESSION_GLOBALS.with(|ssg| ssg as *const _);
     let span_session_globals = &*span_session_globals;
     let ast_session_globals = rustc_ast::attr::SESSION_GLOBALS.with(|asg| asg as *const _);
     let ast_session_globals = &*ast_session_globals;
     thread::spawn(move || {
-        tls::GCX_PTR.set(gcx_ptr, || {
+        tls::enter_context(icx, |_| {
             rustc_ast::attr::SESSION_GLOBALS.set(ast_session_globals, || {
                 rustc_span::SESSION_GLOBALS
-                    .set(span_session_globals, || tls::with_global(|tcx| deadlock(tcx, &registry)))
+                    .set(span_session_globals, || tls::with(|tcx| deadlock(tcx, &registry)))
             });
         })
     });
diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs
index 2f7a9aee536..b39c0b5190a 100644
--- a/src/librustc_middle/ty/query/mod.rs
+++ b/src/librustc_middle/ty/query/mod.rs
@@ -1,10 +1,10 @@
-use crate::dep_graph::{self, DepNode, DepNodeParams};
+use crate::dep_graph::{self, DepKind, DepNode, DepNodeParams};
 use crate::hir::exports::Export;
 use crate::hir::map;
 use crate::infer::canonical::{self, Canonical};
 use crate::lint::LintLevelMap;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
-use crate::middle::cstore::{CrateSource, DepKind};
+use crate::middle::cstore::{CrateDepKind, CrateSource};
 use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use crate::middle::lib_features::LibFeatures;
@@ -161,7 +161,7 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool
     // hit the cache instead of having to go through `force_from_dep_node`.
     // This assertion makes sure, we actually keep applying the solution above.
     debug_assert!(
-        dep_node.kind != crate::dep_graph::DepKind::codegen_unit,
+        dep_node.kind != DepKind::codegen_unit,
         "calling force_from_dep_node() on DepKind::codegen_unit"
     );
 
@@ -172,14 +172,14 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool
     rustc_dep_node_force!([dep_node, tcx]
         // These are inputs that are expected to be pre-allocated and that
         // should therefore always be red or green already.
-        crate::dep_graph::DepKind::CrateMetadata |
+        DepKind::CrateMetadata |
 
         // These are anonymous nodes.
-        crate::dep_graph::DepKind::TraitSelect |
+        DepKind::TraitSelect |
 
         // We don't have enough information to reconstruct the query key of
         // these.
-        crate::dep_graph::DepKind::CompileCodegenUnit => {
+        DepKind::CompileCodegenUnit => {
             bug!("force_from_dep_node: encountered {:?}", dep_node)
         }
     );
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index 21b8d7101a3..dfa9e38a466 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -282,6 +282,7 @@ CloneTypeFoldableAndLiftImpls! {
     ::rustc_hir::def::Res,
     ::rustc_hir::def_id::DefId,
     ::rustc_hir::def_id::LocalDefId,
+    ::rustc_hir::HirId,
     ::rustc_hir::LlvmInlineAsmInner,
     ::rustc_hir::MatchSource,
     ::rustc_hir::Mutability,
@@ -298,6 +299,7 @@ CloneTypeFoldableAndLiftImpls! {
     // really meant to be folded. In general, we can only fold a fully
     // general `Region`.
     crate::ty::BoundRegion,
+    crate::ty::AssocItem,
     crate::ty::Placeholder<crate::ty::BoundRegion>,
     crate::ty::ClosureKind,
     crate::ty::FreeRegion,
diff --git a/src/librustc_middle/ty/subst.rs b/src/librustc_middle/ty/subst.rs
index e9fd67a748c..866b529f35e 100644
--- a/src/librustc_middle/ty/subst.rs
+++ b/src/librustc_middle/ty/subst.rs
@@ -425,8 +425,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
         substs: &[GenericArg<'tcx>],
         span: Option<Span>,
     ) -> T {
-        let mut folder =
-            SubstFolder { tcx, substs, span, root_ty: None, ty_stack_depth: 0, binders_passed: 0 };
+        let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 };
         (*self).fold_with(&mut folder)
     }
 }
@@ -441,12 +440,6 @@ struct SubstFolder<'a, 'tcx> {
     /// The location for which the substitution is performed, if available.
     span: Option<Span>,
 
-    /// The root type that is being substituted, if available.
-    root_ty: Option<Ty<'tcx>>,
-
-    /// Depth of type stack
-    ty_stack_depth: usize,
-
     /// Number of region binders we have passed through while doing the substitution
     binders_passed: u32,
 }
@@ -478,9 +471,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
                         let span = self.span.unwrap_or(DUMMY_SP);
                         let msg = format!(
                             "Region parameter out of range \
-                             when substituting in region {} (root type={:?}) \
-                             (index={})",
-                            data.name, self.root_ty, data.index
+                             when substituting in region {} (index={})",
+                            data.name, data.index
                         );
                         span_bug!(span, "{}", msg);
                     }
@@ -495,25 +487,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
             return t;
         }
 
-        // track the root type we were asked to substitute
-        let depth = self.ty_stack_depth;
-        if depth == 0 {
-            self.root_ty = Some(t);
-        }
-        self.ty_stack_depth += 1;
-
-        let t1 = match t.kind {
+        match t.kind {
             ty::Param(p) => self.ty_for_param(p, t),
             _ => t.super_fold_with(self),
-        };
-
-        assert_eq!(depth + 1, self.ty_stack_depth);
-        self.ty_stack_depth -= 1;
-        if depth == 0 {
-            self.root_ty = None;
         }
-
-        t1
     }
 
     fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
@@ -540,12 +517,11 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
                 span_bug!(
                     span,
                     "expected type for `{:?}` ({:?}/{}) but found {:?} \
-                     when substituting (root type={:?}) substs={:?}",
+                     when substituting, substs={:?}",
                     p,
                     source_ty,
                     p.index,
                     kind,
-                    self.root_ty,
                     self.substs,
                 );
             }
@@ -554,11 +530,10 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
                 span_bug!(
                     span,
                     "type parameter `{:?}` ({:?}/{}) out of range \
-                     when substituting (root type={:?}) substs={:?}",
+                     when substituting, substs={:?}",
                     p,
                     source_ty,
                     p.index,
-                    self.root_ty,
                     self.substs,
                 );
             }
diff --git a/src/librustc_middle/ty/trait_def.rs b/src/librustc_middle/ty/trait_def.rs
index 8f125098ee6..f93cce3f4da 100644
--- a/src/librustc_middle/ty/trait_def.rs
+++ b/src/librustc_middle/ty/trait_def.rs
@@ -187,32 +187,38 @@ pub(super) fn all_local_trait_impls<'tcx>(
 pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls {
     let mut impls = TraitImpls::default();
 
-    {
-        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;
-            }
-
-            if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) {
-                impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
-            } else {
-                impls.blanket_impls.push(impl_def_id);
-            }
-        };
-
-        // Traits defined in the current crate can't have impls in upstream
-        // crates, so we don't bother querying the cstore.
-        if !trait_id.is_local() {
-            for &cnum in tcx.crates().iter() {
-                for &def_id in tcx.implementations_of_trait((cnum, trait_id)).iter() {
-                    add_impl(def_id);
+    // Traits defined in the current crate can't have impls in upstream
+    // crates, so we don't bother querying the cstore.
+    if !trait_id.is_local() {
+        for &cnum in tcx.crates().iter() {
+            for &(impl_def_id, simplified_self_ty) in
+                tcx.implementations_of_trait((cnum, trait_id)).iter()
+            {
+                if let Some(simplified_self_ty) = simplified_self_ty {
+                    impls
+                        .non_blanket_impls
+                        .entry(simplified_self_ty)
+                        .or_default()
+                        .push(impl_def_id);
+                } else {
+                    impls.blanket_impls.push(impl_def_id);
                 }
             }
         }
+    }
+
+    for &hir_id in tcx.hir().trait_impls(trait_id) {
+        let impl_def_id = tcx.hir().local_def_id(hir_id).to_def_id();
+
+        let impl_self_ty = tcx.type_of(impl_def_id);
+        if impl_self_ty.references_error() {
+            continue;
+        }
 
-        for &hir_id in tcx.hir().trait_impls(trait_id) {
-            add_impl(tcx.hir().local_def_id(hir_id).to_def_id());
+        if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) {
+            impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
+        } else {
+            impls.blanket_impls.push(impl_def_id);
         }
     }
 
diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs
index db78fa535cf..07221082048 100644
--- a/src/librustc_middle/ty/util.rs
+++ b/src/librustc_middle/ty/util.rs
@@ -585,7 +585,7 @@ struct OpaqueTypeExpander<'tcx> {
     found_recursion: bool,
     /// Whether or not to check for recursive opaque types.
     /// This is `true` when we're explicitly checking for opaque type
-    /// recursion, and 'false' otherwise to avoid unecessary work.
+    /// recursion, and 'false' otherwise to avoid unnecessary work.
     check_recursion: bool,
     tcx: TyCtxt<'tcx>,
 }
diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs
index 003c40f290b..2113d40a594 100644
--- a/src/librustc_mir/dataflow/framework/engine.rs
+++ b/src/librustc_mir/dataflow/framework/engine.rs
@@ -339,7 +339,7 @@ impl RustcMirAttrs {
             .flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter()));
 
         for attr in rustc_mir_attrs {
-            let attr_result = if attr.check_name(sym::borrowck_graphviz_postflow) {
+            let attr_result = if attr.has_name(sym::borrowck_graphviz_postflow) {
                 Self::set_field(&mut ret.basename_and_suffix, tcx, &attr, |s| {
                     let path = PathBuf::from(s.to_string());
                     match path.file_name() {
@@ -350,7 +350,7 @@ impl RustcMirAttrs {
                         }
                     }
                 })
-            } else if attr.check_name(sym::borrowck_graphviz_format) {
+            } else if attr.has_name(sym::borrowck_graphviz_format) {
                 Self::set_field(&mut ret.formatter, tcx, &attr, |s| match s {
                     sym::gen_kill | sym::two_phase => Ok(s),
                     _ => {
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index ae1328dbd12..8a9edb23a10 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -34,7 +34,7 @@ pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Opti
             let items = attr.meta_item_list();
             for item in items.iter().flat_map(|l| l.iter()) {
                 match item.meta_item() {
-                    Some(mi) if mi.check_name(name) => return Some(mi.clone()),
+                    Some(mi) if mi.has_name(name) => return Some(mi.clone()),
                     _ => continue,
                 }
             }
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index a9e6e324eb2..7dfa913fd08 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -952,7 +952,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
 
         if compressed.no_bytes_init() {
             // Fast path: If all bytes are `uninit` then there is nothing to copy. The target range
-            // is marked as unititialized but we otherwise omit changing the byte representation which may
+            // is marked as uninitialized but we otherwise omit changing the byte representation which may
             // be arbitrary for uninitialized bytes.
             // This also avoids writing to the target bytes so that the backing allocation is never
             // touched if the bytes stay uninitialized for the whole interpreter execution. On contemporary
diff --git a/src/librustc_mir/interpret/util.rs b/src/librustc_mir/interpret/util.rs
index c0eac8a9305..57c5fc59cc0 100644
--- a/src/librustc_mir/interpret/util.rs
+++ b/src/librustc_mir/interpret/util.rs
@@ -47,14 +47,26 @@ where
                             unused_params.contains(index).map(|unused| !unused).unwrap_or(true);
                         // Only recurse when generic parameters in fns, closures and generators
                         // are used and require substitution.
-                        if is_used && subst.needs_subst() {
+                        match (is_used, subst.needs_subst()) {
                             // Just in case there are closures or generators within this subst,
                             // recurse.
-                            if subst.super_visit_with(self) {
+                            (true, true) if subst.super_visit_with(self) => {
                                 // Only return when we find a parameter so the remaining substs
                                 // are not skipped.
                                 return true;
                             }
+                            // Confirm that polymorphization replaced the parameter with
+                            // `ty::Param`/`ty::ConstKind::Param`.
+                            (false, true) if cfg!(debug_assertions) => match subst.unpack() {
+                                ty::subst::GenericArgKind::Type(ty) => {
+                                    assert!(matches!(ty.kind, ty::Param(_)))
+                                }
+                                ty::subst::GenericArgKind::Const(ct) => {
+                                    assert!(matches!(ct.val, ty::ConstKind::Param(_)))
+                                }
+                                ty::subst::GenericArgKind::Lifetime(..) => (),
+                            },
+                            _ => {}
                         }
                     }
                     false
diff --git a/src/librustc_mir/monomorphize/polymorphize.rs b/src/librustc_mir/monomorphize/polymorphize.rs
index 562f512c5da..8fc1458f592 100644
--- a/src/librustc_mir/monomorphize/polymorphize.rs
+++ b/src/librustc_mir/monomorphize/polymorphize.rs
@@ -28,7 +28,7 @@ pub fn provide(providers: &mut Providers) {
 /// Determine which generic parameters are used by the function/method/closure represented by
 /// `def_id`. Returns a bitset where bits representing unused parameters are set (`is_empty`
 /// indicates all parameters are used).
-fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> {
+fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
     debug!("unused_generic_params({:?})", def_id);
 
     if !tcx.sess.opts.debugging_opts.polymorphize {
@@ -36,6 +36,13 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> {
         return FiniteBitSet::new_empty();
     }
 
+    // Polymorphization results are stored in cross-crate metadata only when there are unused
+    // parameters, so assume that non-local items must have only used parameters (else this query
+    // would not be invoked, and the cross-crate metadata used instead).
+    if !def_id.is_local() {
+        return FiniteBitSet::new_empty();
+    }
+
     let generics = tcx.generics_of(def_id);
     debug!("unused_generic_params: generics={:?}", generics);
 
@@ -53,7 +60,7 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> {
     // Create a bitset with N rightmost ones for each parameter.
     let generics_count: u32 =
         generics.count().try_into().expect("more generic parameters than can fit into a `u32`");
-    let mut unused_parameters = FiniteBitSet::<u64>::new_empty();
+    let mut unused_parameters = FiniteBitSet::<u32>::new_empty();
     unused_parameters.set_range(0..generics_count);
     debug!("unused_generic_params: (start) unused_parameters={:?}", unused_parameters);
     mark_used_by_default_parameters(tcx, def_id, generics, &mut unused_parameters);
@@ -84,7 +91,7 @@ fn mark_used_by_default_parameters<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
     generics: &'tcx ty::Generics,
-    unused_parameters: &mut FiniteBitSet<u64>,
+    unused_parameters: &mut FiniteBitSet<u32>,
 ) {
     if !tcx.is_trait(def_id) && (tcx.is_closure(def_id) || tcx.type_of(def_id).is_generator()) {
         for param in &generics.params {
@@ -110,11 +117,11 @@ fn mark_used_by_default_parameters<'tcx>(
 fn mark_used_by_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-    unused_parameters: &mut FiniteBitSet<u64>,
+    unused_parameters: &mut FiniteBitSet<u32>,
 ) {
     let def_id = tcx.closure_base_def_id(def_id);
 
-    let is_self_ty_used = |unused_parameters: &mut FiniteBitSet<u64>, self_ty: Ty<'tcx>| {
+    let is_self_ty_used = |unused_parameters: &mut FiniteBitSet<u32>, self_ty: Ty<'tcx>| {
         debug!("unused_generic_params: self_ty={:?}", self_ty);
         if let ty::Param(param) = self_ty.kind {
             !unused_parameters.contains(param.index).unwrap_or(false)
@@ -123,7 +130,7 @@ fn mark_used_by_predicates<'tcx>(
         }
     };
 
-    let mark_ty = |unused_parameters: &mut FiniteBitSet<u64>, ty: Ty<'tcx>| {
+    let mark_ty = |unused_parameters: &mut FiniteBitSet<u32>, ty: Ty<'tcx>| {
         let mut vis = UsedGenericParametersVisitor { tcx, def_id, unused_parameters };
         ty.visit_with(&mut vis);
     };
@@ -159,7 +166,7 @@ fn emit_unused_generic_params_error<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
     generics: &'tcx ty::Generics,
-    unused_parameters: &FiniteBitSet<u64>,
+    unused_parameters: &FiniteBitSet<u32>,
 ) {
     debug!("emit_unused_generic_params_error: def_id={:?}", def_id);
     let base_def_id = tcx.closure_base_def_id(def_id);
@@ -195,7 +202,7 @@ fn emit_unused_generic_params_error<'tcx>(
 struct UsedGenericParametersVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-    unused_parameters: &'a mut FiniteBitSet<u64>,
+    unused_parameters: &'a mut FiniteBitSet<u32>,
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {
diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/src/librustc_mir/transform/instrument_coverage.rs
index fe63a67fdbb..5b2954dd5b0 100644
--- a/src/librustc_mir/transform/instrument_coverage.rs
+++ b/src/librustc_mir/transform/instrument_coverage.rs
@@ -5,18 +5,19 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir::lang_items;
 use rustc_middle::hir;
 use rustc_middle::ich::StableHashingContext;
+use rustc_middle::mir;
 use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::traversal;
 use rustc_middle::mir::{
-    self, traversal, BasicBlock, BasicBlockData, CoverageInfo, Operand, Place, SourceInfo,
-    SourceScope, StatementKind, Terminator, TerminatorKind,
+    BasicBlock, BasicBlockData, CoverageInfo, Operand, Place, SourceInfo, SourceScope,
+    StatementKind, Terminator, TerminatorKind,
 };
 use rustc_middle::ty;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::FnDef;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{FnDef, TyCtxt};
 use rustc_span::def_id::DefId;
-use rustc_span::{Pos, Span};
+use rustc_span::{FileName, Pos, RealFileName, Span};
 
 /// Inserts call to count_code_region() as a placeholder to be replaced during code generation with
 /// the intrinsic llvm.instrprof.increment.
@@ -112,6 +113,7 @@ enum Op {
 struct InjectedCall<'tcx> {
     func: Operand<'tcx>,
     args: Vec<Operand<'tcx>>,
+    span: Span,
     inject_at: Span,
 }
 
@@ -179,12 +181,11 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         let _ignore = mir_body;
         let id = self.next_counter();
         let function_source_hash = self.function_source_hash();
-        let code_region = body_span;
         let scope = rustc_middle::mir::OUTERMOST_SOURCE_SCOPE;
         let is_cleanup = false;
         let next_block = rustc_middle::mir::START_BLOCK;
         self.inject_call(
-            self.make_counter(id, function_source_hash, code_region),
+            self.make_counter(id, function_source_hash, body_span),
             scope,
             is_cleanup,
             next_block,
@@ -201,14 +202,13 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
             let op = if add { Op::Add } else { Op::Subtract };
             let rhs = 2;
 
-            let code_region = body_span;
             let scope = rustc_middle::mir::OUTERMOST_SOURCE_SCOPE;
             let is_cleanup = false;
             let next_block = rustc_middle::mir::START_BLOCK;
 
             let id = self.next_expression();
             self.inject_call(
-                self.make_expression(id, code_region, lhs, op, rhs),
+                self.make_expression(id, body_span, lhs, op, rhs),
                 scope,
                 is_cleanup,
                 next_block,
@@ -216,13 +216,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         }
     }
 
-    fn make_counter(
-        &self,
-        id: u32,
-        function_source_hash: u64,
-        code_region: Span,
-    ) -> InjectedCall<'tcx> {
-        let inject_at = code_region.shrink_to_lo();
+    fn make_counter(&self, id: u32, function_source_hash: u64, span: Span) -> InjectedCall<'tcx> {
+        let inject_at = span.shrink_to_lo();
 
         let func = function_handle(
             self.tcx,
@@ -239,24 +234,18 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         debug_assert_eq!(COUNTER_ID, args.len());
         args.push(self.const_u32(id, inject_at));
 
-        debug_assert_eq!(START_BYTE_POS, args.len());
-        args.push(self.const_u32(code_region.lo().to_u32(), inject_at));
-
-        debug_assert_eq!(END_BYTE_POS, args.len());
-        args.push(self.const_u32(code_region.hi().to_u32(), inject_at));
-
-        InjectedCall { func, args, inject_at }
+        InjectedCall { func, args, span, inject_at }
     }
 
     fn make_expression(
         &self,
         id: u32,
-        code_region: Span,
+        span: Span,
         lhs: u32,
         op: Op,
         rhs: u32,
     ) -> InjectedCall<'tcx> {
-        let inject_at = code_region.shrink_to_lo();
+        let inject_at = span.shrink_to_lo();
 
         let func = function_handle(
             self.tcx,
@@ -282,13 +271,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         debug_assert_eq!(RIGHT_ID, args.len());
         args.push(self.const_u32(rhs, inject_at));
 
-        debug_assert_eq!(START_BYTE_POS, args.len());
-        args.push(self.const_u32(code_region.lo().to_u32(), inject_at));
-
-        debug_assert_eq!(END_BYTE_POS, args.len());
-        args.push(self.const_u32(code_region.hi().to_u32(), inject_at));
-
-        InjectedCall { func, args, inject_at }
+        InjectedCall { func, args, span, inject_at }
     }
 
     fn inject_call(
@@ -298,7 +281,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         is_cleanup: bool,
         next_block: BasicBlock,
     ) {
-        let InjectedCall { func, args, inject_at } = call;
+        let InjectedCall { func, mut args, span, inject_at } = call;
         debug!(
             "  injecting {}call to {:?}({:?}) at: {:?}, scope: {:?}",
             if is_cleanup { "cleanup " } else { "" },
@@ -310,6 +293,14 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
 
         let mut patch = MirPatch::new(self.mir_body);
 
+        let (file_name, start_line, start_col, end_line, end_col) = self.code_region(&span);
+
+        args.push(self.const_str(&file_name, inject_at));
+        args.push(self.const_u32(start_line, inject_at));
+        args.push(self.const_u32(start_col, inject_at));
+        args.push(self.const_u32(end_line, inject_at));
+        args.push(self.const_u32(end_col, inject_at));
+
         let temp = patch.new_temp(self.tcx.mk_unit(), inject_at);
         let new_block = patch.new_block(placeholder_block(inject_at, scope, is_cleanup));
         patch.patch_terminator(
@@ -335,6 +326,43 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         self.mir_body.basic_blocks_mut().swap(next_block, new_block);
     }
 
+    /// Convert the Span into its file name, start line and column, and end line and column
+    fn code_region(&self, span: &Span) -> (String, u32, u32, u32, u32) {
+        let source_map = self.tcx.sess.source_map();
+        let start = source_map.lookup_char_pos(span.lo());
+        let end = if span.hi() == span.lo() {
+            start.clone()
+        } else {
+            let end = source_map.lookup_char_pos(span.hi());
+            debug_assert_eq!(
+                start.file.name,
+                end.file.name,
+                "Region start ({:?} -> {:?}) and end ({:?} -> {:?}) don't come from the same source file!",
+                span.lo(),
+                start,
+                span.hi(),
+                end
+            );
+            end
+        };
+        match &start.file.name {
+            FileName::Real(RealFileName::Named(path)) => (
+                path.to_string_lossy().to_string(),
+                start.line as u32,
+                start.col.to_u32() + 1,
+                end.line as u32,
+                end.col.to_u32() + 1,
+            ),
+            _ => {
+                bug!("start.file.name should be a RealFileName, but it was: {:?}", start.file.name)
+            }
+        }
+    }
+
+    fn const_str(&self, value: &str, span: Span) -> Operand<'tcx> {
+        Operand::const_from_str(self.tcx, value, span)
+    }
+
     fn const_u32(&self, value: u32, span: Span) -> Operand<'tcx> {
         Operand::const_from_scalar(self.tcx, self.tcx.types.u32, Scalar::from_u32(value), span)
     }
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index f6847348063..f1a7338d11f 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -524,7 +524,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                                         // The `is_empty` predicate is introduced to exclude the case
                                         // where the projection operations are [ .field, * ].
                                         // The reason is because promotion will be illegal if field
-                                        // accesses preceed the dereferencing.
+                                        // accesses precede the dereferencing.
                                         // Discussion can be found at
                                         // https://github.com/rust-lang/rust/pull/74945#discussion_r463063247
                                         // There may be opportunity for generalization, but this needs to be
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index de7d7f27186..34fa840408f 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -193,7 +193,15 @@ fn check_rvalue(
             _,
         ) => Err((span, "function pointer casts are not allowed in const fn".into())),
         Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => {
-            let pointee_ty = cast_ty.builtin_deref(true).unwrap().ty;
+            let pointee_ty = if let Some(deref_ty) = cast_ty.builtin_deref(true) {
+                deref_ty.ty
+            } else {
+                // We cannot allow this for now.
+                return Err((
+                    span,
+                    "unsizing casts are only allowed for references right now".into(),
+                ));
+            };
             let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
             if let ty::Slice(_) | ty::Str = unsized_ty.kind {
                 check_operand(tcx, op, span, def_id, body)?;
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 9288d6e16f5..d8995e92abf 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -142,8 +142,6 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
                 }
 
                 self.basic_blocks[bb].terminator = Some(terminator);
-
-                changed |= inner_changed;
             }
 
             if !changed {
@@ -212,6 +210,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
                 Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } => target,
                 _ => unreachable!(),
             };
+            *changed |= *target != last;
             *target = last;
             debug!("collapsing goto chain from {:?} to {:?}", current, target);
 
@@ -223,7 +222,6 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
                 self.pred_count[*target] += 1;
                 self.pred_count[current] -= 1;
             }
-            *changed = true;
             self.basic_blocks[current].terminator = Some(terminator);
         }
     }
diff --git a/src/librustc_mir_build/thir/pattern/mod.rs b/src/librustc_mir_build/thir/pattern/mod.rs
index bdefaadfdfe..daff10eb194 100644
--- a/src/librustc_mir_build/thir/pattern/mod.rs
+++ b/src/librustc_mir_build/thir/pattern/mod.rs
@@ -133,7 +133,7 @@ crate enum PatKind<'tcx> {
         var: hir::HirId,
         ty: Ty<'tcx>,
         subpattern: Option<Pat<'tcx>>,
-        /// Is this the leftmost occurance of the binding, i.e., is `var` the
+        /// Is this the leftmost occurrence of the binding, i.e., is `var` the
         /// `HirId` of this pattern?
         is_primary: bool,
     },
diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml
index f214ec020cb..25144bd610d 100644
--- a/src/librustc_parse/Cargo.toml
+++ b/src/librustc_parse/Cargo.toml
@@ -21,3 +21,4 @@ rustc_session = { path = "../librustc_session" }
 rustc_span = { path = "../librustc_span" }
 rustc_ast = { path = "../librustc_ast" }
 unicode-normalization = "0.1.11"
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs
index be86b4b7c77..3319ca44da4 100644
--- a/src/librustc_parse/lib.rs
+++ b/src/librustc_parse/lib.rs
@@ -7,14 +7,16 @@
 #![feature(or_patterns)]
 
 use rustc_ast::ast;
-use rustc_ast::token::{self, Nonterminal};
+use rustc_ast::token::{self, DelimToken, Nonterminal, Token};
 use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Diagnostic, FatalError, Level, PResult};
 use rustc_session::parse::ParseSess;
-use rustc_span::{FileName, SourceFile, Span};
+use rustc_span::{symbol::kw, FileName, SourceFile, Span, DUMMY_SP};
 
+use smallvec::SmallVec;
+use std::mem;
 use std::path::Path;
 use std::str;
 
@@ -306,7 +308,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
     // modifications, including adding/removing typically non-semantic
     // tokens such as extra braces and commas, don't happen.
     if let Some(tokens) = tokens {
-        if tokens.probably_equal_for_proc_macro(&tokens_for_real) {
+        if tokenstream_probably_equal_for_proc_macro(&tokens, &tokens_for_real) {
             return tokens;
         }
         info!(
@@ -319,6 +321,186 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
     tokens_for_real
 }
 
+// See comments in `Nonterminal::to_tokenstream` for why we care about
+// *probably* equal here rather than actual equality
+//
+// This is otherwise the same as `eq_unspanned`, only recursing with a
+// different method.
+pub fn tokenstream_probably_equal_for_proc_macro(first: &TokenStream, other: &TokenStream) -> bool {
+    // When checking for `probably_eq`, we ignore certain tokens that aren't
+    // preserved in the AST. Because they are not preserved, the pretty
+    // printer arbitrarily adds or removes them when printing as token
+    // streams, making a comparison between a token stream generated from an
+    // AST and a token stream which was parsed into an AST more reliable.
+    fn semantic_tree(tree: &TokenTree) -> bool {
+        if let TokenTree::Token(token) = tree {
+            if let
+                // The pretty printer tends to add trailing commas to
+                // everything, and in particular, after struct fields.
+                | token::Comma
+                // The pretty printer emits `NoDelim` as whitespace.
+                | token::OpenDelim(DelimToken::NoDelim)
+                | token::CloseDelim(DelimToken::NoDelim)
+                // The pretty printer collapses many semicolons into one.
+                | token::Semi
+                // The pretty printer collapses whitespace arbitrarily and can
+                // introduce whitespace from `NoDelim`.
+                | token::Whitespace
+                // The pretty printer can turn `$crate` into `::crate_name`
+                | token::ModSep = token.kind {
+                return false;
+            }
+        }
+        true
+    }
+
+    // When comparing two `TokenStream`s, we ignore the `IsJoint` information.
+    //
+    // However, `rustc_parse::lexer::tokentrees::TokenStreamBuilder` will
+    // use `Token.glue` on adjacent tokens with the proper `IsJoint`.
+    // Since we are ignoreing `IsJoint`, a 'glued' token (e.g. `BinOp(Shr)`)
+    // and its 'split'/'unglued' compoenents (e.g. `Gt, Gt`) are equivalent
+    // when determining if two `TokenStream`s are 'probably equal'.
+    //
+    // Therefore, we use `break_two_token_op` to convert all tokens
+    // to the 'unglued' form (if it exists). This ensures that two
+    // `TokenStream`s which differ only in how their tokens are glued
+    // will be considered 'probably equal', which allows us to keep spans.
+    //
+    // This is important when the original `TokenStream` contained
+    // extra spaces (e.g. `f :: < Vec < _ > > ( ) ;'). These extra spaces
+    // will be omitted when we pretty-print, which can cause the original
+    // and reparsed `TokenStream`s to differ in the assignment of `IsJoint`,
+    // leading to some tokens being 'glued' together in one stream but not
+    // the other. See #68489 for more details.
+    fn break_tokens(tree: TokenTree) -> impl Iterator<Item = TokenTree> {
+        // In almost all cases, we should have either zero or one levels
+        // of 'unglueing'. However, in some unusual cases, we may need
+        // to iterate breaking tokens mutliple times. For example:
+        // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]'
+        let mut token_trees: SmallVec<[_; 2]>;
+        if let TokenTree::Token(token) = &tree {
+            let mut out = SmallVec::<[_; 2]>::new();
+            out.push(token.clone());
+            // Iterate to fixpoint:
+            // * We start off with 'out' containing our initial token, and `temp` empty
+            // * If we are able to break any tokens in `out`, then `out` will have
+            //   at least one more element than 'temp', so we will try to break tokens
+            //   again.
+            // * If we cannot break any tokens in 'out', we are done
+            loop {
+                let mut temp = SmallVec::<[_; 2]>::new();
+                let mut changed = false;
+
+                for token in out.into_iter() {
+                    if let Some((first, second)) = token.kind.break_two_token_op() {
+                        temp.push(Token::new(first, DUMMY_SP));
+                        temp.push(Token::new(second, DUMMY_SP));
+                        changed = true;
+                    } else {
+                        temp.push(token);
+                    }
+                }
+                out = temp;
+                if !changed {
+                    break;
+                }
+            }
+            token_trees = out.into_iter().map(TokenTree::Token).collect();
+            if token_trees.len() != 1 {
+                debug!("break_tokens: broke {:?} to {:?}", tree, token_trees);
+            }
+        } else {
+            token_trees = SmallVec::new();
+            token_trees.push(tree);
+        }
+        token_trees.into_iter()
+    }
+
+    let mut t1 = first.trees().filter(semantic_tree).flat_map(break_tokens);
+    let mut t2 = other.trees().filter(semantic_tree).flat_map(break_tokens);
+    for (t1, t2) in t1.by_ref().zip(t2.by_ref()) {
+        if !tokentree_probably_equal_for_proc_macro(&t1, &t2) {
+            return false;
+        }
+    }
+    t1.next().is_none() && t2.next().is_none()
+}
+
+// See comments in `Nonterminal::to_tokenstream` for why we care about
+// *probably* equal here rather than actual equality
+//
+// This is otherwise the same as `eq_unspanned`, only recursing with a
+// different method.
+fn tokentree_probably_equal_for_proc_macro(first: &TokenTree, other: &TokenTree) -> bool {
+    match (first, other) {
+        (TokenTree::Token(token), TokenTree::Token(token2)) => {
+            token_probably_equal_for_proc_macro(token, token2)
+        }
+        (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
+            delim == delim2 && tokenstream_probably_equal_for_proc_macro(&tts, &tts2)
+        }
+        _ => false,
+    }
+}
+
+// See comments in `Nonterminal::to_tokenstream` for why we care about
+// *probably* equal here rather than actual equality
+fn token_probably_equal_for_proc_macro(first: &Token, other: &Token) -> bool {
+    if mem::discriminant(&first.kind) != mem::discriminant(&other.kind) {
+        return false;
+    }
+    use rustc_ast::token::TokenKind::*;
+    match (&first.kind, &other.kind) {
+        (&Eq, &Eq)
+        | (&Lt, &Lt)
+        | (&Le, &Le)
+        | (&EqEq, &EqEq)
+        | (&Ne, &Ne)
+        | (&Ge, &Ge)
+        | (&Gt, &Gt)
+        | (&AndAnd, &AndAnd)
+        | (&OrOr, &OrOr)
+        | (&Not, &Not)
+        | (&Tilde, &Tilde)
+        | (&At, &At)
+        | (&Dot, &Dot)
+        | (&DotDot, &DotDot)
+        | (&DotDotDot, &DotDotDot)
+        | (&DotDotEq, &DotDotEq)
+        | (&Comma, &Comma)
+        | (&Semi, &Semi)
+        | (&Colon, &Colon)
+        | (&ModSep, &ModSep)
+        | (&RArrow, &RArrow)
+        | (&LArrow, &LArrow)
+        | (&FatArrow, &FatArrow)
+        | (&Pound, &Pound)
+        | (&Dollar, &Dollar)
+        | (&Question, &Question)
+        | (&Whitespace, &Whitespace)
+        | (&Comment, &Comment)
+        | (&Eof, &Eof) => true,
+
+        (&BinOp(a), &BinOp(b)) | (&BinOpEq(a), &BinOpEq(b)) => a == b,
+
+        (&OpenDelim(a), &OpenDelim(b)) | (&CloseDelim(a), &CloseDelim(b)) => a == b,
+
+        (&DocComment(a), &DocComment(b)) | (&Shebang(a), &Shebang(b)) => a == b,
+
+        (&Literal(a), &Literal(b)) => a == b,
+
+        (&Lifetime(a), &Lifetime(b)) => a == b,
+        (&Ident(a, b), &Ident(c, d)) => {
+            b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate)
+        }
+
+        (&Interpolated(..), &Interpolated(..)) => false,
+
+        _ => panic!("forgot to add a token?"),
+    }
+}
+
 fn prepend_attrs(
     sess: &ParseSess,
     attrs: &[ast::Attribute],
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 609a0c961e9..5e9411327ca 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -333,6 +333,7 @@ impl<'a> Parser<'a> {
                         Applicability::MachineApplicable
                     },
                 );
+                self.sess.type_ascription_path_suggestions.borrow_mut().insert(sp);
             } else if op_pos.line != next_pos.line && maybe_expected_semicolon {
                 err.span_suggestion(
                     sp,
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index d06b172bc14..3aec300d86d 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -1450,7 +1450,7 @@ impl<'a> Parser<'a> {
 
     /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
     /// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
-    pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
+    pub(super) fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
         maybe_whole_expr!(self);
 
         let lo = self.token.span;
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 72866468b65..2509a979221 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -1,16 +1,17 @@
 pub mod attr;
+mod diagnostics;
 mod expr;
+mod generics;
 mod item;
+mod nonterminal;
 mod pat;
 mod path;
-mod ty;
-pub use path::PathStyle;
-mod diagnostics;
-mod generics;
 mod stmt;
-use diagnostics::Error;
+mod ty;
 
 use crate::lexer::UnmatchedBrace;
+use diagnostics::Error;
+pub use path::PathStyle;
 
 use log::debug;
 use rustc_ast::ast::DUMMY_NODE_ID;
@@ -958,7 +959,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a single token tree from the input.
-    pub fn parse_token_tree(&mut self) -> TokenTree {
+    pub(crate) fn parse_token_tree(&mut self) -> TokenTree {
         match self.token.kind {
             token::OpenDelim(..) => {
                 let frame = mem::replace(
@@ -1017,7 +1018,7 @@ impl<'a> Parser<'a> {
     /// If the following element can't be a tuple (i.e., it's a function definition), then
     /// it's not a tuple struct field), and the contents within the parentheses isn't valid,
     /// so emit a proper diagnostic.
-    pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
+    pub(crate) fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
         maybe_whole!(self, NtVis, |x| x);
 
         self.expected_tokens.push(TokenType::Keyword(kw::Crate));
diff --git a/src/librustc_parse/parser/nonterminal.rs b/src/librustc_parse/parser/nonterminal.rs
new file mode 100644
index 00000000000..12139771bbf
--- /dev/null
+++ b/src/librustc_parse/parser/nonterminal.rs
@@ -0,0 +1,163 @@
+use rustc_ast::ptr::P;
+use rustc_ast::token::{self, Nonterminal, NonterminalKind, Token};
+use rustc_ast_pretty::pprust;
+use rustc_errors::PResult;
+use rustc_span::symbol::{kw, Ident};
+
+use crate::parser::{FollowedByType, Parser, PathStyle};
+
+impl<'a> Parser<'a> {
+    /// Checks whether a non-terminal may begin with a particular token.
+    ///
+    /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that
+    /// token. Be conservative (return true) if not sure.
+    pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool {
+        /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
+        fn may_be_ident(nt: &token::Nonterminal) -> bool {
+            match *nt {
+                token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => {
+                    false
+                }
+                _ => true,
+            }
+        }
+
+        match kind {
+            NonterminalKind::Expr => {
+                token.can_begin_expr()
+                // This exception is here for backwards compatibility.
+                && !token.is_keyword(kw::Let)
+            }
+            NonterminalKind::Ty => token.can_begin_type(),
+            NonterminalKind::Ident => get_macro_ident(token).is_some(),
+            NonterminalKind::Literal => token.can_begin_literal_maybe_minus(),
+            NonterminalKind::Vis => match token.kind {
+                // The follow-set of :vis + "priv" keyword + interpolated
+                token::Comma | token::Ident(..) | token::Interpolated(..) => true,
+                _ => token.can_begin_type(),
+            },
+            NonterminalKind::Block => match token.kind {
+                token::OpenDelim(token::Brace) => true,
+                token::Interpolated(ref nt) => match **nt {
+                    token::NtItem(_)
+                    | token::NtPat(_)
+                    | token::NtTy(_)
+                    | token::NtIdent(..)
+                    | token::NtMeta(_)
+                    | token::NtPath(_)
+                    | token::NtVis(_) => false, // none of these may start with '{'.
+                    _ => true,
+                },
+                _ => false,
+            },
+            NonterminalKind::Path | NonterminalKind::Meta => match token.kind {
+                token::ModSep | token::Ident(..) => true,
+                token::Interpolated(ref nt) => match **nt {
+                    token::NtPath(_) | token::NtMeta(_) => true,
+                    _ => may_be_ident(&nt),
+                },
+                _ => false,
+            },
+            NonterminalKind::Pat => match token.kind {
+                token::Ident(..) |                  // box, ref, mut, and other identifiers (can stricten)
+                token::OpenDelim(token::Paren) |    // tuple pattern
+                token::OpenDelim(token::Bracket) |  // slice pattern
+                token::BinOp(token::And) |          // reference
+                token::BinOp(token::Minus) |        // negative literal
+                token::AndAnd |                     // double reference
+                token::Literal(..) |                // literal
+                token::DotDot |                     // range pattern (future compat)
+                token::DotDotDot |                  // range pattern (future compat)
+                token::ModSep |                     // path
+                token::Lt |                         // path (UFCS constant)
+                token::BinOp(token::Shl) => true,   // path (double UFCS)
+                token::Interpolated(ref nt) => may_be_ident(nt),
+                _ => false,
+            },
+            NonterminalKind::Lifetime => match token.kind {
+                token::Lifetime(_) => true,
+                token::Interpolated(ref nt) => match **nt {
+                    token::NtLifetime(_) | token::NtTT(_) => true,
+                    _ => false,
+                },
+                _ => false,
+            },
+            NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => match token.kind
+            {
+                token::CloseDelim(_) => false,
+                _ => true,
+            },
+        }
+    }
+
+    pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, Nonterminal> {
+        // Any `Nonterminal` which stores its tokens (currently `NtItem` and `NtExpr`)
+        // needs to have them force-captured here.
+        // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro,
+        // which requires having captured tokens available. Since we cannot determine
+        // in advance whether or not a proc-macro will be (transitively) invoked,
+        // we always capture tokens for any `Nonterminal` which needs them.
+        Ok(match kind {
+            NonterminalKind::Item => match self.collect_tokens(|this| this.parse_item())? {
+                (Some(mut item), tokens) => {
+                    // If we captured tokens during parsing (due to outer attributes),
+                    // use those.
+                    if item.tokens.is_none() {
+                        item.tokens = Some(tokens);
+                    }
+                    token::NtItem(item)
+                }
+                (None, _) => {
+                    return Err(self.struct_span_err(self.token.span, "expected an item keyword"));
+                }
+            },
+            NonterminalKind::Block => token::NtBlock(self.parse_block()?),
+            NonterminalKind::Stmt => match self.parse_stmt()? {
+                Some(s) => token::NtStmt(s),
+                None => return Err(self.struct_span_err(self.token.span, "expected a statement")),
+            },
+            NonterminalKind::Pat => token::NtPat(self.parse_pat(None)?),
+            NonterminalKind::Expr => {
+                let (mut expr, tokens) = self.collect_tokens(|this| this.parse_expr())?;
+                // If we captured tokens during parsing (due to outer attributes),
+                // use those.
+                if expr.tokens.is_none() {
+                    expr.tokens = Some(tokens);
+                }
+                token::NtExpr(expr)
+            }
+            NonterminalKind::Literal => token::NtLiteral(self.parse_literal_maybe_minus()?),
+            NonterminalKind::Ty => token::NtTy(self.parse_ty()?),
+            // this could be handled like a token, since it is one
+            NonterminalKind::Ident => {
+                if let Some((ident, is_raw)) = get_macro_ident(&self.token) {
+                    self.bump();
+                    token::NtIdent(ident, is_raw)
+                } else {
+                    let token_str = pprust::token_to_string(&self.token);
+                    let msg = &format!("expected ident, found {}", &token_str);
+                    return Err(self.struct_span_err(self.token.span, msg));
+                }
+            }
+            NonterminalKind::Path => token::NtPath(self.parse_path(PathStyle::Type)?),
+            NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item()?)),
+            NonterminalKind::TT => token::NtTT(self.parse_token_tree()),
+            NonterminalKind::Vis => token::NtVis(self.parse_visibility(FollowedByType::Yes)?),
+            NonterminalKind::Lifetime => {
+                if self.check_lifetime() {
+                    token::NtLifetime(self.expect_lifetime().ident)
+                } else {
+                    let token_str = pprust::token_to_string(&self.token);
+                    let msg = &format!("expected a lifetime, found `{}`", &token_str);
+                    return Err(self.struct_span_err(self.token.span, msg));
+                }
+            }
+        })
+    }
+}
+
+/// The token is an identifier, but not `_`.
+/// We prohibit passing `_` to macros expecting `ident` for now.
+fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> {
+    token.ident().filter(|(ident, _)| ident.name != kw::Underscore)
+}
diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs
index 3dcefd36257..d4e44c54b12 100644
--- a/src/librustc_parse/parser/path.rs
+++ b/src/librustc_parse/parser/path.rs
@@ -125,7 +125,7 @@ impl<'a> Parser<'a> {
     /// `a::b::C::<D>` (with disambiguator)
     /// `Fn(Args)` (without disambiguator)
     /// `Fn::(Args)` (with disambiguator)
-    pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> {
+    pub(super) fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> {
         maybe_whole!(self, NtPath, |path| {
             if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some())
             {
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index d04920de47f..5c3a5e99873 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -21,7 +21,7 @@ use std::mem;
 impl<'a> Parser<'a> {
     /// Parses a statement. This stops just before trailing semicolons on everything but items.
     /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
-    pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
+    pub(super) fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
         Ok(self.parse_stmt_without_recovery().unwrap_or_else(|mut e| {
             e.emit();
             self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
@@ -247,7 +247,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a block. No inner attributes are allowed.
-    pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
+    pub(super) fn parse_block(&mut self) -> PResult<'a, P<Block>> {
         let (attrs, block) = self.parse_inner_attrs_and_block()?;
         if let [.., last] = &*attrs {
             self.error_on_forbidden_inner_attr(last.span, DEFAULT_INNER_ATTR_FORBIDDEN);
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index a6015504a32..cd66b917f23 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -610,13 +610,13 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub fn check_lifetime(&mut self) -> bool {
+    pub(super) fn check_lifetime(&mut self) -> bool {
         self.expected_tokens.push(TokenType::Lifetime);
         self.token.is_lifetime()
     }
 
     /// Parses a single lifetime `'a` or panics.
-    pub fn expect_lifetime(&mut self) -> Lifetime {
+    pub(super) fn expect_lifetime(&mut self) -> Lifetime {
         if let Some(ident) = self.token.lifetime() {
             self.bump();
             Lifetime { ident, id: ast::DUMMY_NODE_ID }
diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs
index 3e63a63d9d0..1ff47ee038d 100644
--- a/src/librustc_passes/check_attr.rs
+++ b/src/librustc_passes/check_attr.rs
@@ -222,7 +222,7 @@ impl CheckAttrVisitor<'tcx> {
         if let Some(mi) = attr.meta() {
             if let Some(list) = mi.meta_item_list() {
                 for meta in list {
-                    if meta.check_name(sym::alias) {
+                    if meta.has_name(sym::alias) {
                         if !meta.is_value_str()
                             || meta
                                 .value_str()
diff --git a/src/librustc_query_system/cache.rs b/src/librustc_query_system/cache.rs
new file mode 100644
index 00000000000..be3d3607728
--- /dev/null
+++ b/src/librustc_query_system/cache.rs
@@ -0,0 +1,62 @@
+//! Cache for candidate selection.
+
+use crate::dep_graph::DepNodeIndex;
+use crate::query::QueryContext;
+
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::HashMapExt;
+use rustc_data_structures::sync::Lock;
+
+use std::hash::Hash;
+
+#[derive(Clone)]
+pub struct Cache<Key, Value> {
+    hashmap: Lock<FxHashMap<Key, WithDepNode<Value>>>,
+}
+
+impl<Key, Value> Default for Cache<Key, Value> {
+    fn default() -> Self {
+        Self { hashmap: Default::default() }
+    }
+}
+
+impl<Key, Value> Cache<Key, Value> {
+    /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
+    pub fn clear(&self) {
+        *self.hashmap.borrow_mut() = Default::default();
+    }
+}
+
+impl<Key: Eq + Hash, Value: Clone> Cache<Key, Value> {
+    pub fn get<CTX: QueryContext>(&self, key: &Key, tcx: CTX) -> Option<Value> {
+        Some(self.hashmap.borrow().get(key)?.get(tcx))
+    }
+
+    pub fn insert(&self, key: Key, dep_node: DepNodeIndex, value: Value) {
+        self.hashmap.borrow_mut().insert(key, WithDepNode::new(dep_node, value));
+    }
+
+    pub fn insert_same(&self, key: Key, dep_node: DepNodeIndex, value: Value)
+    where
+        Value: Eq,
+    {
+        self.hashmap.borrow_mut().insert_same(key, WithDepNode::new(dep_node, value));
+    }
+}
+
+#[derive(Clone, Eq, PartialEq)]
+pub struct WithDepNode<T> {
+    dep_node: DepNodeIndex,
+    cached_value: T,
+}
+
+impl<T: Clone> WithDepNode<T> {
+    pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self {
+        WithDepNode { dep_node, cached_value }
+    }
+
+    pub fn get<CTX: QueryContext>(&self, tcx: CTX) -> T {
+        tcx.dep_graph().read_index(self.dep_node);
+        self.cached_value.clone()
+    }
+}
diff --git a/src/librustc_query_system/lib.rs b/src/librustc_query_system/lib.rs
index b7615b25c4a..4bbba7befe9 100644
--- a/src/librustc_query_system/lib.rs
+++ b/src/librustc_query_system/lib.rs
@@ -11,5 +11,6 @@ extern crate log;
 #[macro_use]
 extern crate rustc_data_structures;
 
+pub mod cache;
 pub mod dep_graph;
 pub mod query;
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index bcd2c6c1f1c..44ff4209095 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1510,30 +1510,18 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         pat_src: PatternSource,
         bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
     ) {
-        let is_tuple_struct_pat = matches!(pat.kind, PatKind::TupleStruct(_, _));
-
         // Visit all direct subpatterns of this pattern.
         pat.walk(&mut |pat| {
             debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind);
             match pat.kind {
                 PatKind::Ident(bmode, ident, ref sub) => {
-                    if is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some() {
-                        // In tuple struct patterns ignore the invalid `ident @ ...`.
-                        // It will be handled as an error by the AST lowering.
-                        self.r
-                            .session
-                            .delay_span_bug(ident.span, "ident in tuple pattern is invalid");
-                    } else {
-                        // First try to resolve the identifier as some existing entity,
-                        // then fall back to a fresh binding.
-                        let has_sub = sub.is_some();
-                        let res = self
-                            .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
-                            .unwrap_or_else(|| {
-                                self.fresh_binding(ident, pat.id, pat_src, bindings)
-                            });
-                        self.r.record_partial_res(pat.id, PartialRes::new(res));
-                    }
+                    // First try to resolve the identifier as some existing entity,
+                    // then fall back to a fresh binding.
+                    let has_sub = sub.is_some();
+                    let res = self
+                        .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
+                        .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings));
+                    self.r.record_partial_res(pat.id, PartialRes::new(res));
                 }
                 PatKind::TupleStruct(ref path, ..) => {
                     self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct(pat.span));
@@ -2241,8 +2229,15 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     self.resolve_expr(argument, None);
                 }
             }
-            ExprKind::Type(ref type_expr, _) => {
-                self.diagnostic_metadata.current_type_ascription.push(type_expr.span);
+            ExprKind::Type(ref type_expr, ref ty) => {
+                // `ParseSess::type_ascription_path_suggestions` keeps spans of colon tokens in
+                // type ascription. Here we are trying to retrieve the span of the colon token as
+                // well, but only if it's written without spaces `expr:Ty` and therefore confusable
+                // with `expr::Ty`, only in this case it will match the span from
+                // `type_ascription_path_suggestions`.
+                self.diagnostic_metadata
+                    .current_type_ascription
+                    .push(type_expr.span.between(ty.span));
                 visit::walk_expr(self, expr);
                 self.diagnostic_metadata.current_type_ascription.pop();
             }
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index c86b4141847..ec6dbb070df 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -17,7 +17,7 @@ use rustc_hir::PrimTy;
 use rustc_session::config::nightly_options;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Ident};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
 
 use log::debug;
 
@@ -223,13 +223,31 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
         if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) {
             let enum_candidates =
                 self.r.lookup_import_candidates(ident, ns, &self.parent_scope, is_enum_variant);
-            let mut enum_candidates = enum_candidates
-                .iter()
-                .map(|suggestion| import_candidate_to_enum_paths(&suggestion))
-                .collect::<Vec<_>>();
-            enum_candidates.sort();
 
             if !enum_candidates.is_empty() {
+                if let (PathSource::Type, Some(span)) =
+                    (source, self.diagnostic_metadata.current_type_ascription.last())
+                {
+                    if self
+                        .r
+                        .session
+                        .parse_sess
+                        .type_ascription_path_suggestions
+                        .borrow()
+                        .contains(span)
+                    {
+                        // Already reported this issue on the lhs of the type ascription.
+                        err.delay_as_bug();
+                        return (err, candidates);
+                    }
+                }
+
+                let mut enum_candidates = enum_candidates
+                    .iter()
+                    .map(|suggestion| import_candidate_to_enum_paths(&suggestion))
+                    .collect::<Vec<_>>();
+                enum_candidates.sort();
+
                 // Contextualize for E0412 "cannot find type", but don't belabor the point
                 // (that it's a variant) for E0573 "expected type, found variant".
                 let preamble = if res.is_none() {
@@ -484,10 +502,21 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
             match source {
                 PathSource::Expr(Some(
                     parent @ Expr { kind: ExprKind::Field(..) | ExprKind::MethodCall(..), .. },
-                )) => {
-                    path_sep(err, &parent);
-                }
-                PathSource::Expr(None) if followed_by_brace => {
+                )) if path_sep(err, &parent) => {}
+                PathSource::Expr(
+                    None
+                    | Some(Expr {
+                        kind:
+                            ExprKind::Path(..)
+                            | ExprKind::Binary(..)
+                            | ExprKind::Unary(..)
+                            | ExprKind::If(..)
+                            | ExprKind::While(..)
+                            | ExprKind::ForLoop(..)
+                            | ExprKind::Match(..),
+                        ..
+                    }),
+                ) if followed_by_brace => {
                     if let Some(sp) = closing_brace {
                         err.multipart_suggestion(
                             "surround the struct literal with parentheses",
@@ -508,11 +537,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
                         );
                     }
                 }
-                PathSource::Expr(
-                    None | Some(Expr { kind: ExprKind::Call(..) | ExprKind::Path(..), .. }),
-                )
-                | PathSource::TupleStruct(_)
-                | PathSource::Pat => {
+                PathSource::Expr(_) | PathSource::TupleStruct(_) | PathSource::Pat => {
                     let span = match &source {
                         PathSource::Expr(Some(Expr {
                             span, kind: ExprKind::Call(_, _), ..
@@ -593,6 +618,24 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
                 Res::Def(DefKind::Enum, def_id),
                 PathSource::TupleStruct(_) | PathSource::Expr(..),
             ) => {
+                if self
+                    .diagnostic_metadata
+                    .current_type_ascription
+                    .last()
+                    .map(|sp| {
+                        self.r
+                            .session
+                            .parse_sess
+                            .type_ascription_path_suggestions
+                            .borrow()
+                            .contains(&sp)
+                    })
+                    .unwrap_or(false)
+                {
+                    err.delay_as_bug();
+                    // We already suggested changing `:` into `::` during parsing.
+                    return false;
+                }
                 if let Some(variants) = self.collect_enum_variants(def_id) {
                     if !variants.is_empty() {
                         let msg = if variants.len() == 1 {
@@ -609,7 +652,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
                         );
                     }
                 } else {
-                    err.note("did you mean to use one of the enum's variants?");
+                    err.note("you might have meant to use one of the enum's variants");
                 }
             }
             (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => {
@@ -829,77 +872,73 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
     fn type_ascription_suggestion(&self, err: &mut DiagnosticBuilder<'_>, base_span: Span) {
         let sm = self.r.session.source_map();
         let base_snippet = sm.span_to_snippet(base_span);
-        if let Some(sp) = self.diagnostic_metadata.current_type_ascription.last() {
-            let mut sp = *sp;
-            loop {
-                // Try to find the `:`; bail on first non-':' / non-whitespace.
-                sp = sm.next_point(sp);
-                if let Ok(snippet) = sm.span_to_snippet(sp.to(sm.next_point(sp))) {
-                    let line_sp = sm.lookup_char_pos(sp.hi()).line;
-                    let line_base_sp = sm.lookup_char_pos(base_span.lo()).line;
-                    if snippet == ":" {
-                        let mut show_label = true;
-                        if line_sp != line_base_sp {
-                            err.span_suggestion_short(
-                                sp,
-                                "did you mean to use `;` here instead?",
-                                ";".to_string(),
+        if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() {
+            if let Ok(snippet) = sm.span_to_snippet(sp) {
+                let len = snippet.trim_end().len() as u32;
+                if snippet.trim() == ":" {
+                    let colon_sp =
+                        sp.with_lo(sp.lo() + BytePos(len - 1)).with_hi(sp.lo() + BytePos(len));
+                    let mut show_label = true;
+                    if sm.is_multiline(sp) {
+                        err.span_suggestion_short(
+                            colon_sp,
+                            "maybe you meant to write `;` here",
+                            ";".to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    } else {
+                        let after_colon_sp =
+                            self.get_colon_suggestion_span(colon_sp.shrink_to_hi());
+                        if snippet.len() == 1 {
+                            // `foo:bar`
+                            err.span_suggestion(
+                                colon_sp,
+                                "maybe you meant to write a path separator here",
+                                "::".to_string(),
                                 Applicability::MaybeIncorrect,
                             );
-                        } else {
-                            let colon_sp = self.get_colon_suggestion_span(sp);
-                            let after_colon_sp =
-                                self.get_colon_suggestion_span(colon_sp.shrink_to_hi());
-                            if !sm
-                                .span_to_snippet(after_colon_sp)
-                                .map(|s| s == " ")
-                                .unwrap_or(false)
+                            show_label = false;
+                            if !self
+                                .r
+                                .session
+                                .parse_sess
+                                .type_ascription_path_suggestions
+                                .borrow_mut()
+                                .insert(colon_sp)
                             {
-                                err.span_suggestion(
-                                    colon_sp,
-                                    "maybe you meant to write a path separator here",
-                                    "::".to_string(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                                show_label = false;
+                                err.delay_as_bug();
                             }
-                            if let Ok(base_snippet) = base_snippet {
-                                let mut sp = after_colon_sp;
-                                for _ in 0..100 {
-                                    // Try to find an assignment
-                                    sp = sm.next_point(sp);
-                                    let snippet = sm.span_to_snippet(sp.to(sm.next_point(sp)));
-                                    match snippet {
-                                        Ok(ref x) if x.as_str() == "=" => {
-                                            err.span_suggestion(
-                                                base_span,
-                                                "maybe you meant to write an assignment here",
-                                                format!("let {}", base_snippet),
-                                                Applicability::MaybeIncorrect,
-                                            );
-                                            show_label = false;
-                                            break;
-                                        }
-                                        Ok(ref x) if x.as_str() == "\n" => break,
-                                        Err(_) => break,
-                                        Ok(_) => {}
+                        }
+                        if let Ok(base_snippet) = base_snippet {
+                            let mut sp = after_colon_sp;
+                            for _ in 0..100 {
+                                // Try to find an assignment
+                                sp = sm.next_point(sp);
+                                let snippet = sm.span_to_snippet(sp.to(sm.next_point(sp)));
+                                match snippet {
+                                    Ok(ref x) if x.as_str() == "=" => {
+                                        err.span_suggestion(
+                                            base_span,
+                                            "maybe you meant to write an assignment here",
+                                            format!("let {}", base_snippet),
+                                            Applicability::MaybeIncorrect,
+                                        );
+                                        show_label = false;
+                                        break;
                                     }
+                                    Ok(ref x) if x.as_str() == "\n" => break,
+                                    Err(_) => break,
+                                    Ok(_) => {}
                                 }
                             }
                         }
-                        if show_label {
-                            err.span_label(
-                                base_span,
-                                "expecting a type here because of type ascription",
-                            );
-                        }
-                        break;
-                    } else if !snippet.trim().is_empty() {
-                        debug!("tried to find type ascription `:` token, couldn't find it");
-                        break;
                     }
-                } else {
-                    break;
+                    if show_label {
+                        err.span_label(
+                            base_span,
+                            "expecting a type here because of type ascription",
+                        );
+                    }
                 }
             }
         }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index fee7cb4836e..ccc7e16ae4c 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -1020,7 +1020,7 @@ impl<'a> Resolver<'a> {
         }
         if let Some(depr) = &ext.deprecation {
             let path = pprust::path_to_string(&path);
-            let (message, lint) = stability::deprecation_message(depr, &path);
+            let (message, lint) = stability::deprecation_message(depr, "macro", &path);
             stability::early_report_deprecation(
                 &mut self.lint_buffer,
                 &message,
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 0751dbb027a..8e379a35100 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -832,10 +832,10 @@ impl<'tcx> SaveContext<'tcx> {
                 if let Some(meta_list) = attr.meta_item_list() {
                     meta_list
                         .into_iter()
-                        .filter(|it| it.check_name(sym::include))
+                        .filter(|it| it.has_name(sym::include))
                         .filter_map(|it| it.meta_item_list().map(|l| l.to_owned()))
                         .flat_map(|it| it)
-                        .filter(|meta| meta.check_name(sym::contents))
+                        .filter(|meta| meta.has_name(sym::contents))
                         .filter_map(|meta| meta.value_str())
                         .for_each(|val| {
                             result.push_str(&val.as_str());
diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs
index 620a04b45b0..9fcdd46539c 100644
--- a/src/librustc_session/config.rs
+++ b/src/librustc_session/config.rs
@@ -1717,7 +1717,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         }
 
         // `-Z instrument-coverage` implies:
-        //   * `-Z symbol-mangling-version=v0` - to ensure consistent and reversable name mangling.
+        //   * `-Z symbol-mangling-version=v0` - to ensure consistent and reversible name mangling.
         //     Note, LLVM coverage tools can analyze coverage over multiple runs, including some
         //     changes to source code; so mangled names must be consistent across compilations.
         //   * `-C link-dead-code` - so unexecuted code is still counted as zero, rather than be
diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index b428315b3cd..9cdb7e966fe 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -63,7 +63,7 @@ impl GatedSpans {
 
 #[derive(Default)]
 pub struct SymbolGallery {
-    /// All symbols occurred and their first occurrance span.
+    /// All symbols occurred and their first occurrence span.
     pub symbols: Lock<BTreeMap<Symbol, Span>>,
 }
 
@@ -138,6 +138,8 @@ pub struct ParseSess {
     pub reached_eof: Lock<bool>,
     /// Environment variables accessed during the build and their values when they exist.
     pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>,
+    /// All the type ascriptions expressions that have had a suggestion for likely path typo.
+    pub type_ascription_path_suggestions: Lock<FxHashSet<Span>>,
 }
 
 impl ParseSess {
@@ -164,6 +166,7 @@ impl ParseSess {
             symbol_gallery: SymbolGallery::default(),
             reached_eof: Lock::new(false),
             env_depinfo: Default::default(),
+            type_ascription_path_suggestions: Default::default(),
         }
     }
 
diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs
index 13bc1751831..a03ac4e1fdb 100644
--- a/src/librustc_span/hygiene.rs
+++ b/src/librustc_span/hygiene.rs
@@ -891,7 +891,7 @@ impl UseSpecializedDecodable for ExpnId {}
 
 #[derive(Default)]
 pub struct HygieneEncodeContext {
-    /// All `SyntaxContexts` for which we have writen `SyntaxContextData` into crate metadata.
+    /// All `SyntaxContexts` for which we have written `SyntaxContextData` into crate metadata.
     /// This is `None` after we finish encoding `SyntaxContexts`, to ensure
     /// that we don't accidentally try to encode any more `SyntaxContexts`
     serialized_ctxts: Lock<FxHashSet<SyntaxContext>>,
@@ -961,7 +961,7 @@ pub struct HygieneDecodeContext {
     // Maps serialized `SyntaxContext` ids to a `SyntaxContext` in the current
     // global `HygieneData`. When we deserialize a `SyntaxContext`, we need to create
     // a new id in the global `HygieneData`. This map tracks the ID we end up picking,
-    // so that multiple occurences of the same serialized id are decoded to the same
+    // so that multiple occurrences of the same serialized id are decoded to the same
     // `SyntaxContext`
     remapped_ctxts: Lock<Vec<Option<SyntaxContext>>>,
     // The same as `remapepd_ctxts`, but for `ExpnId`s
diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs
index 8423573b52d..62fc8f06183 100644
--- a/src/librustc_target/spec/wasm32_base.rs
+++ b/src/librustc_target/spec/wasm32_base.rs
@@ -10,13 +10,6 @@ pub fn options() -> TargetOptions {
         clang_args.push(format!("-Wl,{}", arg));
     };
 
-    // There have been reports in the wild (rustwasm/wasm-bindgen#119) of
-    // using threads causing weird hangs and bugs. Disable it entirely as
-    // this isn't yet the bottleneck of compilation at all anyway.
-    //
-    // FIXME: we should file an upstream issue with LLD about this
-    arg("--no-threads");
-
     // By default LLD only gives us one page of stack (64k) which is a
     // little small. Default to a larger stack closer to other PC platforms
     // (1MB) and users can always inject their own link-args to override this.
diff --git a/src/librustc_trait_selection/traits/on_unimplemented.rs b/src/librustc_trait_selection/traits/on_unimplemented.rs
index deb33708681..446d5a489df 100644
--- a/src/librustc_trait_selection/traits/on_unimplemented.rs
+++ b/src/librustc_trait_selection/traits/on_unimplemented.rs
@@ -95,27 +95,27 @@ impl<'tcx> OnUnimplementedDirective {
         };
 
         for item in item_iter {
-            if item.check_name(sym::message) && message.is_none() {
+            if item.has_name(sym::message) && message.is_none() {
                 if let Some(message_) = item.value_str() {
                     message = parse_value(message_)?;
                     continue;
                 }
-            } else if item.check_name(sym::label) && label.is_none() {
+            } else if item.has_name(sym::label) && label.is_none() {
                 if let Some(label_) = item.value_str() {
                     label = parse_value(label_)?;
                     continue;
                 }
-            } else if item.check_name(sym::note) && note.is_none() {
+            } else if item.has_name(sym::note) && note.is_none() {
                 if let Some(note_) = item.value_str() {
                     note = parse_value(note_)?;
                     continue;
                 }
-            } else if item.check_name(sym::enclosing_scope) && enclosing_scope.is_none() {
+            } else if item.has_name(sym::enclosing_scope) && enclosing_scope.is_none() {
                 if let Some(enclosing_scope_) = item.value_str() {
                     enclosing_scope = parse_value(enclosing_scope_)?;
                     continue;
                 }
-            } else if item.check_name(sym::on)
+            } else if item.has_name(sym::on)
                 && is_root
                 && message.is_none()
                 && label.is_none()
diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs
index 4123f293826..75e11619924 100644
--- a/src/librustc_trait_selection/traits/select/mod.rs
+++ b/src/librustc_trait_selection/traits/select/mod.rs
@@ -51,6 +51,47 @@ pub use rustc_middle::traits::select::*;
 mod candidate_assembly;
 mod confirmation;
 
+#[derive(Clone, Debug)]
+pub enum IntercrateAmbiguityCause {
+    DownstreamCrate { trait_desc: String, self_desc: Option<String> },
+    UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
+    ReservationImpl { message: String },
+}
+
+impl IntercrateAmbiguityCause {
+    /// Emits notes when the overlap is caused by complex intercrate ambiguities.
+    /// See #23980 for details.
+    pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) {
+        err.note(&self.intercrate_ambiguity_hint());
+    }
+
+    pub fn intercrate_ambiguity_hint(&self) -> String {
+        match self {
+            &IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => {
+                let self_desc = if let &Some(ref ty) = self_desc {
+                    format!(" for type `{}`", ty)
+                } else {
+                    String::new()
+                };
+                format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc)
+            }
+            &IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => {
+                let self_desc = if let &Some(ref ty) = self_desc {
+                    format!(" for type `{}`", ty)
+                } else {
+                    String::new()
+                };
+                format!(
+                    "upstream crates may add a new impl of trait `{}`{} \
+                     in future versions",
+                    trait_desc, self_desc
+                )
+            }
+            &IntercrateAmbiguityCause::ReservationImpl { ref message } => message.clone(),
+        }
+    }
+}
+
 pub struct SelectionContext<'cx, 'tcx> {
     infcx: &'cx InferCtxt<'cx, 'tcx>,
 
@@ -833,17 +874,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> Option<EvaluationResult> {
         let tcx = self.tcx();
         if self.can_use_global_caches(param_env) {
-            let cache = tcx.evaluation_cache.hashmap.borrow();
-            if let Some(cached) = cache.get(&param_env.and(trait_ref)) {
-                return Some(cached.get(tcx));
+            if let Some(res) = tcx.evaluation_cache.get(&param_env.and(trait_ref), tcx) {
+                return Some(res);
             }
         }
-        self.infcx
-            .evaluation_cache
-            .hashmap
-            .borrow()
-            .get(&param_env.and(trait_ref))
-            .map(|v| v.get(tcx))
+        self.infcx.evaluation_cache.get(&param_env.and(trait_ref), tcx)
     }
 
     fn insert_evaluation_cache(
@@ -869,21 +904,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // FIXME: Due to #50507 this overwrites the different values
                 // This should be changed to use HashMapExt::insert_same
                 // when that is fixed
-                self.tcx()
-                    .evaluation_cache
-                    .hashmap
-                    .borrow_mut()
-                    .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, result));
+                self.tcx().evaluation_cache.insert(param_env.and(trait_ref), dep_node, result);
                 return;
             }
         }
 
         debug!("insert_evaluation_cache(trait_ref={:?}, candidate={:?})", trait_ref, result,);
-        self.infcx
-            .evaluation_cache
-            .hashmap
-            .borrow_mut()
-            .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, result));
+        self.infcx.evaluation_cache.insert(param_env.and(trait_ref), dep_node, result);
     }
 
     /// For various reasons, it's possible for a subobligation
@@ -1180,17 +1207,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let tcx = self.tcx();
         let trait_ref = &cache_fresh_trait_pred.skip_binder().trait_ref;
         if self.can_use_global_caches(param_env) {
-            let cache = tcx.selection_cache.hashmap.borrow();
-            if let Some(cached) = cache.get(&param_env.and(*trait_ref)) {
-                return Some(cached.get(tcx));
+            if let Some(res) = tcx.selection_cache.get(&param_env.and(*trait_ref), tcx) {
+                return Some(res);
             }
         }
-        self.infcx
-            .selection_cache
-            .hashmap
-            .borrow()
-            .get(&param_env.and(*trait_ref))
-            .map(|v| v.get(tcx))
+        self.infcx.selection_cache.get(&param_env.and(*trait_ref), tcx)
     }
 
     /// Determines whether can we safely cache the result
@@ -1248,10 +1269,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         trait_ref, candidate,
                     );
                     // This may overwrite the cache with the same value.
-                    tcx.selection_cache
-                        .hashmap
-                        .borrow_mut()
-                        .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, candidate));
+                    tcx.selection_cache.insert(param_env.and(trait_ref), dep_node, candidate);
                     return;
                 }
             }
@@ -1261,11 +1279,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             "insert_candidate_cache(trait_ref={:?}, candidate={:?}) local",
             trait_ref, candidate,
         );
-        self.infcx
-            .selection_cache
-            .hashmap
-            .borrow_mut()
-            .insert(param_env.and(trait_ref), WithDepNode::new(dep_node, candidate));
+        self.infcx.selection_cache.insert(param_env.and(trait_ref), dep_node, candidate);
     }
 
     fn match_projection_obligation_against_definition_bounds(
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index c7e9b97e2db..db8cdfc5b20 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -456,7 +456,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         //
         // Both of these trigger a special `CoerceUnsized`-related error (E0376)
         //
-        // We can take advantage of this fact to avoid performing unecessary work.
+        // We can take advantage of this fact to avoid performing unnecessary work.
         // If either `source` or `target` is a type variable, then any applicable impl
         // would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`)
         // or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index dc2172650e5..b3287caa0bf 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -379,17 +379,46 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
 
             sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
 
-            sym::count_code_region => {
-                (0, vec![tcx.types.u64, tcx.types.u32, tcx.types.u32, tcx.types.u32], tcx.mk_unit())
-            }
+            sym::count_code_region => (
+                0,
+                vec![
+                    tcx.types.u64,
+                    tcx.types.u32,
+                    tcx.mk_static_str(),
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.types.u32,
+                ],
+                tcx.mk_unit(),
+            ),
 
             sym::coverage_counter_add | sym::coverage_counter_subtract => (
                 0,
-                vec![tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32, tcx.types.u32],
+                vec![
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.mk_static_str(),
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.types.u32,
+                ],
                 tcx.mk_unit(),
             ),
 
-            sym::coverage_unreachable => (0, vec![tcx.types.u32, tcx.types.u32], tcx.mk_unit()),
+            sym::coverage_unreachable => (
+                0,
+                vec![
+                    tcx.mk_static_str(),
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.types.u32,
+                    tcx.types.u32,
+                ],
+                tcx.mk_unit(),
+            ),
 
             other => {
                 struct_span_err!(
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 8715dacb324..97df065500a 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -2231,7 +2231,7 @@ fn from_target_feature(
     let rust_features = tcx.features();
     for item in list {
         // Only `enable = ...` is accepted in the meta-item list.
-        if !item.check_name(sym::enable) {
+        if !item.has_name(sym::enable) {
             bad_item(item.span());
             continue;
         }
@@ -2483,11 +2483,11 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
             no_sanitize_span = Some(attr.span);
             if let Some(list) = attr.meta_item_list() {
                 for item in list.iter() {
-                    if item.check_name(sym::address) {
+                    if item.has_name(sym::address) {
                         codegen_fn_attrs.no_sanitize |= SanitizerSet::ADDRESS;
-                    } else if item.check_name(sym::memory) {
+                    } else if item.has_name(sym::memory) {
                         codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY;
-                    } else if item.check_name(sym::thread) {
+                    } else if item.has_name(sym::thread) {
                         codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD;
                     } else {
                         tcx.sess
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 9ba2545ba63..e203d51f612 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -100,7 +100,7 @@ use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::util;
 use rustc_session::config::EntryFnType;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{symbol::sym, Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
@@ -194,6 +194,23 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: LocalDefId) {
                         .emit();
                         error = true;
                     }
+
+                    for attr in it.attrs {
+                        if attr.check_name(sym::track_caller) {
+                            tcx.sess
+                                .struct_span_err(
+                                    attr.span,
+                                    "`main` function is not allowed to be `#[track_caller]`",
+                                )
+                                .span_label(
+                                    main_span,
+                                    "`main` function is not allowed to be `#[track_caller]`",
+                                )
+                                .emit();
+                            error = true;
+                        }
+                    }
+
                     if error {
                         return;
                     }
@@ -268,12 +285,29 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: LocalDefId) {
                             tcx.sess,
                             span,
                             E0752,
-                            "start is not allowed to be `async`"
+                            "`start` is not allowed to be `async`"
                         )
-                        .span_label(span, "start is not allowed to be `async`")
+                        .span_label(span, "`start` is not allowed to be `async`")
                         .emit();
                         error = true;
                     }
+
+                    for attr in it.attrs {
+                        if attr.check_name(sym::track_caller) {
+                            tcx.sess
+                                .struct_span_err(
+                                    attr.span,
+                                    "`start` is not allowed to be `#[track_caller]`",
+                                )
+                                .span_label(
+                                    start_span,
+                                    "`start` is not allowed to be `#[track_caller]`",
+                                )
+                                .emit();
+                            error = true;
+                        }
+                    }
+
                     if error {
                         return;
                     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5b048372624..2a090d6efa5 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -113,7 +113,7 @@ impl Clean<ExternalCrate> for CrateNum {
                 let mut prim = None;
                 for attr in attrs.lists(sym::doc) {
                     if let Some(v) = attr.value_str() {
-                        if attr.check_name(sym::primitive) {
+                        if attr.has_name(sym::primitive) {
                             prim = PrimitiveType::from_symbol(v);
                             if prim.is_some() {
                                 break;
@@ -168,7 +168,7 @@ impl Clean<ExternalCrate> for CrateNum {
                 let mut keyword = None;
                 for attr in attrs.lists(sym::doc) {
                     if let Some(v) = attr.value_str() {
-                        if attr.check_name(sym::keyword) {
+                        if attr.has_name(sym::keyword) {
                             if v.is_doc_keyword() {
                                 keyword = Some(v.to_string());
                                 break;
@@ -2157,7 +2157,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
         let please_inline = self.vis.node.is_pub()
             && self.attrs.iter().any(|a| {
-                a.check_name(sym::doc)
+                a.has_name(sym::doc)
                     && match a.meta_item_list() {
                         Some(l) => attr::list_contains_name(&l, sym::inline),
                         None => false,
@@ -2197,7 +2197,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
         // Don't inline doc(hidden) imports so they can be stripped at a later stage.
         let mut denied = !self.vis.node.is_pub()
             || self.attrs.iter().any(|a| {
-                a.check_name(sym::doc)
+                a.has_name(sym::doc)
                     && match a.meta_item_list() {
                         Some(l) => {
                             attr::list_contains_name(&l, sym::no_inline)
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 89549eae2cb..1bea41b6585 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -210,7 +210,7 @@ impl Item {
     }
 
     pub fn is_non_exhaustive(&self) -> bool {
-        self.attrs.other_attrs.iter().any(|a| a.check_name(sym::non_exhaustive))
+        self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive))
     }
 
     /// Returns a documentation-level item type from the item.
@@ -309,7 +309,7 @@ impl<'a> Iterator for ListAttributesIter<'a> {
 
         for attr in &mut self.attrs {
             if let Some(list) = attr.meta_item_list() {
-                if attr.check_name(self.name) {
+                if attr.has_name(self.name) {
                     self.current_list = list.into_iter();
                     if let Some(nested) = self.current_list.next() {
                         return Some(nested);
@@ -345,7 +345,7 @@ pub trait NestedAttributesExt {
 
 impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
     fn has_word(self, word: Symbol) -> bool {
-        self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
+        self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
     }
 }
 
@@ -425,7 +425,7 @@ impl Attributes {
         if let ast::MetaItemKind::List(ref nmis) = mi.kind {
             if nmis.len() == 1 {
                 if let MetaItem(ref cfg_mi) = nmis[0] {
-                    if cfg_mi.check_name(sym::cfg) {
+                    if cfg_mi.has_name(sym::cfg) {
                         if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind {
                             if cfg_nmis.len() == 1 {
                                 if let MetaItem(ref content_mi) = cfg_nmis[0] {
@@ -447,7 +447,7 @@ impl Attributes {
     pub fn extract_include(mi: &ast::MetaItem) -> Option<(String, String)> {
         mi.meta_item_list().and_then(|list| {
             for meta in list {
-                if meta.check_name(sym::include) {
+                if meta.has_name(sym::include) {
                     // the actual compiled `#[doc(include="filename")]` gets expanded to
                     // `#[doc(include(file="filename", contents="file contents")]` so we need to
                     // look for that instead
@@ -456,11 +456,11 @@ impl Attributes {
                         let mut contents: Option<String> = None;
 
                         for it in list {
-                            if it.check_name(sym::file) {
+                            if it.has_name(sym::file) {
                                 if let Some(name) = it.value_str() {
                                     filename = Some(name.to_string());
                                 }
-                            } else if it.check_name(sym::contents) {
+                            } else if it.has_name(sym::contents) {
                                 if let Some(docs) = it.value_str() {
                                     contents = Some(docs.to_string());
                                 }
@@ -482,12 +482,12 @@ impl Attributes {
 
     pub fn has_doc_flag(&self, flag: Symbol) -> bool {
         for attr in &self.other_attrs {
-            if !attr.check_name(sym::doc) {
+            if !attr.has_name(sym::doc) {
                 continue;
             }
 
             if let Some(items) = attr.meta_item_list() {
-                if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
+                if items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) {
                     return true;
                 }
             }
@@ -521,7 +521,7 @@ impl Attributes {
                     }
                     None
                 } else {
-                    if attr.check_name(sym::doc) {
+                    if attr.has_name(sym::doc) {
                         if let Some(mi) = attr.meta() {
                             if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
                                 // Extracted #[doc(cfg(...))]
@@ -548,7 +548,7 @@ impl Attributes {
         // treat #[target_feature(enable = "feat")] attributes as if they were
         // #[doc(cfg(target_feature = "feat"))] attributes as well
         for attr in attrs.lists(sym::target_feature) {
-            if attr.check_name(sym::enable) {
+            if attr.has_name(sym::enable) {
                 if let Some(feat) = attr.value_str() {
                     let meta = attr::mk_name_value_item_str(
                         Ident::with_dummy_span(sym::target_feature),
@@ -648,7 +648,7 @@ impl Attributes {
     pub fn get_doc_aliases(&self) -> FxHashSet<String> {
         self.other_attrs
             .lists(sym::doc)
-            .filter(|a| a.check_name(sym::alias))
+            .filter(|a| a.has_name(sym::alias))
             .filter_map(|a| a.value_str().map(|s| s.to_string().replace("\"", "")))
             .filter(|v| !v.is_empty())
             .collect::<FxHashSet<_>>()
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 378efa1a1be..5a9e9dda677 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -48,7 +48,7 @@ pub fn extern_location(
     // external crate
     e.attrs
         .lists(sym::doc)
-        .filter(|a| a.check_name(sym::html_root_url))
+        .filter(|a| a.has_name(sym::html_root_url))
         .filter_map(|a| a.value_str())
         .map(|url| {
             let mut url = url.to_string();
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 002c5f96710..d5f7ddcbdfb 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -43,13 +43,13 @@ extern crate rustc_trait_selection;
 extern crate rustc_typeck;
 extern crate test as testing;
 #[macro_use]
-extern crate log;
+extern crate tracing;
 
 use std::default::Default;
 use std::env;
-use std::panic;
 use std::process;
 
+use rustc_errors::ErrorReported;
 use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup};
 use rustc_session::getopts;
 use rustc_session::{early_error, early_warn};
@@ -82,22 +82,14 @@ struct Output {
 }
 
 pub fn main() {
-    let thread_stack_size: usize = if cfg!(target_os = "haiku") {
-        16_000_000 // 16MB on Haiku
-    } else {
-        32_000_000 // 32MB on other platforms
-    };
     rustc_driver::set_sigpipe_handler();
     rustc_driver::install_ice_hook();
     rustc_driver::init_env_logger("RUSTDOC_LOG");
-
-    let res = std::thread::Builder::new()
-        .stack_size(thread_stack_size)
-        .spawn(move || get_args().map(|args| main_args(&args)).unwrap_or(1))
-        .unwrap()
-        .join()
-        .unwrap_or(rustc_driver::EXIT_FAILURE);
-    process::exit(res);
+    let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() {
+        Some(args) => main_args(&args),
+        _ => Err(ErrorReported),
+    });
+    process::exit(exit_code);
 }
 
 fn get_args() -> Option<Vec<String>> {
@@ -418,7 +410,10 @@ fn usage(argv0: &str) {
     println!("{}", options.usage(&format!("{} [options] <input>", argv0)));
 }
 
-fn main_args(args: &[String]) -> i32 {
+/// A result type used by several functions under `main()`.
+type MainResult = Result<(), ErrorReported>;
+
+fn main_args(args: &[String]) -> MainResult {
     let mut options = getopts::Options::new();
     for option in opts() {
         (option.apply)(&mut options);
@@ -429,24 +424,27 @@ fn main_args(args: &[String]) -> i32 {
             early_error(ErrorOutputType::default(), &err.to_string());
         }
     };
+
+    // Note that we discard any distinction between different non-zero exit
+    // codes from `from_matches` here.
     let options = match config::Options::from_matches(&matches) {
         Ok(opts) => opts,
-        Err(code) => return code,
+        Err(code) => return if code == 0 { Ok(()) } else { Err(ErrorReported) },
     };
-    rustc_interface::interface::setup_callbacks_and_run_in_default_thread_pool_with_globals(
+    rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals(
         options.edition,
+        1, // this runs single-threaded, even in a parallel compiler
+        &None,
         move || main_options(options),
     )
 }
 
-fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> i32 {
+fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainResult {
     match res {
-        Ok(()) => 0,
+        Ok(()) => Ok(()),
         Err(err) => {
-            if !err.is_empty() {
-                diag.struct_err(&err).emit();
-            }
-            1
+            diag.struct_err(&err).emit();
+            Err(ErrorReported)
         }
     }
 }
@@ -457,9 +455,9 @@ fn run_renderer<T: formats::FormatRenderer>(
     render_info: config::RenderInfo,
     diag: &rustc_errors::Handler,
     edition: rustc_span::edition::Edition,
-) -> i32 {
+) -> MainResult {
     match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition) {
-        Ok(_) => rustc_driver::EXIT_SUCCESS,
+        Ok(_) => Ok(()),
         Err(e) => {
             let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error));
             let file = e.file.display().to_string();
@@ -468,17 +466,17 @@ fn run_renderer<T: formats::FormatRenderer>(
             } else {
                 msg.note(&format!("failed to create or modify \"{}\"", file)).emit()
             }
-            rustc_driver::EXIT_FAILURE
+            Err(ErrorReported)
         }
     }
 }
 
-fn main_options(options: config::Options) -> i32 {
+fn main_options(options: config::Options) -> MainResult {
     let diag = core::new_handler(options.error_format, None, &options.debugging_options);
 
     match (options.should_test, options.markdown_input()) {
         (true, true) => return wrap_return(&diag, markdown::test(options)),
-        (true, false) => return wrap_return(&diag, test::run(options)),
+        (true, false) => return test::run(options),
         (false, true) => {
             return wrap_return(
                 &diag,
@@ -500,44 +498,37 @@ fn main_options(options: config::Options) -> i32 {
     // compiler all the way through the analysis passes. The rustdoc output is
     // then generated from the cleaned AST of the crate. This runs all the
     // plug/cleaning passes.
-    let result = rustc_driver::catch_fatal_errors(move || {
-        let crate_name = options.crate_name.clone();
-        let crate_version = options.crate_version.clone();
-        let output_format = options.output_format;
-        let (mut krate, renderinfo, renderopts) = core::run_core(options);
+    let crate_name = options.crate_name.clone();
+    let crate_version = options.crate_version.clone();
+    let output_format = options.output_format;
+    let (mut krate, renderinfo, renderopts) = core::run_core(options);
 
-        info!("finished with rustc");
+    info!("finished with rustc");
 
-        if let Some(name) = crate_name {
-            krate.name = name
-        }
+    if let Some(name) = crate_name {
+        krate.name = name
+    }
 
-        krate.version = crate_version;
+    krate.version = crate_version;
 
-        let out = Output { krate, renderinfo, renderopts };
+    let out = Output { krate, renderinfo, renderopts };
 
-        if show_coverage {
-            // if we ran coverage, bail early, we don't need to also generate docs at this point
-            // (also we didn't load in any of the useful passes)
-            return rustc_driver::EXIT_SUCCESS;
-        }
+    if show_coverage {
+        // if we ran coverage, bail early, we don't need to also generate docs at this point
+        // (also we didn't load in any of the useful passes)
+        return Ok(());
+    }
 
-        let Output { krate, renderinfo, renderopts } = out;
-        info!("going to format");
-        let (error_format, edition, debugging_options) = diag_opts;
-        let diag = core::new_handler(error_format, None, &debugging_options);
-        match output_format {
-            None | Some(config::OutputFormat::Html) => {
-                run_renderer::<html::render::Context>(krate, renderopts, renderinfo, &diag, edition)
-            }
-            Some(config::OutputFormat::Json) => {
-                run_renderer::<json::JsonRenderer>(krate, renderopts, renderinfo, &diag, edition)
-            }
+    let Output { krate, renderinfo, renderopts } = out;
+    info!("going to format");
+    let (error_format, edition, debugging_options) = diag_opts;
+    let diag = core::new_handler(error_format, None, &debugging_options);
+    match output_format {
+        None | Some(config::OutputFormat::Html) => {
+            run_renderer::<html::render::Context>(krate, renderopts, renderinfo, &diag, edition)
+        }
+        Some(config::OutputFormat::Json) => {
+            run_renderer::<json::JsonRenderer>(krate, renderopts, renderinfo, &diag, edition)
         }
-    });
-
-    match result {
-        Ok(output) => output,
-        Err(_) => panic::resume_unwind(Box::new(rustc_errors::FatalErrorMarker)),
     }
 }
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 0fdeefd79e9..3000afde0c2 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -28,7 +28,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
     let mut new_items = Vec::new();
 
     for &cnum in cx.tcx.crates().iter() {
-        for &did in cx.tcx.all_trait_implementations(cnum).iter() {
+        for &(did, _) in cx.tcx.all_trait_implementations(cnum).iter() {
             inline::build_impl(cx, did, None, &mut new_items);
         }
     }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index e8ea7199710..b86a105ff76 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -42,7 +42,7 @@ pub struct TestOptions {
     pub attrs: Vec<String>,
 }
 
-pub fn run(options: Options) -> Result<(), String> {
+pub fn run(options: Options) -> Result<(), ErrorReported> {
     let input = config::Input::File(options.input.clone());
 
     let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name;
@@ -150,7 +150,7 @@ pub fn run(options: Options) -> Result<(), String> {
     });
     let tests = match tests {
         Ok(tests) => tests,
-        Err(ErrorReported) => return Err(String::new()),
+        Err(ErrorReported) => return Err(ErrorReported),
     };
 
     test_args.insert(0, "rustdoctest".to_string());
@@ -175,17 +175,17 @@ fn scrape_test_config(krate: &::rustc_hir::Crate<'_>) -> TestOptions {
         .item
         .attrs
         .iter()
-        .filter(|a| a.check_name(sym::doc))
+        .filter(|a| a.has_name(sym::doc))
         .flat_map(|a| a.meta_item_list().unwrap_or_else(Vec::new))
-        .filter(|a| a.check_name(sym::test))
+        .filter(|a| a.has_name(sym::test))
         .collect();
     let attrs = test_attrs.iter().flat_map(|a| a.meta_item_list().unwrap_or(&[]));
 
     for attr in attrs {
-        if attr.check_name(sym::no_crate_inject) {
+        if attr.has_name(sym::no_crate_inject) {
             opts.no_crate_inject = true;
         }
-        if attr.check_name(sym::attr) {
+        if attr.has_name(sym::attr) {
             if let Some(l) = attr.meta_item_list() {
                 for item in l {
                     opts.attrs.push(pprust::meta_list_item_to_string(item));
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 735446d235c..cf57ffd0b4b 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -165,11 +165,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     ) {
         debug!("visiting fn");
         let macro_kind = item.attrs.iter().find_map(|a| {
-            if a.check_name(sym::proc_macro) {
+            if a.has_name(sym::proc_macro) {
                 Some(MacroKind::Bang)
-            } else if a.check_name(sym::proc_macro_derive) {
+            } else if a.has_name(sym::proc_macro_derive) {
                 Some(MacroKind::Derive)
-            } else if a.check_name(sym::proc_macro_attribute) {
+            } else if a.has_name(sym::proc_macro_attribute) {
                 Some(MacroKind::Attr)
             } else {
                 None
@@ -189,7 +189,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
                 let mut helpers = Vec::new();
                 for mi in item.attrs.lists(sym::proc_macro_derive) {
-                    if !mi.check_name(sym::attributes) {
+                    if !mi.has_name(sym::attributes) {
                         continue;
                     }
 
@@ -419,8 +419,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 // anything as it will probably be stripped anyway.
                 if item.vis.node.is_pub() && self.inside_public_path {
                     let please_inline = item.attrs.iter().any(|item| match item.meta_item_list() {
-                        Some(ref list) if item.check_name(sym::doc) => {
-                            list.iter().any(|i| i.check_name(sym::inline))
+                        Some(ref list) if item.has_name(sym::doc) => {
+                            list.iter().any(|i| i.has_name(sym::inline))
                         }
                         _ => false,
                     });
diff --git a/src/test/assembly/asm/aarch64-modifiers.rs b/src/test/assembly/asm/aarch64-modifiers.rs
index c2484e9b6d0..150997ee807 100644
--- a/src/test/assembly/asm/aarch64-modifiers.rs
+++ b/src/test/assembly/asm/aarch64-modifiers.rs
@@ -2,6 +2,7 @@
 // assembly-output: emit-asm
 // compile-flags: -O
 // compile-flags: --target aarch64-unknown-linux-gnu
+// needs-llvm-components: aarch64
 
 #![feature(no_core, lang_items, rustc_attrs)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/aarch64-types.rs b/src/test/assembly/asm/aarch64-types.rs
index ce2f0082a06..b78a8cbb559 100644
--- a/src/test/assembly/asm/aarch64-types.rs
+++ b/src/test/assembly/asm/aarch64-types.rs
@@ -1,6 +1,7 @@
 // no-system-llvm
 // assembly-output: emit-asm
 // compile-flags: --target aarch64-unknown-linux-gnu
+// needs-llvm-components: aarch64
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/arm-modifiers.rs b/src/test/assembly/asm/arm-modifiers.rs
index b71503d0a53..ad4ab63f265 100644
--- a/src/test/assembly/asm/arm-modifiers.rs
+++ b/src/test/assembly/asm/arm-modifiers.rs
@@ -3,6 +3,7 @@
 // compile-flags: -O
 // compile-flags: --target armv7-unknown-linux-gnueabihf
 // compile-flags: -C target-feature=+neon
+// needs-llvm-components: arm
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/arm-types.rs b/src/test/assembly/asm/arm-types.rs
index 1e338f56c4d..07e25a38e45 100644
--- a/src/test/assembly/asm/arm-types.rs
+++ b/src/test/assembly/asm/arm-types.rs
@@ -2,6 +2,7 @@
 // assembly-output: emit-asm
 // compile-flags: --target armv7-unknown-linux-gnueabihf
 // compile-flags: -C target-feature=+neon
+// needs-llvm-components: arm
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/hexagon-types.rs b/src/test/assembly/asm/hexagon-types.rs
index ba2d8a363cd..b6b3b54cd71 100644
--- a/src/test/assembly/asm/hexagon-types.rs
+++ b/src/test/assembly/asm/hexagon-types.rs
@@ -1,6 +1,7 @@
 // no-system-llvm
 // assembly-output: emit-asm
 // compile-flags: --target hexagon-unknown-linux-musl
+// needs-llvm-components: hexagon
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/nvptx-types.rs b/src/test/assembly/asm/nvptx-types.rs
index 4ee79d1bcc8..77fd5141357 100644
--- a/src/test/assembly/asm/nvptx-types.rs
+++ b/src/test/assembly/asm/nvptx-types.rs
@@ -2,6 +2,7 @@
 // assembly-output: emit-asm
 // compile-flags: --target nvptx64-nvidia-cuda
 // compile-flags: --crate-type cdylib
+// needs-llvm-components: nvptx
 
 #![feature(no_core, lang_items, rustc_attrs)]
 #![no_core]
diff --git a/src/test/assembly/asm/riscv-modifiers.rs b/src/test/assembly/asm/riscv-modifiers.rs
index 8c816e3220b..b6735153b5d 100644
--- a/src/test/assembly/asm/riscv-modifiers.rs
+++ b/src/test/assembly/asm/riscv-modifiers.rs
@@ -3,6 +3,7 @@
 // compile-flags: -O
 // compile-flags: --target riscv64gc-unknown-linux-gnu
 // compile-flags: -C target-feature=+f
+// needs-llvm-components: riscv
 
 #![feature(no_core, lang_items, rustc_attrs)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/riscv-types.rs b/src/test/assembly/asm/riscv-types.rs
index 449213471cc..0ff0bf1f949 100644
--- a/src/test/assembly/asm/riscv-types.rs
+++ b/src/test/assembly/asm/riscv-types.rs
@@ -4,6 +4,7 @@
 //[riscv64] compile-flags: --target riscv64imac-unknown-none-elf
 //[riscv32] compile-flags: --target riscv32imac-unknown-none-elf
 // compile-flags: -C target-feature=+d
+// needs-llvm-components: riscv
 
 #![feature(no_core, lang_items, rustc_attrs)]
 #![crate_type = "rlib"]
diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs
index 7c61b780990..1c0b77ad9c7 100644
--- a/src/test/codegen/abi-efiapi.rs
+++ b/src/test/codegen/abi-efiapi.rs
@@ -1,12 +1,14 @@
 // Checks if the correct annotation for the efiapi ABI is passed to llvm.
 
-// revisions:x86_64 i686 arm
-
+// revisions:x86_64 i686 aarch64 arm riscv
 // min-llvm-version: 9.0
+// needs-llvm-components: aarch64 arm riscv
 
 //[x86_64] compile-flags: --target x86_64-unknown-uefi
 //[i686] compile-flags: --target i686-unknown-linux-musl
+//[aarch64] compile-flags: --target aarch64-unknown-none
 //[arm] compile-flags: --target armv7r-none-eabi
+//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
@@ -22,6 +24,8 @@ trait Copy { }
 
 //x86_64: define win64cc void @has_efiapi
 //i686: define void @has_efiapi
+//aarch64: define void @has_efiapi
 //arm: define void @has_efiapi
+//riscv: define void @has_efiapi
 #[no_mangle]
 pub extern "efiapi" fn has_efiapi() {}
diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs
index 7759d9603a5..6d25ca56f14 100644
--- a/src/test/codegen/avr/avr-func-addrspace.rs
+++ b/src/test/codegen/avr/avr-func-addrspace.rs
@@ -1,4 +1,5 @@
 // compile-flags: -O --target=avr-unknown-unknown --crate-type=rlib
+// needs-llvm-components: avr
 
 // This test validates that function pointers can be stored in global variables
 // and called upon. It ensures that Rust emits function pointers in the correct
diff --git a/src/test/codegen/wasm_casts_trapping.rs b/src/test/codegen/wasm_casts_trapping.rs
index b7f8522fdfb..ed51faa7be1 100644
--- a/src/test/codegen/wasm_casts_trapping.rs
+++ b/src/test/codegen/wasm_casts_trapping.rs
@@ -5,72 +5,72 @@
 // CHECK-LABEL: @cast_f64_i64
 #[no_mangle]
 pub fn cast_f64_i64(a: f64) -> i64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi double {{.*}} to i64
-    // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK-NOT: fptosi double {{.*}} to i64
+    // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
 // CHECK-LABEL: @cast_f64_i32
 #[no_mangle]
 pub fn cast_f64_i32(a: f64) -> i32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi double {{.*}} to i32
-    // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK-NOT: fptosi double {{.*}} to i32
+    // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
 // CHECK-LABEL: @cast_f32_i64
 #[no_mangle]
 pub fn cast_f32_i64(a: f32) -> i64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi float {{.*}} to i64
-    // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK-NOT: fptosi float {{.*}} to i64
+    // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
 // CHECK-LABEL: @cast_f32_i32
 #[no_mangle]
 pub fn cast_f32_i32(a: f32) -> i32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptosi float {{.*}} to i32
-    // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK-NOT: fptosi float {{.*}} to i32
+    // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
 // CHECK-LABEL: @cast_f64_u64
 #[no_mangle]
 pub fn cast_f64_u64(a: f64) -> u64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui double {{.*}} to i64
-    // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK-NOT: fptoui double {{.*}} to i64
+    // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
 // CHECK-LABEL: @cast_f64_u32
 #[no_mangle]
 pub fn cast_f64_u32(a: f64) -> u32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui double {{.*}} to i32
-    // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK-NOT: fptoui double {{.*}} to i32
+    // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
 // CHECK-LABEL: @cast_f32_u64
 #[no_mangle]
 pub fn cast_f32_u64(a: f32) -> u64 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui float {{.*}} to i64
-    // CHECK-NEXT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK-NOT: fptoui float {{.*}} to i64
+    // CHECK-NOT: select i1 {{.*}}, i64 {{.*}}, i64 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
 // CHECK-LABEL: @cast_f32_u32
 #[no_mangle]
 pub fn cast_f32_u32(a: f32) -> u32 {
-    // CHECK-NOT: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
-    // CHECK: fptoui float {{.*}} to i32
-    // CHECK-NEXT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK-NOT: fptoui float {{.*}} to i32
+    // CHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
+    // CHECK: {{.*}} call {{.*}} @llvm.wasm.trunc.{{.*}}
     a as _
 }
 
diff --git a/src/test/debuginfo/rc_arc.rs b/src/test/debuginfo/rc_arc.rs
index 8ab8a2f9c1c..87bc79ea794 100644
--- a/src/test/debuginfo/rc_arc.rs
+++ b/src/test/debuginfo/rc_arc.rs
@@ -1,3 +1,4 @@
+// ignore-windows pretty-printers are not loaded
 // compile-flags:-g
 
 // min-gdb-version: 8.1
diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
index 96df5c6a518..9ca6f93c9bc 100644
--- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
@@ -2,58 +2,76 @@
 + // MIR for `bar` after InstrumentCoverage
   
   fn bar() -> bool {
-      let mut _0: bool;                    // return place in scope 0 at $DIR/instrument_coverage.rs:18:13: 18:17
-+     let mut _1: ();                      // in scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18
+      let mut _0: bool;                    // return place in scope 0 at /the/src/instrument_coverage.rs:19:13: 19:17
++     let mut _1: ();                      // in scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18
   
       bb0: {
-+         StorageLive(_1);                 // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18
-+         _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const 529_u32, const 541_u32) -> bb2; // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18
++         StorageLive(_1);                 // scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18
++         _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const "/the/src/instrument_coverage.rs", const 19_u32, const 18_u32, const 21_u32, const 2_u32) -> bb2; // scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18
 +                                          // ty::Const
-+                                          // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}
++                                          // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}
 +                                          // + val: Value(Scalar(<ZST>))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:18:18: 18:18
-+                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
++                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
 +                                          // ty::Const
 +                                          // + ty: u64
 +                                          // + val: Value(Scalar(0x8dabe565aaa2aefd))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:18:18: 18:18
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
 +                                          // + literal: Const { ty: u64, val: Value(Scalar(0x8dabe565aaa2aefd)) }
 +                                          // ty::Const
 +                                          // + ty: u32
 +                                          // + val: Value(Scalar(0x00000000))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:18:18: 18:18
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
 +                                          // ty::Const
++                                          // + ty: &str
++                                          // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 })
++                                          // mir::Constant
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
++                                          // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) }
++                                          // ty::Const
++                                          // + ty: u32
++                                          // + val: Value(Scalar(0x00000013))
++                                          // mir::Constant
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000013)) }
++                                          // ty::Const
++                                          // + ty: u32
++                                          // + val: Value(Scalar(0x00000012))
++                                          // mir::Constant
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000012)) }
++                                          // ty::Const
 +                                          // + ty: u32
-+                                          // + val: Value(Scalar(0x00000211))
++                                          // + val: Value(Scalar(0x00000015))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:18:18: 18:18
-+                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000211)) }
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000015)) }
 +                                          // ty::Const
 +                                          // + ty: u32
-+                                          // + val: Value(Scalar(0x0000021d))
++                                          // + val: Value(Scalar(0x00000002))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:18:18: 18:18
-+                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000021d)) }
++                                          // + span: /the/src/instrument_coverage.rs:19:18: 19:18
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
 +     }
 + 
 +     bb1 (cleanup): {
-+         resume;                          // scope 0 at $DIR/instrument_coverage.rs:18:1: 20:2
++         resume;                          // scope 0 at /the/src/instrument_coverage.rs:19:1: 21:2
 +     }
 + 
 +     bb2: {
-+         StorageDead(_1);                 // scope 0 at $DIR/instrument_coverage.rs:19:5: 19:9
-          _0 = const true;                 // scope 0 at $DIR/instrument_coverage.rs:19:5: 19:9
++         StorageDead(_1);                 // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
+          _0 = const true;                 // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
                                            // ty::Const
                                            // + ty: bool
                                            // + val: Value(Scalar(0x01))
                                            // mir::Constant
-                                           // + span: $DIR/instrument_coverage.rs:19:5: 19:9
+                                           // + span: /the/src/instrument_coverage.rs:20:5: 20:9
                                            // + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
-          return;                          // scope 0 at $DIR/instrument_coverage.rs:20:2: 20:2
+          return;                          // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
       }
   }
   
diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
index 1bcc98de8d4..3f47aa13bf9 100644
--- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
@@ -2,99 +2,117 @@
 + // MIR for `main` after InstrumentCoverage
   
   fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
-      let mut _1: ();                      // in scope 0 at $DIR/instrument_coverage.rs:9:1: 15:2
-      let mut _2: bool;                    // in scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
-      let mut _3: !;                       // in scope 0 at $DIR/instrument_coverage.rs:11:18: 13:10
-+     let mut _4: ();                      // in scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
+      let mut _0: ();                      // return place in scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
+      let mut _1: ();                      // in scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2
+      let mut _2: bool;                    // in scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
+      let mut _3: !;                       // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10
++     let mut _4: ();                      // in scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
   
       bb0: {
--         falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
-+         StorageLive(_4);                 // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
-+         _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const 425_u32, const 493_u32) -> bb7; // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
+-         falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
++         StorageLive(_4);                 // scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
++         _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const "/the/src/instrument_coverage.rs", const 10_u32, const 11_u32, const 16_u32, const 2_u32) -> bb7; // scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
 +                                          // ty::Const
-+                                          // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}
++                                          // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}
 +                                          // + val: Value(Scalar(<ZST>))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:9:11: 9:11
-+                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
++                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
 +                                          // ty::Const
 +                                          // + ty: u64
 +                                          // + val: Value(Scalar(0xde1b3f75a72fc7f7))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:9:11: 9:11
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
 +                                          // + literal: Const { ty: u64, val: Value(Scalar(0xde1b3f75a72fc7f7)) }
 +                                          // ty::Const
 +                                          // + ty: u32
 +                                          // + val: Value(Scalar(0x00000000))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:9:11: 9:11
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
 +                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
 +                                          // ty::Const
++                                          // + ty: &str
++                                          // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 })
++                                          // mir::Constant
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
++                                          // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) }
++                                          // ty::Const
++                                          // + ty: u32
++                                          // + val: Value(Scalar(0x0000000a))
++                                          // mir::Constant
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000000a)) }
++                                          // ty::Const
++                                          // + ty: u32
++                                          // + val: Value(Scalar(0x0000000b))
++                                          // mir::Constant
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x0000000b)) }
++                                          // ty::Const
 +                                          // + ty: u32
-+                                          // + val: Value(Scalar(0x000001a9))
++                                          // + val: Value(Scalar(0x00000010))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:9:11: 9:11
-+                                          // + literal: Const { ty: u32, val: Value(Scalar(0x000001a9)) }
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000010)) }
 +                                          // ty::Const
 +                                          // + ty: u32
-+                                          // + val: Value(Scalar(0x000001ed))
++                                          // + val: Value(Scalar(0x00000002))
 +                                          // mir::Constant
-+                                          // + span: $DIR/instrument_coverage.rs:9:11: 9:11
-+                                          // + literal: Const { ty: u32, val: Value(Scalar(0x000001ed)) }
++                                          // + span: /the/src/instrument_coverage.rs:10:11: 10:11
++                                          // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
       }
   
       bb1: {
-          StorageLive(_2);                 // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
-          _2 = const bar() -> [return: bb3, unwind: bb2]; // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
+          StorageLive(_2);                 // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
+          _2 = const bar() -> [return: bb3, unwind: bb2]; // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
                                            // ty::Const
                                            // + ty: fn() -> bool {bar}
                                            // + val: Value(Scalar(<ZST>))
                                            // mir::Constant
-                                           // + span: $DIR/instrument_coverage.rs:11:12: 11:15
+                                           // + span: /the/src/instrument_coverage.rs:12:12: 12:15
                                            // + literal: Const { ty: fn() -> bool {bar}, val: Value(Scalar(<ZST>)) }
       }
   
       bb2 (cleanup): {
-          resume;                          // scope 0 at $DIR/instrument_coverage.rs:9:1: 15:2
+          resume;                          // scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2
       }
   
       bb3: {
-          FakeRead(ForMatchedPlace, _2);   // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
-          switchInt(_2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10
+          FakeRead(ForMatchedPlace, _2);   // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
+          switchInt(_2) -> [false: bb5, otherwise: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
       }
   
       bb4: {
-          falseEdge -> [real: bb6, imaginary: bb5]; // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10
+          falseEdge -> [real: bb6, imaginary: bb5]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
       }
   
       bb5: {
-          _1 = const ();                   // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10
+          _1 = const ();                   // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
                                            // ty::Const
                                            // + ty: ()
                                            // + val: Value(Scalar(<ZST>))
                                            // mir::Constant
-                                           // + span: $DIR/instrument_coverage.rs:11:9: 13:10
+                                           // + span: /the/src/instrument_coverage.rs:12:9: 14:10
                                            // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-          StorageDead(_2);                 // scope 0 at $DIR/instrument_coverage.rs:14:5: 14:6
-          goto -> bb0;                     // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
+          StorageDead(_2);                 // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
+          goto -> bb0;                     // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
       }
   
       bb6: {
-          _0 = const ();                   // scope 0 at $DIR/instrument_coverage.rs:12:13: 12:18
+          _0 = const ();                   // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18
                                            // ty::Const
                                            // + ty: ()
                                            // + val: Value(Scalar(<ZST>))
                                            // mir::Constant
-                                           // + span: $DIR/instrument_coverage.rs:12:13: 12:18
+                                           // + span: /the/src/instrument_coverage.rs:13:13: 13:18
                                            // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
-          StorageDead(_2);                 // scope 0 at $DIR/instrument_coverage.rs:14:5: 14:6
-          return;                          // scope 0 at $DIR/instrument_coverage.rs:15:2: 15:2
+          StorageDead(_2);                 // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
+          return;                          // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
 +     }
 + 
 +     bb7: {
-+         StorageDead(_4);                 // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
-+         falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
++         StorageDead(_4);                 // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
++         falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
       }
   }
   
diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs
index 4770ec9b66e..430573c7c05 100644
--- a/src/test/mir-opt/instrument_coverage.rs
+++ b/src/test/mir-opt/instrument_coverage.rs
@@ -3,7 +3,8 @@
 // intrinsics, during codegen.
 
 // needs-profiler-support
-// compile-flags: -Zinstrument-coverage
+// ignore-windows
+// compile-flags: -Zinstrument-coverage --remap-path-prefix={{src-base}}=/the/src
 // EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff
 // EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff
 fn main() {
@@ -18,3 +19,18 @@ fn main() {
 fn bar() -> bool {
     true
 }
+
+// Note that the MIR with injected coverage intrinsics includes references to source locations,
+// including the source file absolute path. Typically, MIR pretty print output with file
+// references are safe because the file prefixes are substituted with `$DIR`, but in this case
+// the file references are encoded as function arguments, with an `Operand` type representation
+// (`Slice` `Allocation` interned byte array) that cannot be normalized by simple substitution.
+//
+// The first workaround is to use the `SourceMap`-supported `--remap-path-prefix` option; however,
+// the implementation of the `--remap-path-prefix` option currently joins the new prefix and the
+// remaining source path with an OS-specific path separator (`\` on Windows). This difference still
+// shows up in the byte array representation of the path, causing Windows tests to fail to match
+// blessed results baselined with a `/` path separator.
+//
+// Since this `mir-opt` test does not have any significant platform dependencies, other than the
+// path separator differences, the final workaround is to disable testing on Windows.
diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp
index 9317b36ba49..2bfcdd75e15 100644
--- a/src/test/pretty/block-comment-wchar.pp
+++ b/src/test/pretty/block-comment-wchar.pp
@@ -73,7 +73,6 @@ fn f() {
     */
 
 
-
     /* */
 
     /*
@@ -81,7 +80,6 @@ fn f() {
       Space 6+2:                     compare A
       Ogham Space Mark 6+2: compare B
     */
-
     /* */
 
     /*
diff --git a/src/test/pretty/issue-74745.rs b/src/test/pretty/issue-74745.rs
new file mode 100644
index 00000000000..e255cd6caa8
--- /dev/null
+++ b/src/test/pretty/issue-74745.rs
@@ -0,0 +1,5 @@
+// ignore-tidy-trailing-newlines
+// pretty-compare-only
+
+/*
+*/
\ No newline at end of file
diff --git a/src/test/ui/allocator/custom.rs b/src/test/ui/allocator/custom.rs
index 184e4706a4c..a6c2317c736 100644
--- a/src/test/ui/allocator/custom.rs
+++ b/src/test/ui/allocator/custom.rs
@@ -4,10 +4,11 @@
 // no-prefer-dynamic
 
 #![feature(allocator_api)]
+#![feature(slice_ptr_get)]
 
 extern crate helper;
 
-use std::alloc::{self, AllocInit, AllocRef, Global, Layout, System};
+use std::alloc::{self, AllocRef, Global, Layout, System};
 use std::sync::atomic::{AtomicUsize, Ordering};
 
 static HITS: AtomicUsize = AtomicUsize::new(0);
@@ -37,10 +38,10 @@ fn main() {
     unsafe {
         let layout = Layout::from_size_align(4, 2).unwrap();
 
-        let memory = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
-        helper::work_with(&memory.ptr);
+        let memory = Global.alloc(layout.clone()).unwrap();
+        helper::work_with(&memory);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 1);
-        Global.dealloc(memory.ptr, layout);
+        Global.dealloc(memory.as_non_null_ptr(), layout);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 2);
 
         let s = String::with_capacity(10);
@@ -49,10 +50,10 @@ fn main() {
         drop(s);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
 
-        let memory = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
+        let memory = System.alloc(layout.clone()).unwrap();
         assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
-        helper::work_with(&memory.ptr);
-        System.dealloc(memory.ptr, layout);
+        helper::work_with(&memory);
+        System.dealloc(memory.as_non_null_ptr(), layout);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
     }
 }
diff --git a/src/test/ui/allocator/xcrate-use.rs b/src/test/ui/allocator/xcrate-use.rs
index 7de1ab7a553..a1446b3664d 100644
--- a/src/test/ui/allocator/xcrate-use.rs
+++ b/src/test/ui/allocator/xcrate-use.rs
@@ -5,11 +5,12 @@
 // no-prefer-dynamic
 
 #![feature(allocator_api)]
+#![feature(slice_ptr_get)]
 
 extern crate custom;
 extern crate helper;
 
-use std::alloc::{AllocInit, AllocRef, Global, Layout, System};
+use std::alloc::{AllocRef, Global, Layout, System};
 use std::sync::atomic::{AtomicUsize, Ordering};
 
 #[global_allocator]
@@ -20,16 +21,16 @@ fn main() {
         let n = GLOBAL.0.load(Ordering::SeqCst);
         let layout = Layout::from_size_align(4, 2).unwrap();
 
-        let memory = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
-        helper::work_with(&memory.ptr);
+        let memory = Global.alloc(layout.clone()).unwrap();
+        helper::work_with(&memory);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1);
-        Global.dealloc(memory.ptr, layout);
+        Global.dealloc(memory.as_non_null_ptr(), layout);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
 
-        let memory = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
+        let memory = System.alloc(layout.clone()).unwrap();
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
-        helper::work_with(&memory.ptr);
-        System.dealloc(memory.ptr, layout);
+        helper::work_with(&memory);
+        System.dealloc(memory.as_non_null_ptr(), layout);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
     }
 }
diff --git a/src/test/ui/async-await/issue-68523-start.rs b/src/test/ui/async-await/issue-68523-start.rs
index 5988dffd68f..2ced88a16cc 100644
--- a/src/test/ui/async-await/issue-68523-start.rs
+++ b/src/test/ui/async-await/issue-68523-start.rs
@@ -4,6 +4,6 @@
 
 #[start]
 pub async fn start(_: isize, _: *const *const u8) -> isize {
-//~^ ERROR start is not allowed to be `async`
+//~^ ERROR `start` is not allowed to be `async`
     0
 }
diff --git a/src/test/ui/async-await/issue-68523-start.stderr b/src/test/ui/async-await/issue-68523-start.stderr
index e471945900e..3a0a3b5dece 100644
--- a/src/test/ui/async-await/issue-68523-start.stderr
+++ b/src/test/ui/async-await/issue-68523-start.stderr
@@ -1,8 +1,8 @@
-error[E0752]: start is not allowed to be `async`
+error[E0752]: `start` is not allowed to be `async`
   --> $DIR/issue-68523-start.rs:6:1
    |
 LL | pub async fn start(_: isize, _: *const *const u8) -> isize {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ start is not allowed to be `async`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `start` is not allowed to be `async`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs
index cd635c6a722..876d8b079a1 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.rs
@@ -9,13 +9,13 @@
 #[cfg_attr(all(), deprecated, must_use)]
 struct MustUseDeprecated {}
 
-impl MustUseDeprecated { //~ warning: use of deprecated item
-    fn new() -> MustUseDeprecated { //~ warning: use of deprecated item
-        MustUseDeprecated {} //~ warning: use of deprecated item
+impl MustUseDeprecated { //~ warning: use of deprecated
+    fn new() -> MustUseDeprecated { //~ warning: use of deprecated
+        MustUseDeprecated {} //~ warning: use of deprecated
     }
 }
 
 fn main() {
-    MustUseDeprecated::new(); //~ warning: use of deprecated item
+    MustUseDeprecated::new(); //~ warning: use of deprecated
     //~| warning: unused `MustUseDeprecated` that must be used
 }
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
index d7b5d2d263a..21b3a6f1f33 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
@@ -1,4 +1,4 @@
-warning: use of deprecated item 'MustUseDeprecated'
+warning: use of deprecated struct `MustUseDeprecated`
   --> $DIR/cfg-attr-multi-true.rs:12:6
    |
 LL | impl MustUseDeprecated {
@@ -6,19 +6,19 @@ LL | impl MustUseDeprecated {
    |
    = note: `#[warn(deprecated)]` on by default
 
-warning: use of deprecated item 'MustUseDeprecated'
+warning: use of deprecated struct `MustUseDeprecated`
   --> $DIR/cfg-attr-multi-true.rs:19:5
    |
 LL |     MustUseDeprecated::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'MustUseDeprecated'
+warning: use of deprecated struct `MustUseDeprecated`
   --> $DIR/cfg-attr-multi-true.rs:13:17
    |
 LL |     fn new() -> MustUseDeprecated {
    |                 ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'MustUseDeprecated'
+warning: use of deprecated struct `MustUseDeprecated`
   --> $DIR/cfg-attr-multi-true.rs:14:9
    |
 LL |         MustUseDeprecated {}
diff --git a/src/test/ui/const-generics/issues/issue-64494.rs b/src/test/ui/const-generics/issues/issue-64494.rs
new file mode 100644
index 00000000000..4c755530b99
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-64494.rs
@@ -0,0 +1,19 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    const VAL: usize;
+}
+
+trait MyTrait {}
+
+trait True {}
+struct Is<const T: bool>;
+impl True for Is<{true}> {}
+
+impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
+//~^ ERROR constant expression depends on a generic parameter
+impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
+//~^ ERROR constant expression depends on a generic parameter
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-64494.stderr b/src/test/ui/const-generics/issues/issue-64494.stderr
new file mode 100644
index 00000000000..30dca169643
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-64494.stderr
@@ -0,0 +1,18 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-64494.rs:14:53
+   |
+LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
+   |                                                     ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-64494.rs:16:53
+   |
+LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
+   |                                                     ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/issues/issue-72787.rs b/src/test/ui/const-generics/issues/issue-72787.rs
new file mode 100644
index 00000000000..a368c226ec3
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72787.rs
@@ -0,0 +1,32 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+pub struct IsLessOrEqual<const LHS: u32, const RHS: u32>;
+pub struct Condition<const CONDITION: bool>;
+pub trait True {}
+
+impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
+    Condition<{ LHS <= RHS }>: True
+//~^ Error constant expression depends on a generic parameter
+{
+}
+impl True for Condition<true> {}
+
+struct S<const I: u32, const J: u32>;
+impl<const I: u32, const J: u32> S<I, J>
+where
+    IsLessOrEqual<I, 8>: True,
+    IsLessOrEqual<J, 8>: True,
+    IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+//~^ Error constant expression depends on a generic parameter
+//~| Error constant expression depends on a generic parameter
+//~| Error constant expression depends on a generic parameter
+//~| Error constant expression depends on a generic parameter
+    // Condition<{ 8 - I <= 8 - J }>: True,
+{
+    fn print() {
+        println!("I {} J {}", I, J);
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-72787.stderr b/src/test/ui/const-generics/issues/issue-72787.stderr
new file mode 100644
index 00000000000..ed892e46bbb
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72787.stderr
@@ -0,0 +1,42 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-72787.rs:9:32
+   |
+LL |     Condition<{ LHS <= RHS }>: True
+   |                                ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-72787.rs:20:42
+   |
+LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+   |                                          ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-72787.rs:20:42
+   |
+LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+   |                                          ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-72787.rs:20:42
+   |
+LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+   |                                          ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-72787.rs:20:42
+   |
+LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+   |                                          ^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs
index c6b794de195..51e1af359cd 100644
--- a/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs
+++ b/src/test/ui/consts/const_in_pattern/warn_corner_cases.rs
@@ -10,7 +10,7 @@
 // const-evaluator computes a value that *does* meet the conditions for
 // structural-match, but the const expression itself has abstractions (like
 // calls to const functions) that may fit better with a type-based analysis
-// rather than a committment to a specific value.
+// rather than a commitment to a specific value.
 
 #![warn(indirect_structural_match)]
 
diff --git a/src/test/ui/consts/issue-73976-polymorphic.rs b/src/test/ui/consts/issue-73976-polymorphic.rs
index 518036c9dbe..b3d8610ff51 100644
--- a/src/test/ui/consts/issue-73976-polymorphic.rs
+++ b/src/test/ui/consts/issue-73976-polymorphic.rs
@@ -1,5 +1,5 @@
 // This test is from #73976. We previously did not check if a type is monomorphized
-// before calculating its type id, which leads to the bizzare behaviour below that
+// before calculating its type id, which leads to the bizarre behaviour below that
 // TypeId of a generic type does not match itself.
 //
 // This test case should either run-pass or be rejected at compile time.
diff --git a/src/test/ui/consts/unsizing-cast-non-null.rs b/src/test/ui/consts/unsizing-cast-non-null.rs
new file mode 100644
index 00000000000..67d9f6baca5
--- /dev/null
+++ b/src/test/ui/consts/unsizing-cast-non-null.rs
@@ -0,0 +1,10 @@
+// Regression test for #75118.
+
+use std::ptr::NonNull;
+
+pub const fn dangling_slice<T>() -> NonNull<[T]> {
+    NonNull::<[T; 0]>::dangling()
+    //~^ ERROR: unsizing casts are only allowed for references right now
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/unsizing-cast-non-null.stderr b/src/test/ui/consts/unsizing-cast-non-null.stderr
new file mode 100644
index 00000000000..6575355daad
--- /dev/null
+++ b/src/test/ui/consts/unsizing-cast-non-null.stderr
@@ -0,0 +1,12 @@
+error[E0723]: unsizing casts are only allowed for references right now
+  --> $DIR/unsizing-cast-non-null.rs:6:5
+   |
+LL |     NonNull::<[T; 0]>::dangling()
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
+   = help: add `#![feature(const_fn)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/deprecation/atomic_initializers.fixed b/src/test/ui/deprecation/atomic_initializers.fixed
index d8485ed7da1..4fb0aeeb573 100644
--- a/src/test/ui/deprecation/atomic_initializers.fixed
+++ b/src/test/ui/deprecation/atomic_initializers.fixed
@@ -6,6 +6,6 @@ use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT};
 
 #[allow(dead_code)]
 static FOO: AtomicIsize = AtomicIsize::new(0);
-//~^ WARN use of deprecated item
+//~^ WARN use of deprecated constant
 
 fn main() {}
diff --git a/src/test/ui/deprecation/atomic_initializers.rs b/src/test/ui/deprecation/atomic_initializers.rs
index b15a1bbfd92..1dcfd36d7d5 100644
--- a/src/test/ui/deprecation/atomic_initializers.rs
+++ b/src/test/ui/deprecation/atomic_initializers.rs
@@ -6,6 +6,6 @@ use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT};
 
 #[allow(dead_code)]
 static FOO: AtomicIsize = ATOMIC_ISIZE_INIT;
-//~^ WARN use of deprecated item
+//~^ WARN use of deprecated constant
 
 fn main() {}
diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr
index 75baf4a1bf9..eaf5c61b440 100644
--- a/src/test/ui/deprecation/atomic_initializers.stderr
+++ b/src/test/ui/deprecation/atomic_initializers.stderr
@@ -1,8 +1,8 @@
-warning: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new` function is now preferred
+warning: use of deprecated constant `std::sync::atomic::ATOMIC_ISIZE_INIT`: the `new` function is now preferred
   --> $DIR/atomic_initializers.rs:8:27
    |
 LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT;
-   |                           ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated item: `AtomicIsize::new(0)`
+   |                           ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated constant: `AtomicIsize::new(0)`
    |
    = note: `#[warn(deprecated)]` on by default
 
diff --git a/src/test/ui/deprecation/deprecation-in-future.rs b/src/test/ui/deprecation/deprecation-in-future.rs
index bfeab49548f..53826183d06 100644
--- a/src/test/ui/deprecation/deprecation-in-future.rs
+++ b/src/test/ui/deprecation/deprecation-in-future.rs
@@ -7,7 +7,7 @@ pub fn deprecated_future() {}
 
 fn test() {
     deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated
-    //~^ WARNING use of deprecated item 'deprecated_future': text [deprecated]
+    //~^ WARNING use of deprecated function `deprecated_future`: text [deprecated]
 }
 
 fn main() {}
diff --git a/src/test/ui/deprecation/deprecation-in-future.stderr b/src/test/ui/deprecation/deprecation-in-future.stderr
index 3040dcd9939..6561ec74349 100644
--- a/src/test/ui/deprecation/deprecation-in-future.stderr
+++ b/src/test/ui/deprecation/deprecation-in-future.stderr
@@ -1,4 +1,4 @@
-warning: use of deprecated item 'deprecated_future': text
+warning: use of deprecated function `deprecated_future`: text
   --> $DIR/deprecation-in-future.rs:9:5
    |
 LL |     deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated
diff --git a/src/test/ui/deprecation/deprecation-lint-2.rs b/src/test/ui/deprecation/deprecation-lint-2.rs
index 2aa0d0c64d2..16ed6d4ecd6 100644
--- a/src/test/ui/deprecation/deprecation-lint-2.rs
+++ b/src/test/ui/deprecation/deprecation-lint-2.rs
@@ -1,5 +1,5 @@
 // aux-build:deprecation-lint.rs
-// error-pattern: use of deprecated item
+// error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 
diff --git a/src/test/ui/deprecation/deprecation-lint-2.stderr b/src/test/ui/deprecation/deprecation-lint-2.stderr
index 65152a2f9ab..b81d4bf402a 100644
--- a/src/test/ui/deprecation/deprecation-lint-2.stderr
+++ b/src/test/ui/deprecation/deprecation-lint-2.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'deprecation_lint::deprecated': text
+error: use of deprecated function `deprecation_lint::deprecated`: text
   --> $DIR/deprecation-lint-2.rs:12:5
    |
 LL |     macro_test!();
diff --git a/src/test/ui/deprecation/deprecation-lint-3.rs b/src/test/ui/deprecation/deprecation-lint-3.rs
index ae2dd7aac81..e6e1587daeb 100644
--- a/src/test/ui/deprecation/deprecation-lint-3.rs
+++ b/src/test/ui/deprecation/deprecation-lint-3.rs
@@ -1,5 +1,5 @@
 // aux-build:deprecation-lint.rs
-// error-pattern: use of deprecated item
+// error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 #![allow(warnings)]
diff --git a/src/test/ui/deprecation/deprecation-lint-3.stderr b/src/test/ui/deprecation/deprecation-lint-3.stderr
index b450f74d7f3..6f7cd9be2dd 100644
--- a/src/test/ui/deprecation/deprecation-lint-3.stderr
+++ b/src/test/ui/deprecation/deprecation-lint-3.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'deprecation_lint::deprecated_text': text
+error: use of deprecated function `deprecation_lint::deprecated_text`: text
   --> $DIR/deprecation-lint-3.rs:13:5
    |
 LL |     macro_test_arg_nested!(deprecated_text);
diff --git a/src/test/ui/deprecation/deprecation-lint-nested.rs b/src/test/ui/deprecation/deprecation-lint-nested.rs
index ee6f0a22363..589522cdbdf 100644
--- a/src/test/ui/deprecation/deprecation-lint-nested.rs
+++ b/src/test/ui/deprecation/deprecation-lint-nested.rs
@@ -52,19 +52,19 @@ mod loud {
     #[deprecated]
     const DEPRECATED_CONST: u8 = 1;
 
-    struct Foo(DeprecatedType); //~ ERROR use of deprecated item
+    struct Foo(DeprecatedType); //~ ERROR use of deprecated type alias
 
-    impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated item
+    impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated trait
 
     impl Foo {
-        fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated item
-            deprecated_fn(); //~ ERROR use of deprecated item
+        fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated trait
+            deprecated_fn(); //~ ERROR use of deprecated function
         }
     }
 
     fn foo() -> u8 {
-        DEPRECATED_STATIC + //~ ERROR use of deprecated item
-        DEPRECATED_CONST //~ ERROR use of deprecated item
+        DEPRECATED_STATIC + //~ ERROR use of deprecated static
+        DEPRECATED_CONST //~ ERROR use of deprecated const
     }
 }
 
diff --git a/src/test/ui/deprecation/deprecation-lint-nested.stderr b/src/test/ui/deprecation/deprecation-lint-nested.stderr
index b71f90014fe..47607b8cc7c 100644
--- a/src/test/ui/deprecation/deprecation-lint-nested.stderr
+++ b/src/test/ui/deprecation/deprecation-lint-nested.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'loud::DeprecatedType'
+error: use of deprecated type alias `loud::DeprecatedType`
   --> $DIR/deprecation-lint-nested.rs:55:16
    |
 LL |     struct Foo(DeprecatedType);
@@ -10,31 +10,31 @@ note: the lint level is defined here
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
 
-error: use of deprecated item 'loud::DeprecatedTrait'
+error: use of deprecated trait `loud::DeprecatedTrait`
   --> $DIR/deprecation-lint-nested.rs:57:10
    |
 LL |     impl DeprecatedTrait for Foo {}
    |          ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'loud::DEPRECATED_STATIC'
+error: use of deprecated static `loud::DEPRECATED_STATIC`
   --> $DIR/deprecation-lint-nested.rs:66:9
    |
 LL |         DEPRECATED_STATIC +
    |         ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'loud::DEPRECATED_CONST'
+error: use of deprecated constant `loud::DEPRECATED_CONST`
   --> $DIR/deprecation-lint-nested.rs:67:9
    |
 LL |         DEPRECATED_CONST
    |         ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'loud::DeprecatedTrait'
+error: use of deprecated trait `loud::DeprecatedTrait`
   --> $DIR/deprecation-lint-nested.rs:60:19
    |
 LL |         fn bar<T: DeprecatedTrait>() {
    |                   ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'loud::deprecated_fn'
+error: use of deprecated function `loud::deprecated_fn`
   --> $DIR/deprecation-lint-nested.rs:61:13
    |
 LL |             deprecated_fn();
diff --git a/src/test/ui/deprecation/deprecation-lint.rs b/src/test/ui/deprecation/deprecation-lint.rs
index 26271395005..1932344fc57 100644
--- a/src/test/ui/deprecation/deprecation-lint.rs
+++ b/src/test/ui/deprecation/deprecation-lint.rs
@@ -14,86 +14,86 @@ mod cross_crate {
         type Foo = MethodTester;
         let foo = MethodTester;
 
-        deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated'
-        foo.method_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated'
-        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated'
-        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated'
-        foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-
-        deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text
-        foo.method_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text
-        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text
-        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
-
-        let _ = DeprecatedStruct { //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedStruct': text
-            i: 0 //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedStruct::i': text
+        deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated`
+        foo.method_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+
+        deprecated_text(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text
+        foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+
+        let _ = DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedStruct`: text
+            i: 0 //~ ERROR use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text
         };
 
-        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedUnitStruct': text
+        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedUnitStruct`: text
 
-        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'deprecation_lint::Enum::DeprecatedVariant': text
+        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text
 
-        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTupleStruct': text
+        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text
 
-        let _ = nested::DeprecatedStruct { //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedStruct': text
-            i: 0 //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedStruct::i': text
+        let _ = nested::DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text
+            i: 0 //~ ERROR use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: text
         };
 
-        let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedUnitStruct': text
+        let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text
 
-        let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'deprecation_lint::nested::Enum::DeprecatedVariant': text
+        let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text
 
-        let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'deprecation_lint::nested::DeprecatedTupleStruct': text
+        let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text
 
         // At the moment, the lint checker only checks stability in
         // in the arguments of macros.
         // Eventually, we will want to lint the contents of the
         // macro in the module *defining* it. Also, stability levels
         // on macros themselves are not yet linted.
-        macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text
-        macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_text': text
+        macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text
+        macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
     }
 
     fn test_method_object(foo: &Trait) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
     }
 
     struct S;
 
-    impl DeprecatedTrait for S {} //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTrait': text
-    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item 'deprecation_lint::DeprecatedTrait': text
+    impl DeprecatedTrait for S {} //~ ERROR use of deprecated trait `deprecation_lint::DeprecatedTrait`: text
+    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated trait `deprecation_lint::DeprecatedTrait`: text
 
     pub fn foo() {
         let x = Stable {
             override2: 3,
-            //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text
+            //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text
         };
 
         let _ = x.override2;
-        //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text
+        //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text
 
         let Stable {
             override2: _
-            //~^ ERROR use of deprecated item 'deprecation_lint::Stable::override2': text
+            //~^ ERROR use of deprecated field `deprecation_lint::Stable::override2`: text
         } = x;
         // all fine
         let Stable { .. } = x;
@@ -101,56 +101,56 @@ mod cross_crate {
         let x = Stable2(1, 2, 3);
 
         let _ = x.2;
-        //~^ ERROR use of deprecated item 'deprecation_lint::Stable2::2': text
+        //~^ ERROR use of deprecated field `deprecation_lint::Stable2::2`: text
 
         let Stable2(_,
                    _,
                    _)
-            //~^ ERROR use of deprecated item 'deprecation_lint::Stable2::2': text
+            //~^ ERROR use of deprecated field `deprecation_lint::Stable2::2`: text
             = x;
         // all fine
         let Stable2(..) = x;
 
         let x = Deprecated {
-            //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text
+            //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text
             inherit: 1,
-            //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text
+            //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text
         };
 
         let _ = x.inherit;
-        //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text
+        //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text
 
         let Deprecated {
-            //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text
+            //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text
             inherit: _,
-            //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated::inherit': text
+            //~^ ERROR use of deprecated field `deprecation_lint::Deprecated::inherit`: text
         } = x;
 
         let Deprecated
-            //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated': text
+            //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated`: text
             { .. } = x;
 
         let x = Deprecated2(1, 2, 3);
-        //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text
+        //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text
 
         let _ = x.0;
-        //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::0': text
+        //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::0`: text
         let _ = x.1;
-        //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::1': text
+        //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::1`: text
         let _ = x.2;
-        //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::2': text
+        //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::2`: text
 
         let Deprecated2
-        //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text
+        //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text
             (_,
-             //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::0': text
+             //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::0`: text
              _,
-             //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::1': text
+             //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::1`: text
              _)
-             //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2::2': text
+             //~^ ERROR use of deprecated field `deprecation_lint::Deprecated2::2`: text
             = x;
         let Deprecated2
-        //~^ ERROR use of deprecated item 'deprecation_lint::Deprecated2': text
+        //~^ ERROR use of deprecated struct `deprecation_lint::Deprecated2`: text
             // the patterns are all fine:
             (..) = x;
     }
@@ -160,7 +160,7 @@ mod inheritance {
     use deprecation_lint::*;
 
     fn test_inheritance() {
-        deprecated_mod::deprecated(); //~ ERROR use of deprecated item 'deprecation_lint::deprecated_mod::deprecated': text
+        deprecated_mod::deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text
     }
 }
 
@@ -243,65 +243,65 @@ mod this_crate {
         type Foo = MethodTester;
         let foo = MethodTester;
 
-        deprecated(); //~ ERROR use of deprecated item 'this_crate::deprecated'
-        foo.method_deprecated(); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated'
-        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated'
-        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated'
-        foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-
-        deprecated_text(); //~ ERROR use of deprecated item 'this_crate::deprecated_text': text
-        foo.method_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
-        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
-        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+        deprecated(); //~ ERROR use of deprecated function `this_crate::deprecated`
+        foo.method_deprecated(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+
+        deprecated_text(); //~ ERROR use of deprecated function `this_crate::deprecated_text`: text
+        foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
 
         // Future deprecations are only permitted for rustc_deprecated.
-        deprecated_future(); //~ ERROR use of deprecated item
-        deprecated_future_text(); //~ ERROR use of deprecated item
+        deprecated_future(); //~ ERROR use of deprecated function
+        deprecated_future_text(); //~ ERROR use of deprecated function
 
         let _ = DeprecatedStruct {
-            //~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text
-            i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text
+            //~^ ERROR use of deprecated struct `this_crate::DeprecatedStruct`: text
+            i: 0 //~ ERROR use of deprecated field `this_crate::DeprecatedStruct::i`: text
         };
 
-        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item 'this_crate::DeprecatedUnitStruct': text
+        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text
 
-        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'this_crate::Enum::DeprecatedVariant': text
+        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
 
-        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'this_crate::DeprecatedTupleStruct': text
+        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
 
         let _ = nested::DeprecatedStruct {
-            //~^ ERROR use of deprecated item 'this_crate::nested::DeprecatedStruct': text
-            i: 0 //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedStruct::i': text
+            //~^ ERROR use of deprecated struct `this_crate::nested::DeprecatedStruct`: text
+            i: 0 //~ ERROR use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text
         };
 
-        let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedUnitStruct': text
+        let _ = nested::DeprecatedUnitStruct; //~ ERROR use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text
 
-        let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated item 'this_crate::nested::Enum::DeprecatedVariant': text
+        let _ = nested::Enum::DeprecatedVariant; //~ ERROR use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text
 
-        let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated item 'this_crate::nested::DeprecatedTupleStruct': text
+        let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
     }
 
     fn test_method_object(foo: &Trait) {
-        foo.trait_deprecated(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+        foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
     }
 
     #[deprecated(since = "1.0.0", note = "text")]
@@ -314,7 +314,7 @@ mod this_crate {
         let _ = || {
             #[deprecated]
             fn bar() { }
-            bar(); //~ ERROR use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar'
+            bar(); //~ ERROR use of deprecated function `this_crate::test_fn_closure_body::{{closure}}#0::bar`
         };
     }
 
@@ -333,9 +333,9 @@ mod this_crate {
 
     struct S;
 
-    impl DeprecatedTrait for S { } //~ ERROR use of deprecated item 'this_crate::DeprecatedTrait': text
+    impl DeprecatedTrait for S { } //~ ERROR use of deprecated trait `this_crate::DeprecatedTrait`: text
 
-    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item 'this_crate::DeprecatedTrait': text
+    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated trait `this_crate::DeprecatedTrait`: text
 }
 
 mod this_crate2 {
@@ -361,15 +361,15 @@ mod this_crate2 {
     pub fn foo() {
         let x = Stable {
             override2: 3,
-            //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text
+            //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text
         };
 
         let _ = x.override2;
-        //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text
+        //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text
 
         let Stable {
             override2: _
-            //~^ ERROR use of deprecated item 'this_crate2::Stable::override2': text
+            //~^ ERROR use of deprecated field `this_crate2::Stable::override2`: text
         } = x;
         // all fine
         let Stable { .. } = x;
@@ -377,57 +377,57 @@ mod this_crate2 {
         let x = Stable2(1, 2, 3);
 
         let _ = x.2;
-        //~^ ERROR use of deprecated item 'this_crate2::Stable2::2': text
+        //~^ ERROR use of deprecated field `this_crate2::Stable2::2`: text
 
         let Stable2(_,
                    _,
                    _)
-            //~^ ERROR use of deprecated item 'this_crate2::Stable2::2': text
+            //~^ ERROR use of deprecated field `this_crate2::Stable2::2`: text
             = x;
         // all fine
         let Stable2(..) = x;
 
         let x = Deprecated {
-            //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text
+            //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text
             inherit: 1,
-            //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text
+            //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text
         };
 
         let _ = x.inherit;
-        //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text
+        //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text
 
         let Deprecated {
-            //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text
+            //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text
             inherit: _,
-            //~^ ERROR use of deprecated item 'this_crate2::Deprecated::inherit': text
+            //~^ ERROR use of deprecated field `this_crate2::Deprecated::inherit`: text
         } = x;
 
         let Deprecated
-            //~^ ERROR use of deprecated item 'this_crate2::Deprecated': text
+            //~^ ERROR use of deprecated struct `this_crate2::Deprecated`: text
             // the patterns are all fine:
             { .. } = x;
 
         let x = Deprecated2(1, 2, 3);
-        //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text
+        //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text
 
         let _ = x.0;
-        //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::0': text
+        //~^ ERROR use of deprecated field `this_crate2::Deprecated2::0`: text
         let _ = x.1;
-        //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::1': text
+        //~^ ERROR use of deprecated field `this_crate2::Deprecated2::1`: text
         let _ = x.2;
-        //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::2': text
+        //~^ ERROR use of deprecated field `this_crate2::Deprecated2::2`: text
 
         let Deprecated2
-        //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text
+        //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text
             (_,
-             //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::0': text
+             //~^ ERROR use of deprecated field `this_crate2::Deprecated2::0`: text
              _,
-             //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::1': text
+             //~^ ERROR use of deprecated field `this_crate2::Deprecated2::1`: text
              _)
-            //~^ ERROR use of deprecated item 'this_crate2::Deprecated2::2': text
+            //~^ ERROR use of deprecated field `this_crate2::Deprecated2::2`: text
             = x;
         let Deprecated2
-        //~^ ERROR use of deprecated item 'this_crate2::Deprecated2': text
+        //~^ ERROR use of deprecated tuple struct `this_crate2::Deprecated2`: text
             // the patterns are all fine:
             (..) = x;
     }
diff --git a/src/test/ui/deprecation/deprecation-lint.stderr b/src/test/ui/deprecation/deprecation-lint.stderr
index 362a901d77d..03a2ec7edc9 100644
--- a/src/test/ui/deprecation/deprecation-lint.stderr
+++ b/src/test/ui/deprecation/deprecation-lint.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'deprecation_lint::deprecated': text
+error: use of deprecated function `deprecation_lint::deprecated`: text
   --> $DIR/deprecation-lint.rs:17:9
    |
 LL |         deprecated();
@@ -10,727 +10,727 @@ note: the lint level is defined here
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:22:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:24:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::deprecated_text': text
+error: use of deprecated function `deprecation_lint::deprecated_text`: text
   --> $DIR/deprecation-lint.rs:26:9
    |
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:31:9
    |
-LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:33:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::DeprecatedStruct': text
+error: use of deprecated struct `deprecation_lint::DeprecatedStruct`: text
   --> $DIR/deprecation-lint.rs:35:17
    |
 LL |         let _ = DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::DeprecatedUnitStruct': text
+error: use of deprecated struct `deprecation_lint::DeprecatedUnitStruct`: text
   --> $DIR/deprecation-lint.rs:39:17
    |
 LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Enum::DeprecatedVariant': text
+error: use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text
   --> $DIR/deprecation-lint.rs:41:17
    |
 LL |         let _ = Enum::DeprecatedVariant;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::DeprecatedTupleStruct': text
+error: use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text
   --> $DIR/deprecation-lint.rs:43:17
    |
 LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::nested::DeprecatedStruct': text
+error: use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text
   --> $DIR/deprecation-lint.rs:45:17
    |
 LL |         let _ = nested::DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::nested::DeprecatedUnitStruct': text
+error: use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text
   --> $DIR/deprecation-lint.rs:49:17
    |
 LL |         let _ = nested::DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::nested::Enum::DeprecatedVariant': text
+error: use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text
   --> $DIR/deprecation-lint.rs:51:17
    |
-LL |         let _ = nested::Enum::DeprecatedVariant;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   let _ = nested::Enum::DeprecatedVariant;
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::nested::DeprecatedTupleStruct': text
+error: use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text
   --> $DIR/deprecation-lint.rs:53:17
    |
-LL |         let _ = nested::DeprecatedTupleStruct (1);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   let _ = nested::DeprecatedTupleStruct (1);
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::deprecated_text': text
+error: use of deprecated function `deprecation_lint::deprecated_text`: text
   --> $DIR/deprecation-lint.rs:60:25
    |
 LL |         macro_test_arg!(deprecated_text());
    |                         ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::deprecated_text': text
+error: use of deprecated function `deprecation_lint::deprecated_text`: text
   --> $DIR/deprecation-lint.rs:61:41
    |
 LL |         macro_test_arg!(macro_test_arg!(deprecated_text()));
    |                                         ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:66:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:68:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:70:9
    |
-LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:72:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::DeprecatedTrait': text
+error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text
   --> $DIR/deprecation-lint.rs:82:10
    |
 LL |     impl DeprecatedTrait for S {}
    |          ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::DeprecatedTrait': text
+error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text
   --> $DIR/deprecation-lint.rs:83:24
    |
 LL |     trait LocalTrait : DeprecatedTrait { }
    |                        ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated': text
+error: use of deprecated struct `deprecation_lint::Deprecated`: text
   --> $DIR/deprecation-lint.rs:114:17
    |
 LL |         let x = Deprecated {
    |                 ^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated': text
+error: use of deprecated struct `deprecation_lint::Deprecated`: text
   --> $DIR/deprecation-lint.rs:123:13
    |
 LL |         let Deprecated {
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated': text
+error: use of deprecated struct `deprecation_lint::Deprecated`: text
   --> $DIR/deprecation-lint.rs:129:13
    |
 LL |         let Deprecated
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2': text
+error: use of deprecated struct `deprecation_lint::Deprecated2`: text
   --> $DIR/deprecation-lint.rs:133:17
    |
 LL |         let x = Deprecated2(1, 2, 3);
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2': text
+error: use of deprecated struct `deprecation_lint::Deprecated2`: text
   --> $DIR/deprecation-lint.rs:143:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2': text
+error: use of deprecated struct `deprecation_lint::Deprecated2`: text
   --> $DIR/deprecation-lint.rs:152:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::deprecated_mod::deprecated': text
+error: use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text
   --> $DIR/deprecation-lint.rs:163:9
    |
 LL |         deprecated_mod::deprecated();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::deprecated': text
+error: use of deprecated function `this_crate::deprecated`: text
   --> $DIR/deprecation-lint.rs:246:9
    |
 LL |         deprecated();
    |         ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:251:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:253:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::deprecated_text': text
+error: use of deprecated function `this_crate::deprecated_text`: text
   --> $DIR/deprecation-lint.rs:255:9
    |
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:260:9
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:262:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::deprecated_future': text
+error: use of deprecated function `this_crate::deprecated_future`: text
   --> $DIR/deprecation-lint.rs:265:9
    |
 LL |         deprecated_future();
    |         ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::deprecated_future_text': text
+error: use of deprecated function `this_crate::deprecated_future_text`: text
   --> $DIR/deprecation-lint.rs:266:9
    |
 LL |         deprecated_future_text();
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::DeprecatedStruct': text
+error: use of deprecated struct `this_crate::DeprecatedStruct`: text
   --> $DIR/deprecation-lint.rs:268:17
    |
 LL |         let _ = DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::DeprecatedUnitStruct': text
+error: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text
   --> $DIR/deprecation-lint.rs:273:17
    |
 LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text
+error: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
   --> $DIR/deprecation-lint.rs:275:17
    |
 LL |         let _ = Enum::DeprecatedVariant;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::DeprecatedTupleStruct': text
+error: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
   --> $DIR/deprecation-lint.rs:277:17
    |
 LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::nested::DeprecatedStruct': text
+error: use of deprecated struct `this_crate::nested::DeprecatedStruct`: text
   --> $DIR/deprecation-lint.rs:279:17
    |
 LL |         let _ = nested::DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::nested::DeprecatedUnitStruct': text
+error: use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text
   --> $DIR/deprecation-lint.rs:284:17
    |
 LL |         let _ = nested::DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::nested::Enum::DeprecatedVariant': text
+error: use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text
   --> $DIR/deprecation-lint.rs:286:17
    |
-LL |         let _ = nested::Enum::DeprecatedVariant;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   let _ = nested::Enum::DeprecatedVariant;
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::nested::DeprecatedTupleStruct': text
+error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text
   --> $DIR/deprecation-lint.rs:288:17
    |
-LL |         let _ = nested::DeprecatedTupleStruct (1);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   let _ = nested::DeprecatedTupleStruct (1);
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:293:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:295:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:297:9
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:299:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::test_fn_closure_body::{{closure}}#0::bar'
+error: use of deprecated function `this_crate::test_fn_closure_body::{{closure}}#0::bar`
   --> $DIR/deprecation-lint.rs:317:13
    |
 LL |             bar();
    |             ^^^
 
-error: use of deprecated item 'this_crate::DeprecatedTrait': text
+error: use of deprecated trait `this_crate::DeprecatedTrait`: text
   --> $DIR/deprecation-lint.rs:336:10
    |
 LL |     impl DeprecatedTrait for S { }
    |          ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::DeprecatedTrait': text
+error: use of deprecated trait `this_crate::DeprecatedTrait`: text
   --> $DIR/deprecation-lint.rs:338:24
    |
 LL |     trait LocalTrait : DeprecatedTrait { }
    |                        ^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated': text
+error: use of deprecated struct `this_crate2::Deprecated`: text
   --> $DIR/deprecation-lint.rs:390:17
    |
 LL |         let x = Deprecated {
    |                 ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated': text
+error: use of deprecated struct `this_crate2::Deprecated`: text
   --> $DIR/deprecation-lint.rs:399:13
    |
 LL |         let Deprecated {
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated': text
+error: use of deprecated struct `this_crate2::Deprecated`: text
   --> $DIR/deprecation-lint.rs:405:13
    |
 LL |         let Deprecated
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated2': text
+error: use of deprecated tuple struct `this_crate2::Deprecated2`: text
   --> $DIR/deprecation-lint.rs:410:17
    |
 LL |         let x = Deprecated2(1, 2, 3);
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated2': text
+error: use of deprecated tuple struct `this_crate2::Deprecated2`: text
   --> $DIR/deprecation-lint.rs:420:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated2': text
+error: use of deprecated tuple struct `this_crate2::Deprecated2`: text
   --> $DIR/deprecation-lint.rs:429:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text
+error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:18:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text
+error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:19:9
    |
 LL |         Foo::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated': text
+error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:20:9
    |
 LL |         <Foo>::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:21:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:23:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:27:13
    |
-LL |         foo.method_deprecated_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.method_deprecated_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:28:9
    |
-LL |         Foo::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Foo::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::MethodTester::method_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:29:9
    |
-LL |         <Foo>::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:30:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:32:9
    |
-LL |         <Foo>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::DeprecatedStruct::i': text
+error: use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text
   --> $DIR/deprecation-lint.rs:36:13
    |
 LL |             i: 0
    |             ^^^^
 
-error: use of deprecated item 'deprecation_lint::nested::DeprecatedStruct::i': text
+error: use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: text
   --> $DIR/deprecation-lint.rs:46:13
    |
 LL |             i: 0
    |             ^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:65:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:67:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:69:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:71:9
    |
-LL |         <Foo>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:76:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:77:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Stable::override2': text
+error: use of deprecated field `deprecation_lint::Stable::override2`: text
   --> $DIR/deprecation-lint.rs:87:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Stable::override2': text
+error: use of deprecated field `deprecation_lint::Stable::override2`: text
   --> $DIR/deprecation-lint.rs:91:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Stable::override2': text
+error: use of deprecated field `deprecation_lint::Stable::override2`: text
   --> $DIR/deprecation-lint.rs:95:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Stable2::2': text
+error: use of deprecated field `deprecation_lint::Stable2::2`: text
   --> $DIR/deprecation-lint.rs:103:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'deprecation_lint::Stable2::2': text
+error: use of deprecated field `deprecation_lint::Stable2::2`: text
   --> $DIR/deprecation-lint.rs:108:20
    |
 LL |                    _)
    |                    ^
 
-error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text
+error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text
   --> $DIR/deprecation-lint.rs:116:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text
+error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text
   --> $DIR/deprecation-lint.rs:120:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated::inherit': text
+error: use of deprecated field `deprecation_lint::Deprecated::inherit`: text
   --> $DIR/deprecation-lint.rs:125:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2::0': text
+error: use of deprecated field `deprecation_lint::Deprecated2::0`: text
   --> $DIR/deprecation-lint.rs:136:17
    |
 LL |         let _ = x.0;
    |                 ^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2::1': text
+error: use of deprecated field `deprecation_lint::Deprecated2::1`: text
   --> $DIR/deprecation-lint.rs:138:17
    |
 LL |         let _ = x.1;
    |                 ^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2::2': text
+error: use of deprecated field `deprecation_lint::Deprecated2::2`: text
   --> $DIR/deprecation-lint.rs:140:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2::0': text
+error: use of deprecated field `deprecation_lint::Deprecated2::0`: text
   --> $DIR/deprecation-lint.rs:145:14
    |
 LL |             (_,
    |              ^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2::1': text
+error: use of deprecated field `deprecation_lint::Deprecated2::1`: text
   --> $DIR/deprecation-lint.rs:147:14
    |
 LL |              _,
    |              ^
 
-error: use of deprecated item 'deprecation_lint::Deprecated2::2': text
+error: use of deprecated field `deprecation_lint::Deprecated2::2`: text
   --> $DIR/deprecation-lint.rs:149:14
    |
 LL |              _)
    |              ^
 
-error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text
+error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:247:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text
+error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:248:9
    |
 LL |         Foo::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::MethodTester::method_deprecated': text
+error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/deprecation-lint.rs:249:9
    |
 LL |         <Foo>::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:250:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:252:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
+error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:256:13
    |
-LL |         foo.method_deprecated_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.method_deprecated_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
+error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:257:9
    |
-LL |         Foo::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Foo::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
+error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:258:9
    |
-LL |         <Foo>::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:259:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:261:9
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::DeprecatedStruct::i': text
+error: use of deprecated field `this_crate::DeprecatedStruct::i`: text
   --> $DIR/deprecation-lint.rs:270:13
    |
 LL |             i: 0
    |             ^^^^
 
-error: use of deprecated item 'this_crate::nested::DeprecatedStruct::i': text
+error: use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text
   --> $DIR/deprecation-lint.rs:281:13
    |
 LL |             i: 0
    |             ^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:292:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:294:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:296:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:298:9
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/deprecation-lint.rs:303:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/deprecation-lint.rs:304:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Stable::override2': text
+error: use of deprecated field `this_crate2::Stable::override2`: text
   --> $DIR/deprecation-lint.rs:363:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Stable::override2': text
+error: use of deprecated field `this_crate2::Stable::override2`: text
   --> $DIR/deprecation-lint.rs:367:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Stable::override2': text
+error: use of deprecated field `this_crate2::Stable::override2`: text
   --> $DIR/deprecation-lint.rs:371:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Stable2::2': text
+error: use of deprecated field `this_crate2::Stable2::2`: text
   --> $DIR/deprecation-lint.rs:379:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'this_crate2::Stable2::2': text
+error: use of deprecated field `this_crate2::Stable2::2`: text
   --> $DIR/deprecation-lint.rs:384:20
    |
 LL |                    _)
    |                    ^
 
-error: use of deprecated item 'this_crate2::Deprecated::inherit': text
+error: use of deprecated field `this_crate2::Deprecated::inherit`: text
   --> $DIR/deprecation-lint.rs:392:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated::inherit': text
+error: use of deprecated field `this_crate2::Deprecated::inherit`: text
   --> $DIR/deprecation-lint.rs:396:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated::inherit': text
+error: use of deprecated field `this_crate2::Deprecated::inherit`: text
   --> $DIR/deprecation-lint.rs:401:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate2::Deprecated2::0': text
+error: use of deprecated field `this_crate2::Deprecated2::0`: text
   --> $DIR/deprecation-lint.rs:413:17
    |
 LL |         let _ = x.0;
    |                 ^^^
 
-error: use of deprecated item 'this_crate2::Deprecated2::1': text
+error: use of deprecated field `this_crate2::Deprecated2::1`: text
   --> $DIR/deprecation-lint.rs:415:17
    |
 LL |         let _ = x.1;
    |                 ^^^
 
-error: use of deprecated item 'this_crate2::Deprecated2::2': text
+error: use of deprecated field `this_crate2::Deprecated2::2`: text
   --> $DIR/deprecation-lint.rs:417:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'this_crate2::Deprecated2::0': text
+error: use of deprecated field `this_crate2::Deprecated2::0`: text
   --> $DIR/deprecation-lint.rs:422:14
    |
 LL |             (_,
    |              ^
 
-error: use of deprecated item 'this_crate2::Deprecated2::1': text
+error: use of deprecated field `this_crate2::Deprecated2::1`: text
   --> $DIR/deprecation-lint.rs:424:14
    |
 LL |              _,
    |              ^
 
-error: use of deprecated item 'this_crate2::Deprecated2::2': text
+error: use of deprecated field `this_crate2::Deprecated2::2`: text
   --> $DIR/deprecation-lint.rs:426:14
    |
 LL |              _)
diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.rs b/src/test/ui/deprecation/rustc_deprecation-in-future.rs
index a19363c5129..6a619bcc49c 100644
--- a/src/test/ui/deprecation/rustc_deprecation-in-future.rs
+++ b/src/test/ui/deprecation/rustc_deprecation-in-future.rs
@@ -11,5 +11,5 @@
 pub struct S;
 
 fn main() {
-    let _ = S; //~ ERROR use of item 'S' that will be deprecated in future version 99.99.99: effectively never
+    let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
 }
diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
index 4aff11ad66f..e4f50d10dad 100644
--- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
+++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
@@ -1,4 +1,4 @@
-error: use of item 'S' that will be deprecated in future version 99.99.99: effectively never
+error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
   --> $DIR/rustc_deprecation-in-future.rs:14:13
    |
 LL |     let _ = S;
diff --git a/src/test/ui/deprecation/suggestion.stderr b/src/test/ui/deprecation/suggestion.stderr
index b60d420b546..8a7cb1def90 100644
--- a/src/test/ui/deprecation/suggestion.stderr
+++ b/src/test/ui/deprecation/suggestion.stderr
@@ -1,8 +1,8 @@
-error: use of deprecated item 'Foo::deprecated': replaced by `replacement`
+error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement`
   --> $DIR/suggestion.rs:27:9
    |
 LL |     foo.deprecated();
-   |         ^^^^^^^^^^ help: replace the use of the deprecated item: `replacement`
+   |         ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement`
    |
 note: the lint level is defined here
   --> $DIR/suggestion.rs:7:9
diff --git a/src/test/ui/issues/issue-17337.rs b/src/test/ui/issues/issue-17337.rs
index 65f2f8fc5ac..3fd81401e00 100644
--- a/src/test/ui/issues/issue-17337.rs
+++ b/src/test/ui/issues/issue-17337.rs
@@ -13,5 +13,5 @@ impl Foo {
 
 fn main() {
     Foo
-    .foo(); //~ ERROR use of deprecated item
+    .foo(); //~ ERROR use of deprecated
 }
diff --git a/src/test/ui/issues/issue-17337.stderr b/src/test/ui/issues/issue-17337.stderr
index 4a8116b1ffd..34c2eb05fff 100644
--- a/src/test/ui/issues/issue-17337.stderr
+++ b/src/test/ui/issues/issue-17337.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'Foo::foo': text
+error: use of deprecated associated function `Foo::foo`: text
   --> $DIR/issue-17337.rs:16:6
    |
 LL |     .foo();
diff --git a/src/test/ui/issues/issue-37131.rs b/src/test/ui/issues/issue-37131.rs
index aa3b6ea86bb..ac2d1d1ed8b 100644
--- a/src/test/ui/issues/issue-37131.rs
+++ b/src/test/ui/issues/issue-37131.rs
@@ -3,6 +3,7 @@
 
 // compile-flags: --target=thumbv6m-none-eabi
 // ignore-arm
+// needs-llvm-components: arm
 
 // error-pattern:target may not be installed
 fn main() { }
diff --git a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs
index 9449376513f..ddb070ddf9f 100644
--- a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs
+++ b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs
@@ -1,6 +1,7 @@
 //~ ERROR 1:1: 1:1: can't find crate for `core` [E0463]
 
 // compile-flags: --target thumbv7em-none-eabihf
+// needs-llvm-components: arm
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![no_std]
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
index 1d5eabd6170..f713dee507f 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
@@ -1,5 +1,3 @@
-#![feature(inner_deref)]
-
 fn main() {
     let _result = &Ok(42).as_deref();
 //~^ ERROR no method named `as_deref` found
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
index f33e9c7823e..96524c30959 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `as_deref` found for enum `std::result::Result<{integer}, _>` in the current scope
-  --> $DIR/result-as_deref.rs:4:27
+  --> $DIR/result-as_deref.rs:2:27
    |
 LL |     let _result = &Ok(42).as_deref();
    |                           ^^^^^^^^ help: there is an associated function with a similar name: `as_ref`
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs
deleted file mode 100644
index 104aa3bcadf..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(inner_deref)]
-
-fn main() {
-    let _result = &Err(41).as_deref_err();
-//~^ ERROR no method named `as_deref_err` found
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr
deleted file mode 100644
index 68ebfab95c4..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0599]: no method named `as_deref_err` found for enum `std::result::Result<_, {integer}>` in the current scope
-  --> $DIR/result-as_deref_err.rs:4:28
-   |
-LL |     let _result = &Err(41).as_deref_err();
-   |                            ^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_mut`
-   |
-   = note: the method `as_deref_err` exists but the following trait bounds were not satisfied:
-           `{integer}: std::ops::Deref`
-           `<{integer} as std::ops::Deref>::Target = _`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
index c897ab3531f..3af7033dd5d 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
@@ -1,5 +1,3 @@
-#![feature(inner_deref)]
-
 fn main() {
     let _result = &mut Ok(42).as_deref_mut();
 //~^ ERROR no method named `as_deref_mut` found
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
index d2ba1049b76..73266bc7f68 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
@@ -1,8 +1,8 @@
 error[E0599]: no method named `as_deref_mut` found for enum `std::result::Result<{integer}, _>` in the current scope
-  --> $DIR/result-as_deref_mut.rs:4:31
+  --> $DIR/result-as_deref_mut.rs:2:31
    |
 LL |     let _result = &mut Ok(42).as_deref_mut();
-   |                               ^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_err`
+   |                               ^^^^^^^^^^^^ method not found in `std::result::Result<{integer}, _>`
    |
    = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
            `{integer}: std::ops::DerefMut`
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs
deleted file mode 100644
index b7849ecb6d2..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(inner_deref)]
-
-fn main() {
-    let _result = &mut Err(41).as_deref_mut_err();
-//~^ ERROR no method named `as_deref_mut_err` found
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr
deleted file mode 100644
index d724ae5c74b..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0599]: no method named `as_deref_mut_err` found for enum `std::result::Result<_, {integer}>` in the current scope
-  --> $DIR/result-as_deref_mut_err.rs:4:32
-   |
-LL |     let _result = &mut Err(41).as_deref_mut_err();
-   |                                ^^^^^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_mut`
-   |
-   = note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied:
-           `{integer}: std::ops::DerefMut`
-           `<{integer} as std::ops::Deref>::Target = _`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs
index d38eb826678..e6a9451a060 100644
--- a/src/test/ui/issues/issue-50993.rs
+++ b/src/test/ui/issues/issue-50993.rs
@@ -1,4 +1,5 @@
 // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf
+// needs-llvm-components: arm
 // build-pass
 // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf`
 
diff --git a/src/test/ui/issues/issue-72574-1.rs b/src/test/ui/issues/issue-72574-1.rs
index efbb0bfb150..1b80a21793a 100644
--- a/src/test/ui/issues/issue-72574-1.rs
+++ b/src/test/ui/issues/issue-72574-1.rs
@@ -6,3 +6,5 @@ fn main() {
     }
 }
 //~^^^^ ERROR `_x @` is not allowed in a tuple
+//~| ERROR: `..` patterns are not allowed here
+//~| ERROR: mismatched types
diff --git a/src/test/ui/issues/issue-72574-1.stderr b/src/test/ui/issues/issue-72574-1.stderr
index 329f7d008d4..92ebb45e88d 100644
--- a/src/test/ui/issues/issue-72574-1.stderr
+++ b/src/test/ui/issues/issue-72574-1.stderr
@@ -10,5 +10,25 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining
 LL |         (_a, ..) => {}
    |              ^^
 
-error: aborting due to previous error
+error: `..` patterns are not allowed here
+  --> $DIR/issue-72574-1.rs:4:19
+   |
+LL |         (_a, _x @ ..) => {}
+   |                   ^^
+   |
+   = note: only allowed in tuple, tuple struct, and slice patterns
+
+error[E0308]: mismatched types
+  --> $DIR/issue-72574-1.rs:4:9
+   |
+LL |     match x {
+   |           - this expression has type `({integer}, {integer}, {integer})`
+LL |         (_a, _x @ ..) => {}
+   |         ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
+   |
+   = note: expected tuple `({integer}, {integer}, {integer})`
+              found tuple `(_, _)`
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-72574-2.rs b/src/test/ui/issues/issue-72574-2.rs
index 0c8f6fcc508..0ad2db848b2 100644
--- a/src/test/ui/issues/issue-72574-2.rs
+++ b/src/test/ui/issues/issue-72574-2.rs
@@ -8,3 +8,5 @@ fn main() {
     }
 }
 //~^^^^ ERROR `_x @` is not allowed in a tuple struct
+//~| ERROR: `..` patterns are not allowed here
+//~| ERROR: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr
index 6faa57bcca6..0a9c868af7a 100644
--- a/src/test/ui/issues/issue-72574-2.stderr
+++ b/src/test/ui/issues/issue-72574-2.stderr
@@ -10,5 +10,23 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining
 LL |         Binder(_a, ..) => {}
    |                    ^^
 
-error: aborting due to previous error
+error: `..` patterns are not allowed here
+  --> $DIR/issue-72574-2.rs:6:25
+   |
+LL |         Binder(_a, _x @ ..) => {}
+   |                         ^^
+   |
+   = note: only allowed in tuple, tuple struct, and slice patterns
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/issue-72574-2.rs:6:9
+   |
+LL | struct Binder(i32, i32, i32);
+   | ----------------------------- tuple struct defined here
+...
+LL |         Binder(_a, _x @ ..) => {}
+   |         ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0023`.
diff --git a/src/test/ui/issues/issue-74539.rs b/src/test/ui/issues/issue-74539.rs
deleted file mode 100644
index 75632d11c1d..00000000000
--- a/src/test/ui/issues/issue-74539.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-enum E {
-    A(u8, u8),
-}
-
-fn main() {
-    let e = E::A(2, 3);
-    match e {
-        E::A(x @ ..) => {  //~ ERROR `x @` is not allowed in a tuple
-            x //~ ERROR cannot find value `x` in this scope
-        }
-    };
-}
diff --git a/src/test/ui/issues/issue-74539.stderr b/src/test/ui/issues/issue-74539.stderr
deleted file mode 100644
index 94526dcd7cb..00000000000
--- a/src/test/ui/issues/issue-74539.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-74539.rs:9:13
-   |
-LL |             x
-   |             ^ help: a local variable with a similar name exists: `e`
-
-error: `x @` is not allowed in a tuple struct
-  --> $DIR/issue-74539.rs:8:14
-   |
-LL |         E::A(x @ ..) => {
-   |              ^^^^^^ this is only allowed in slice patterns
-   |
-   = help: remove this and bind each tuple field independently
-help: if you don't need to use the contents of x, discard the tuple's remaining fields
-   |
-LL |         E::A(..) => {
-   |              ^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issues/issue-75704.rs b/src/test/ui/issues/issue-75704.rs
new file mode 100644
index 00000000000..aed7ddbcb8c
--- /dev/null
+++ b/src/test/ui/issues/issue-75704.rs
@@ -0,0 +1,7 @@
+// Caused an infinite loop during SimlifyCfg MIR transform previously.
+//
+// build-pass
+
+fn main() {
+    loop { continue; }
+}
diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs
new file mode 100644
index 00000000000..8064c3a88d1
--- /dev/null
+++ b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs
@@ -0,0 +1,26 @@
+#![feature(generator_trait)]
+#![feature(generators)]
+#![deny(unused_braces, unused_parens)]
+
+use std::ops::Generator;
+use std::pin::Pin;
+
+fn main() {
+    let mut x = |_| {
+        while let Some(_) = (yield) {}
+        while let Some(_) = {yield} {}
+
+        // Only warn these cases
+        while let Some(_) = ({yield}) {} //~ ERROR: unnecessary parentheses
+        while let Some(_) = ((yield)) {} //~ ERROR: unnecessary parentheses
+        {{yield}}; //~ ERROR: unnecessary braces
+        {( yield )}; //~ ERROR: unnecessary parentheses
+        while let Some(_) = {(yield)} {} //~ ERROR: unnecessary parentheses
+        while let Some(_) = {{yield}} {} //~ ERROR: unnecessary braces
+
+        // FIXME: It'd be great if we could also warn them.
+        ((yield));
+        ({ yield });
+    };
+    let _ = Pin::new(&mut x).resume(Some(5));
+}
diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr
new file mode 100644
index 00000000000..3f6260dc6e1
--- /dev/null
+++ b/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr
@@ -0,0 +1,50 @@
+error: unnecessary parentheses around `let` scrutinee expression
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:14:29
+   |
+LL |         while let Some(_) = ({yield}) {}
+   |                             ^^^^^^^^^ help: remove these parentheses
+   |
+note: the lint level is defined here
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:24
+   |
+LL | #![deny(unused_braces, unused_parens)]
+   |                        ^^^^^^^^^^^^^
+
+error: unnecessary parentheses around `let` scrutinee expression
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:15:29
+   |
+LL |         while let Some(_) = ((yield)) {}
+   |                             ^^^^^^^^^ help: remove these parentheses
+
+error: unnecessary braces around block return value
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:16:10
+   |
+LL |         {{yield}};
+   |          ^^^^^^^ help: remove these braces
+   |
+note: the lint level is defined here
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:9
+   |
+LL | #![deny(unused_braces, unused_parens)]
+   |         ^^^^^^^^^^^^^
+
+error: unnecessary parentheses around block return value
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:17:10
+   |
+LL |         {( yield )};
+   |          ^^^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around block return value
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:18:30
+   |
+LL |         while let Some(_) = {(yield)} {}
+   |                              ^^^^^^^ help: remove these parentheses
+
+error: unnecessary braces around block return value
+  --> $DIR/issue-74883-unused-paren-baren-yield.rs:19:30
+   |
+LL |         while let Some(_) = {{yield}} {}
+   |                              ^^^^^^^ help: remove these braces
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs b/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs
index 4f90bd98c63..034499145b7 100644
--- a/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs
+++ b/src/test/ui/lint/lint-nonstandard-style-unicode-1.rs
@@ -23,7 +23,7 @@ struct _ヒb;
 struct __χa;
 //~^ ERROR type `__χa` should have an upper camel case name
 
-// Besides this, we cannot have two continous underscores in the middle.
+// Besides this, we cannot have two continuous underscores in the middle.
 
 struct 对__否;
 //~^ ERROR type `对__否` should have an upper camel case name
diff --git a/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs b/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs
index 813e0ea5c57..0b52a5fde35 100644
--- a/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs
+++ b/src/test/ui/lint/lint-nonstandard-style-unicode-2.rs
@@ -18,7 +18,7 @@ fn 编程() {}
 fn Ц() {}
 //~^ ERROR function `Ц` should have a snake case name
 
-// besides this, you cannot use continous underscores in the middle
+// besides this, you cannot use continuous underscores in the middle
 
 fn 分__隔() {}
 //~^ ERROR function `分__隔` should have a snake case name
diff --git a/src/test/ui/lint/lint-output-format-2.rs b/src/test/ui/lint/lint-output-format-2.rs
index 521472d99b1..985166e095d 100644
--- a/src/test/ui/lint/lint-output-format-2.rs
+++ b/src/test/ui/lint/lint-output-format-2.rs
@@ -5,11 +5,11 @@
 
 extern crate lint_output_format;
 use lint_output_format::{foo, bar};
-//~^ WARNING use of deprecated item 'lint_output_format::foo': text
+//~^ WARNING use of deprecated function `lint_output_format::foo`: text
 
 
 fn main() {
     let _x = foo();
-    //~^ WARNING use of deprecated item 'lint_output_format::foo': text
+    //~^ WARNING use of deprecated function `lint_output_format::foo`: text
     let _y = bar();
 }
diff --git a/src/test/ui/lint/lint-output-format-2.stderr b/src/test/ui/lint/lint-output-format-2.stderr
index a95fd69fb01..a36dbd61fdc 100644
--- a/src/test/ui/lint/lint-output-format-2.stderr
+++ b/src/test/ui/lint/lint-output-format-2.stderr
@@ -1,4 +1,4 @@
-warning: use of deprecated item 'lint_output_format::foo': text
+warning: use of deprecated function `lint_output_format::foo`: text
   --> $DIR/lint-output-format-2.rs:7:26
    |
 LL | use lint_output_format::{foo, bar};
@@ -6,7 +6,7 @@ LL | use lint_output_format::{foo, bar};
    |
    = note: `#[warn(deprecated)]` on by default
 
-warning: use of deprecated item 'lint_output_format::foo': text
+warning: use of deprecated function `lint_output_format::foo`: text
   --> $DIR/lint-output-format-2.rs:12:14
    |
 LL |     let _x = foo();
diff --git a/src/test/ui/lint/lint-stability-deprecated.rs b/src/test/ui/lint/lint-stability-deprecated.rs
index 4b407a29f64..a6fde11495c 100644
--- a/src/test/ui/lint/lint-stability-deprecated.rs
+++ b/src/test/ui/lint/lint-stability-deprecated.rs
@@ -22,41 +22,41 @@ mod cross_crate {
         type Foo = MethodTester;
         let foo = MethodTester;
 
-        deprecated(); //~ WARN use of deprecated item 'lint_stability::deprecated'
-        foo.method_deprecated(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated'
-        Foo::method_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated'
-        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated'
-        foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-
-        deprecated_text(); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text
-        foo.method_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text
-        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text
-        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text
-        foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-
-        deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable'
-        foo.method_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable'
-        Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable'
-        <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable'
-        foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-
-        deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable_text': text
-        foo.method_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
-        Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
-        <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
-        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
-        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
-        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
-        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+        deprecated(); //~ WARN use of deprecated function `lint_stability::deprecated`
+        foo.method_deprecated(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+
+        deprecated_text(); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text
+        foo.method_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+
+        deprecated_unstable(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable`
+        foo.method_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
+        Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
+        <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`
+        foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+
+        deprecated_unstable_text(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text
+        foo.method_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+        Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+        <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
+        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
 
         unstable();
         foo.method_unstable();
@@ -96,38 +96,38 @@ mod cross_crate {
 
         struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
         struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
-        //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text
-        //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text
+        //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
+        //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
         type A = dyn TraitWithAssociatedTypes<
             TypeUnstable = u8,
             TypeDeprecated = u16,
-            //~^ WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated'
-            //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated'
-            //~| WARN use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated'
+            //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
+            //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
+            //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
         >;
 
-        let _ = DeprecatedStruct { //~ WARN use of deprecated item 'lint_stability::DeprecatedStruct'
-            i: 0 //~ WARN use of deprecated item 'lint_stability::DeprecatedStruct::i'
+        let _ = DeprecatedStruct { //~ WARN use of deprecated struct `lint_stability::DeprecatedStruct`
+            i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedStruct::i`
         };
         let _ = DeprecatedUnstableStruct {
-            //~^ WARN use of deprecated item 'lint_stability::DeprecatedUnstableStruct'
-            i: 0 //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i'
+            //~^ WARN use of deprecated struct `lint_stability::DeprecatedUnstableStruct`
+            i: 0 //~ WARN use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`
         };
         let _ = UnstableStruct { i: 0 };
         let _ = StableStruct { i: 0 };
 
-        let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item 'lint_stability::DeprecatedUnitStruct'
-        let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct'
+        let _ = DeprecatedUnitStruct; //~ WARN use of deprecated struct `lint_stability::DeprecatedUnitStruct`
+        let _ = DeprecatedUnstableUnitStruct; //~ WARN use of deprecated struct `lint_stability::DeprecatedUnstableUnitStruct`
         let _ = UnstableUnitStruct;
         let _ = StableUnitStruct;
 
-        let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item 'lint_stability::Enum::DeprecatedVariant'
-        let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant'
+        let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated variant `lint_stability::Enum::DeprecatedVariant`
+        let _ = Enum::DeprecatedUnstableVariant; //~ WARN use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant`
         let _ = Enum::UnstableVariant;
         let _ = Enum::StableVariant;
 
-        let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item 'lint_stability::DeprecatedTupleStruct'
-        let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct'
+        let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated struct `lint_stability::DeprecatedTupleStruct`
+        let _ = DeprecatedUnstableTupleStruct (1); //~ WARN use of deprecated struct `lint_stability::DeprecatedUnstableTupleStruct`
         let _ = UnstableTupleStruct (1);
         let _ = StableTupleStruct (1);
 
@@ -136,28 +136,28 @@ mod cross_crate {
         // Eventually, we will want to lint the contents of the
         // macro in the module *defining* it. Also, stability levels
         // on macros themselves are not yet linted.
-        macro_test_arg!(deprecated_text()); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text
-        macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated item 'lint_stability::deprecated_unstable_text': text
-        macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated item 'lint_stability::deprecated_text': text
+        macro_test_arg!(deprecated_text()); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text
+        macro_test_arg!(deprecated_unstable_text()); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text
+        macro_test_arg!(macro_test_arg!(deprecated_text())); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
-        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
-        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
-        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+        foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
+        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
         foo.trait_unstable();
         Trait::trait_unstable(&foo);
         <Foo>::trait_unstable(&foo);
@@ -173,10 +173,10 @@ mod cross_crate {
     }
 
     fn test_method_object(foo: &dyn Trait) {
-        foo.trait_deprecated(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
-        foo.trait_deprecated_unstable(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable'
-        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+        foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
+        foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`
+        foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
         foo.trait_unstable();
         foo.trait_unstable_text();
         foo.trait_stable();
@@ -185,9 +185,9 @@ mod cross_crate {
     struct S;
 
     impl UnstableTrait for S { }
-    impl DeprecatedTrait for S {} //~ WARN use of deprecated item 'lint_stability::DeprecatedTrait': text
+    impl DeprecatedTrait for S {} //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text
     trait LocalTrait : UnstableTrait { }
-    trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated item 'lint_stability::DeprecatedTrait': text
+    trait LocalTrait2 : DeprecatedTrait { } //~ WARN use of deprecated trait `lint_stability::DeprecatedTrait`: text
 
     impl Trait for S {
         fn trait_stable(&self) {}
@@ -206,7 +206,7 @@ mod inheritance {
         stable_mod::unstable();
         stable_mod::stable();
 
-        unstable_mod::deprecated(); //~ WARN use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text
+        unstable_mod::deprecated(); //~ WARN use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text
         unstable_mod::unstable();
 
         let _ = Unstable::UnstableVariant;
@@ -328,23 +328,23 @@ mod this_crate {
         type Foo = MethodTester;
         let foo = MethodTester;
 
-        deprecated(); //~ WARN use of deprecated item 'this_crate::deprecated'
-        foo.method_deprecated(); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated'
-        Foo::method_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated'
-        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated'
-        foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-
-        deprecated_text(); //~ WARN use of deprecated item 'this_crate::deprecated_text': text
-        foo.method_deprecated_text(); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
-        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
-        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
-        foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+        deprecated(); //~ WARN use of deprecated function `this_crate::deprecated`
+        foo.method_deprecated(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+        Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+        <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated`
+        foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+
+        deprecated_text(); //~ WARN use of deprecated function `this_crate::deprecated_text`: text
+        foo.method_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+        Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+        <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
+        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
 
         unstable();
         foo.method_unstable();
@@ -383,34 +383,34 @@ mod this_crate {
         <Foo as Trait>::trait_stable_text(&foo);
 
         let _ = DeprecatedStruct {
-            //~^ WARN use of deprecated item 'this_crate::DeprecatedStruct'
-            i: 0 //~ WARN use of deprecated item 'this_crate::DeprecatedStruct::i'
+            //~^ WARN use of deprecated struct `this_crate::DeprecatedStruct`
+            i: 0 //~ WARN use of deprecated field `this_crate::DeprecatedStruct::i`
         };
         let _ = UnstableStruct { i: 0 };
         let _ = StableStruct { i: 0 };
 
-        let _ = DeprecatedUnitStruct; //~ WARN use of deprecated item 'this_crate::DeprecatedUnitStruct'
+        let _ = DeprecatedUnitStruct; //~ WARN use of deprecated unit struct `this_crate::DeprecatedUnitStruct`
         let _ = UnstableUnitStruct;
         let _ = StableUnitStruct;
 
-        let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated item 'this_crate::Enum::DeprecatedVariant'
+        let _ = Enum::DeprecatedVariant; //~ WARN use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`
         let _ = Enum::UnstableVariant;
         let _ = Enum::StableVariant;
 
-        let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated item 'this_crate::DeprecatedTupleStruct'
+        let _ = DeprecatedTupleStruct (1); //~ WARN use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`
         let _ = UnstableTupleStruct (1);
         let _ = StableTupleStruct (1);
     }
 
     fn test_method_param<Foo: Trait>(foo: Foo) {
-        foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        Trait::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
-        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+        foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
         foo.trait_unstable();
         Trait::trait_unstable(&foo);
         <Foo>::trait_unstable(&foo);
@@ -426,8 +426,8 @@ mod this_crate {
     }
 
     fn test_method_object(foo: &dyn Trait) {
-        foo.trait_deprecated(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated'
-        foo.trait_deprecated_text(); //~ WARN use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+        foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated`
+        foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
         foo.trait_unstable();
         foo.trait_unstable_text();
         foo.trait_stable();
@@ -437,7 +437,7 @@ mod this_crate {
     #[rustc_deprecated(since = "1.0.0", reason = "text")]
     fn test_fn_body() {
         fn fn_in_body() {}
-        fn_in_body(); //~ WARN use of deprecated item 'this_crate::test_fn_body::fn_in_body': text
+        fn_in_body(); //~ WARN use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
     }
 
     impl MethodTester {
@@ -445,7 +445,7 @@ mod this_crate {
         #[rustc_deprecated(since = "1.0.0", reason = "text")]
         fn test_method_body(&self) {
             fn fn_in_body() {}
-            fn_in_body(); //~ WARN use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text
+            fn_in_body(); //~ WARN use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text
         }
     }
 
@@ -457,9 +457,9 @@ mod this_crate {
 
     struct S;
 
-    impl DeprecatedTrait for S { } //~ WARN use of deprecated item 'this_crate::DeprecatedTrait'
+    impl DeprecatedTrait for S { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait`
 
-    trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated item 'this_crate::DeprecatedTrait'
+    trait LocalTrait : DeprecatedTrait { } //~ WARN use of deprecated trait `this_crate::DeprecatedTrait`
 }
 
 fn main() {}
diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr
index 801e04a7f4f..d8dd83b0d06 100644
--- a/src/test/ui/lint/lint-stability-deprecated.stderr
+++ b/src/test/ui/lint/lint-stability-deprecated.stderr
@@ -1,4 +1,4 @@
-warning: use of deprecated item 'lint_stability::deprecated': text
+warning: use of deprecated function `lint_stability::deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:25:9
    |
 LL |         deprecated();
@@ -10,643 +10,643 @@ note: the lint level is defined here
 LL | #![warn(deprecated)]
    |         ^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:30:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:32:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::deprecated_text': text
+warning: use of deprecated function `lint_stability::deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:34:9
    |
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:39:9
    |
-LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:41:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::deprecated_unstable': text
+warning: use of deprecated function `lint_stability::deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:43:9
    |
 LL |         deprecated_unstable();
    |         ^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:48:9
    |
-LL |         Trait::trait_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:50:9
    |
-LL |         <Foo as Trait>::trait_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text
+warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:52:9
    |
 LL |         deprecated_unstable_text();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:57:9
    |
 LL | ...   Trait::trait_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:59:9
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedStruct': text
+warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text
   --> $DIR/lint-stability-deprecated.rs:109:17
    |
 LL |         let _ = DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct': text
+warning: use of deprecated struct `lint_stability::DeprecatedUnstableStruct`: text
   --> $DIR/lint-stability-deprecated.rs:112:17
    |
 LL |         let _ = DeprecatedUnstableStruct {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedUnitStruct': text
+warning: use of deprecated struct `lint_stability::DeprecatedUnitStruct`: text
   --> $DIR/lint-stability-deprecated.rs:119:17
    |
 LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedUnstableUnitStruct': text
+warning: use of deprecated struct `lint_stability::DeprecatedUnstableUnitStruct`: text
   --> $DIR/lint-stability-deprecated.rs:120:17
    |
 LL |         let _ = DeprecatedUnstableUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Enum::DeprecatedVariant': text
+warning: use of deprecated variant `lint_stability::Enum::DeprecatedVariant`: text
   --> $DIR/lint-stability-deprecated.rs:124:17
    |
 LL |         let _ = Enum::DeprecatedVariant;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Enum::DeprecatedUnstableVariant': text
+warning: use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant`: text
   --> $DIR/lint-stability-deprecated.rs:125:17
    |
 LL |         let _ = Enum::DeprecatedUnstableVariant;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedTupleStruct': text
+warning: use of deprecated struct `lint_stability::DeprecatedTupleStruct`: text
   --> $DIR/lint-stability-deprecated.rs:129:17
    |
 LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedUnstableTupleStruct': text
+warning: use of deprecated struct `lint_stability::DeprecatedUnstableTupleStruct`: text
   --> $DIR/lint-stability-deprecated.rs:130:17
    |
 LL |         let _ = DeprecatedUnstableTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::deprecated_text': text
+warning: use of deprecated function `lint_stability::deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:139:25
    |
 LL |         macro_test_arg!(deprecated_text());
    |                         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::deprecated_unstable_text': text
+warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:140:25
    |
 LL |         macro_test_arg!(deprecated_unstable_text());
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::deprecated_text': text
+warning: use of deprecated function `lint_stability::deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:141:41
    |
 LL |         macro_test_arg!(macro_test_arg!(deprecated_text()));
    |                                         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:146:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:148:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:150:9
    |
-LL |         Trait::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:152:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:154:9
    |
-LL |         Trait::trait_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:156:9
    |
-LL |         <Foo as Trait>::trait_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:158:9
    |
 LL | ...   Trait::trait_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:160:9
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedTrait': text
+warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
   --> $DIR/lint-stability-deprecated.rs:188:10
    |
 LL |     impl DeprecatedTrait for S {}
    |          ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedTrait': text
+warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
   --> $DIR/lint-stability-deprecated.rs:190:25
    |
 LL |     trait LocalTrait2 : DeprecatedTrait { }
    |                         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'inheritance::inherited_stability::unstable_mod::deprecated': text
+warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:209:9
    |
 LL |         unstable_mod::deprecated();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::deprecated': text
+warning: use of deprecated function `this_crate::deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:331:9
    |
 LL |         deprecated();
    |         ^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:336:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:338:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::deprecated_text': text
+warning: use of deprecated function `this_crate::deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:340:9
    |
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:345:9
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:347:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::DeprecatedStruct': text
+warning: use of deprecated struct `this_crate::DeprecatedStruct`: text
   --> $DIR/lint-stability-deprecated.rs:385:17
    |
 LL |         let _ = DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::DeprecatedUnitStruct': text
+warning: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text
   --> $DIR/lint-stability-deprecated.rs:392:17
    |
 LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Enum::DeprecatedVariant': text
+warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
   --> $DIR/lint-stability-deprecated.rs:396:17
    |
 LL |         let _ = Enum::DeprecatedVariant;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::DeprecatedTupleStruct': text
+warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
   --> $DIR/lint-stability-deprecated.rs:400:17
    |
 LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:407:9
    |
 LL |         Trait::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:409:9
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:411:9
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:413:9
    |
-LL |         <Foo as Trait>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::test_fn_body::fn_in_body': text
+warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
   --> $DIR/lint-stability-deprecated.rs:440:9
    |
 LL |         fn_in_body();
    |         ^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::DeprecatedTrait': text
+warning: use of deprecated trait `this_crate::DeprecatedTrait`: text
   --> $DIR/lint-stability-deprecated.rs:460:10
    |
 LL |     impl DeprecatedTrait for S { }
    |          ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::DeprecatedTrait': text
+warning: use of deprecated trait `this_crate::DeprecatedTrait`: text
   --> $DIR/lint-stability-deprecated.rs:462:24
    |
 LL |     trait LocalTrait : DeprecatedTrait { }
    |                        ^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::MethodTester::test_method_body::fn_in_body': text
+warning: use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text
   --> $DIR/lint-stability-deprecated.rs:448:13
    |
 LL |             fn_in_body();
    |             ^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
   --> $DIR/lint-stability-deprecated.rs:98:48
    |
 LL |         struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
    |                                                ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
   --> $DIR/lint-stability-deprecated.rs:103:13
    |
 LL |             TypeDeprecated = u16,
    |             ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:26:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:27:9
    |
 LL |         Foo::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:28:9
    |
 LL |         <Foo>::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:29:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:31:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:35:13
    |
-LL |         foo.method_deprecated_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.method_deprecated_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:36:9
    |
-LL |         Foo::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Foo::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:37:9
    |
-LL |         <Foo>::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:38:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:40:9
    |
-LL |         <Foo>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:44:13
    |
-LL |         foo.method_deprecated_unstable();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.method_deprecated_unstable();
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:45:9
    |
-LL |         Foo::method_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Foo::method_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:46:9
    |
-LL |         <Foo>::method_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::method_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:47:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:49:9
    |
-LL |         <Foo>::trait_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:53:13
    |
 LL | ...   foo.method_deprecated_unstable_text();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:54:9
    |
 LL | ...   Foo::method_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:55:9
    |
 LL | ...   <Foo>::method_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:56:13
    |
-LL |         foo.trait_deprecated_unstable_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.trait_deprecated_unstable_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:58:9
    |
 LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedStruct::i': text
+warning: use of deprecated field `lint_stability::DeprecatedStruct::i`: text
   --> $DIR/lint-stability-deprecated.rs:110:13
    |
 LL |             i: 0
    |             ^^^^
 
-warning: use of deprecated item 'lint_stability::DeprecatedUnstableStruct::i': text
+warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`: text
   --> $DIR/lint-stability-deprecated.rs:114:13
    |
 LL |             i: 0
    |             ^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:145:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:147:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:149:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:151:9
    |
-LL |         <Foo>::trait_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:153:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:155:9
    |
-LL |         <Foo>::trait_deprecated_unstable(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_unstable(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:157:13
    |
-LL |         foo.trait_deprecated_unstable_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.trait_deprecated_unstable_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:159:9
    |
 LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:176:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:177:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
   --> $DIR/lint-stability-deprecated.rs:178:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
+warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
   --> $DIR/lint-stability-deprecated.rs:179:13
    |
-LL |         foo.trait_deprecated_unstable_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.trait_deprecated_unstable_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:332:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:333:9
    |
 LL |         Foo::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::MethodTester::method_deprecated': text
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:334:9
    |
 LL |         <Foo>::method_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:335:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:337:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:341:13
    |
-LL |         foo.method_deprecated_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.method_deprecated_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:342:9
    |
-LL |         Foo::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Foo::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::MethodTester::method_deprecated_text': text
+warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:343:9
    |
-LL |         <Foo>::method_deprecated_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::method_deprecated_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:344:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:346:9
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::DeprecatedStruct::i': text
+warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text
   --> $DIR/lint-stability-deprecated.rs:387:13
    |
 LL |             i: 0
    |             ^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:406:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:408:9
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:410:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:412:9
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
   --> $DIR/lint-stability-deprecated.rs:429:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'this_crate::Trait::trait_deprecated_text': text
+warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
   --> $DIR/lint-stability-deprecated.rs:430:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
   --> $DIR/lint-stability-deprecated.rs:98:48
    |
 LL |         struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
    |                                                ^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
   --> $DIR/lint-stability-deprecated.rs:103:13
    |
 LL |             TypeDeprecated = u16,
    |             ^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated item 'lint_stability::TraitWithAssociatedTypes::TypeDeprecated': text
+warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
   --> $DIR/lint-stability-deprecated.rs:103:13
    |
 LL |             TypeDeprecated = u16,
diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.rs b/src/test/ui/lint/lint-stability-fields-deprecated.rs
index 50e3970c7f0..14c6383806f 100644
--- a/src/test/ui/lint/lint-stability-fields-deprecated.rs
+++ b/src/test/ui/lint/lint-stability-fields-deprecated.rs
@@ -16,19 +16,19 @@ mod cross_crate {
             inherit: 1,
             override1: 2,
             override2: 3,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         };
 
         let _ = x.inherit;
         let _ = x.override1;
         let _ = x.override2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Stable {
             inherit: _,
             override1: _,
             override2: _
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         } = x;
         // all fine
         let Stable { .. } = x;
@@ -38,12 +38,12 @@ mod cross_crate {
         let _ = x.0;
         let _ = x.1;
         let _ = x.2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Stable2(_,
                    _,
                    _)
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             = x;
         // all fine
         let Stable2(..) = x;
@@ -53,19 +53,19 @@ mod cross_crate {
             inherit: 1,
             override1: 2,
             override2: 3,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         };
 
         let _ = x.inherit;
         let _ = x.override1;
         let _ = x.override2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Unstable {
             inherit: _,
             override1: _,
             override2: _
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         } = x;
 
         let Unstable
@@ -78,13 +78,13 @@ mod cross_crate {
         let _ = x.0;
         let _ = x.1;
         let _ = x.2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Unstable2
             (_,
              _,
              _)
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             = x;
         let Unstable2
             // the patterns are all fine:
@@ -92,58 +92,58 @@ mod cross_crate {
 
 
         let x = Deprecated {
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated struct
             inherit: 1,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override1: 2,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override2: 3,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         };
 
         let _ = x.inherit;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.override1;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.override2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Deprecated {
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated struct
             inherit: _,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override1: _,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override2: _
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         } = x;
 
         let Deprecated
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated struct
             // the patterns are all fine:
             { .. } = x;
 
         let x = Deprecated2(1, 2, 3);
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated struct
 
         let _ = x.0;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.1;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Deprecated2
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated struct
             (_,
-             //~^ ERROR use of deprecated item
+             //~^ ERROR use of deprecated field
              _,
-             //~^ ERROR use of deprecated item
+             //~^ ERROR use of deprecated field
              _)
-             //~^ ERROR use of deprecated item
+             //~^ ERROR use of deprecated field
             = x;
         let Deprecated2
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated struct
             // the patterns are all fine:
             (..) = x;
     }
@@ -203,19 +203,19 @@ mod this_crate {
             inherit: 1,
             override1: 2,
             override2: 3,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         };
 
         let _ = x.inherit;
         let _ = x.override1;
         let _ = x.override2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Stable {
             inherit: _,
             override1: _,
             override2: _
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         } = x;
         // all fine
         let Stable { .. } = x;
@@ -225,12 +225,12 @@ mod this_crate {
         let _ = x.0;
         let _ = x.1;
         let _ = x.2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Stable2(_,
                    _,
                    _)
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             = x;
         // all fine
         let Stable2(..) = x;
@@ -240,19 +240,19 @@ mod this_crate {
             inherit: 1,
             override1: 2,
             override2: 3,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         };
 
         let _ = x.inherit;
         let _ = x.override1;
         let _ = x.override2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Unstable {
             inherit: _,
             override1: _,
             override2: _
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         } = x;
 
         let Unstable
@@ -265,13 +265,13 @@ mod this_crate {
         let _ = x.0;
         let _ = x.1;
         let _ = x.2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Unstable2
             (_,
              _,
              _)
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             = x;
         let Unstable2
             // the patterns are all fine:
@@ -279,58 +279,58 @@ mod this_crate {
 
 
         let x = Deprecated {
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated struct
             inherit: 1,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override1: 2,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override2: 3,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         };
 
         let _ = x.inherit;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.override1;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.override2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Deprecated {
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated struct
             inherit: _,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override1: _,
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             override2: _
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
         } = x;
 
         let Deprecated
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated struct
             // the patterns are all fine:
             { .. } = x;
 
         let x = Deprecated2(1, 2, 3);
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated tuple struct
 
         let _ = x.0;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.1;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
         let _ = x.2;
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated field
 
         let Deprecated2
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated tuple struct
             (_,
-             //~^ ERROR use of deprecated item
+             //~^ ERROR use of deprecated field
              _,
-             //~^ ERROR use of deprecated item
+             //~^ ERROR use of deprecated field
              _)
-            //~^ ERROR use of deprecated item
+            //~^ ERROR use of deprecated field
             = x;
         let Deprecated2
-        //~^ ERROR use of deprecated item
+        //~^ ERROR use of deprecated tuple struct
             // the patterns are all fine:
             (..) = x;
     }
diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.stderr b/src/test/ui/lint/lint-stability-fields-deprecated.stderr
index 5210fb690e9..ec786786023 100644
--- a/src/test/ui/lint/lint-stability-fields-deprecated.stderr
+++ b/src/test/ui/lint/lint-stability-fields-deprecated.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
   --> $DIR/lint-stability-fields-deprecated.rs:94:17
    |
 LL |         let x = Deprecated {
@@ -10,367 +10,367 @@ note: the lint level is defined here
 LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
   --> $DIR/lint-stability-fields-deprecated.rs:111:13
    |
 LL |         let Deprecated {
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated': text
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
   --> $DIR/lint-stability-fields-deprecated.rs:121:13
    |
 LL |         let Deprecated
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:126:17
    |
 LL |         let x = Deprecated2(1, 2, 3);
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:136:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2': text
+error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:145:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated': text
+error: use of deprecated struct `this_crate::Deprecated`: text
   --> $DIR/lint-stability-fields-deprecated.rs:281:17
    |
 LL |         let x = Deprecated {
    |                 ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated': text
+error: use of deprecated struct `this_crate::Deprecated`: text
   --> $DIR/lint-stability-fields-deprecated.rs:298:13
    |
 LL |         let Deprecated {
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated': text
+error: use of deprecated struct `this_crate::Deprecated`: text
   --> $DIR/lint-stability-fields-deprecated.rs:308:13
    |
 LL |         let Deprecated
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated2': text
+error: use of deprecated tuple struct `this_crate::Deprecated2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:313:17
    |
 LL |         let x = Deprecated2(1, 2, 3);
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated2': text
+error: use of deprecated tuple struct `this_crate::Deprecated2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:323:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated2': text
+error: use of deprecated tuple struct `this_crate::Deprecated2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:332:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:18:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:24:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Stable::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:30:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Stable2::2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:40:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Stable2::2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:45:20
    |
 LL |                    _)
    |                    ^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:55:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:61:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:67:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable2::2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:80:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Unstable2::2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:86:14
    |
 LL |              _)
    |              ^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
   --> $DIR/lint-stability-fields-deprecated.rs:96:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:98:13
    |
 LL |             override1: 2,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:100:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
   --> $DIR/lint-stability-fields-deprecated.rs:104:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:106:17
    |
 LL |         let _ = x.override1;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:108:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::inherit': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
   --> $DIR/lint-stability-fields-deprecated.rs:113:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override1': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:115:13
    |
 LL |             override1: _,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated::override2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:117:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::0': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text
   --> $DIR/lint-stability-fields-deprecated.rs:129:17
    |
 LL |         let _ = x.0;
    |                 ^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::1': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:131:17
    |
 LL |         let _ = x.1;
    |                 ^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:133:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::0': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text
   --> $DIR/lint-stability-fields-deprecated.rs:138:14
    |
 LL |             (_,
    |              ^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::1': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:140:14
    |
 LL |              _,
    |              ^
 
-error: use of deprecated item 'cross_crate::lint_stability_fields::Deprecated2::2': text
+error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:142:14
    |
 LL |              _)
    |              ^
 
-error: use of deprecated item 'this_crate::Stable::override2': text
+error: use of deprecated field `this_crate::Stable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:205:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Stable::override2': text
+error: use of deprecated field `this_crate::Stable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:211:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Stable::override2': text
+error: use of deprecated field `this_crate::Stable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:217:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Stable2::2': text
+error: use of deprecated field `this_crate::Stable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:227:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'this_crate::Stable2::2': text
+error: use of deprecated field `this_crate::Stable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:232:20
    |
 LL |                    _)
    |                    ^
 
-error: use of deprecated item 'this_crate::Unstable::override2': text
+error: use of deprecated field `this_crate::Unstable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:242:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Unstable::override2': text
+error: use of deprecated field `this_crate::Unstable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:248:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Unstable::override2': text
+error: use of deprecated field `this_crate::Unstable::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:254:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Unstable2::2': text
+error: use of deprecated field `this_crate::Unstable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:267:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'this_crate::Unstable2::2': text
+error: use of deprecated field `this_crate::Unstable2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:273:14
    |
 LL |              _)
    |              ^
 
-error: use of deprecated item 'this_crate::Deprecated::inherit': text
+error: use of deprecated field `this_crate::Deprecated::inherit`: text
   --> $DIR/lint-stability-fields-deprecated.rs:283:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::override1': text
+error: use of deprecated field `this_crate::Deprecated::override1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:285:13
    |
 LL |             override1: 2,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::override2': text
+error: use of deprecated field `this_crate::Deprecated::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:287:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::inherit': text
+error: use of deprecated field `this_crate::Deprecated::inherit`: text
   --> $DIR/lint-stability-fields-deprecated.rs:291:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::override1': text
+error: use of deprecated field `this_crate::Deprecated::override1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:293:17
    |
 LL |         let _ = x.override1;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::override2': text
+error: use of deprecated field `this_crate::Deprecated::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:295:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::inherit': text
+error: use of deprecated field `this_crate::Deprecated::inherit`: text
   --> $DIR/lint-stability-fields-deprecated.rs:300:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::override1': text
+error: use of deprecated field `this_crate::Deprecated::override1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:302:13
    |
 LL |             override1: _,
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated::override2': text
+error: use of deprecated field `this_crate::Deprecated::override2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:304:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
-error: use of deprecated item 'this_crate::Deprecated2::0': text
+error: use of deprecated field `this_crate::Deprecated2::0`: text
   --> $DIR/lint-stability-fields-deprecated.rs:316:17
    |
 LL |         let _ = x.0;
    |                 ^^^
 
-error: use of deprecated item 'this_crate::Deprecated2::1': text
+error: use of deprecated field `this_crate::Deprecated2::1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:318:17
    |
 LL |         let _ = x.1;
    |                 ^^^
 
-error: use of deprecated item 'this_crate::Deprecated2::2': text
+error: use of deprecated field `this_crate::Deprecated2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:320:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
-error: use of deprecated item 'this_crate::Deprecated2::0': text
+error: use of deprecated field `this_crate::Deprecated2::0`: text
   --> $DIR/lint-stability-fields-deprecated.rs:325:14
    |
 LL |             (_,
    |              ^
 
-error: use of deprecated item 'this_crate::Deprecated2::1': text
+error: use of deprecated field `this_crate::Deprecated2::1`: text
   --> $DIR/lint-stability-fields-deprecated.rs:327:14
    |
 LL |              _,
    |              ^
 
-error: use of deprecated item 'this_crate::Deprecated2::2': text
+error: use of deprecated field `this_crate::Deprecated2::2`: text
   --> $DIR/lint-stability-fields-deprecated.rs:329:14
    |
 LL |              _)
diff --git a/src/test/ui/lint/lint-stability2.rs b/src/test/ui/lint/lint-stability2.rs
index 9710d0826c7..9ae23dac61b 100644
--- a/src/test/ui/lint/lint-stability2.rs
+++ b/src/test/ui/lint/lint-stability2.rs
@@ -1,5 +1,5 @@
 // aux-build:lint_stability.rs
-// error-pattern: use of deprecated item
+// error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 
diff --git a/src/test/ui/lint/lint-stability2.stderr b/src/test/ui/lint/lint-stability2.stderr
index a14bf2ec8ca..036304d25f9 100644
--- a/src/test/ui/lint/lint-stability2.stderr
+++ b/src/test/ui/lint/lint-stability2.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'lint_stability::deprecated': text
+error: use of deprecated function `lint_stability::deprecated`: text
   --> $DIR/lint-stability2.rs:12:5
    |
 LL |     macro_test!();
diff --git a/src/test/ui/lint/lint-stability3.rs b/src/test/ui/lint/lint-stability3.rs
index 3d2cc6890b8..4452846ec0a 100644
--- a/src/test/ui/lint/lint-stability3.rs
+++ b/src/test/ui/lint/lint-stability3.rs
@@ -1,5 +1,5 @@
 // aux-build:lint_stability.rs
-// error-pattern: use of deprecated item
+// error-pattern: use of deprecated function
 
 #![deny(deprecated)]
 #![allow(warnings)]
diff --git a/src/test/ui/lint/lint-stability3.stderr b/src/test/ui/lint/lint-stability3.stderr
index 858ac12612c..b89a7df4938 100644
--- a/src/test/ui/lint/lint-stability3.stderr
+++ b/src/test/ui/lint/lint-stability3.stderr
@@ -1,4 +1,4 @@
-error: use of deprecated item 'lint_stability::deprecated_text': text
+error: use of deprecated function `lint_stability::deprecated_text`: text
   --> $DIR/lint-stability3.rs:13:5
    |
 LL |     macro_test_arg_nested!(deprecated_text);
diff --git a/src/test/ui/lint/unused-braces-while-let-with-mutable-value.rs b/src/test/ui/lint/unused-braces-while-let-with-mutable-value.rs
new file mode 100644
index 00000000000..ac547293c58
--- /dev/null
+++ b/src/test/ui/lint/unused-braces-while-let-with-mutable-value.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![deny(unused_braces)]
+
+fn main() {
+    let mut a = Some(3);
+    // Shouldn't warn below `a`.
+    while let Some(ref mut v) = {a} {
+        a.as_mut().map(|a| std::mem::swap(a, v));
+        break;
+    }
+}
diff --git a/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr b/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr
index 2f3d48bf039..4d8a8edf4c9 100644
--- a/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr
+++ b/src/test/ui/macro_backtrace/main.-Zmacro-backtrace.stderr
@@ -17,20 +17,20 @@ LL | /  macro_rules! pong {
 LL | |      () => { syntax error };
    | |                     ^^^^^ expected one of 8 possible tokens
 LL | |  }
-   | |__- in this expansion of `pong!`
+   | |__- in this expansion of `pong!` (#2)
 ...
 LL |        ping!();
-   |        -------- in this macro invocation
+   |        -------- in this macro invocation (#1)
    | 
   ::: $DIR/auxiliary/ping.rs:5:1
    |
 LL |  / macro_rules! ping {
 LL |  |     () => {
 LL |  |         pong!();
-   |  |         -------- in this macro invocation
+   |  |         -------- in this macro invocation (#2)
 LL |  |     }
 LL |  | }
-   |  |_- in this expansion of `ping!`
+   |  |_- in this expansion of `ping!` (#1)
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `error`
   --> $DIR/main.rs:10:20
diff --git a/src/test/ui/macros/macro-deprecation.rs b/src/test/ui/macros/macro-deprecation.rs
index 9636b48c2da..a7f327cf53b 100644
--- a/src/test/ui/macros/macro-deprecation.rs
+++ b/src/test/ui/macros/macro-deprecation.rs
@@ -8,6 +8,6 @@
 macro_rules! local_deprecated{ () => () }
 
 fn main() {
-    local_deprecated!(); //~ WARN use of deprecated item 'local_deprecated': local deprecation note
-    deprecated_macro!(); //~ WARN use of deprecated item 'deprecated_macro': deprecation note
+    local_deprecated!(); //~ WARN use of deprecated macro `local_deprecated`: local deprecation note
+    deprecated_macro!(); //~ WARN use of deprecated macro `deprecated_macro`: deprecation note
 }
diff --git a/src/test/ui/macros/macro-deprecation.stderr b/src/test/ui/macros/macro-deprecation.stderr
index 0e8ecb58fe5..07849d7ce57 100644
--- a/src/test/ui/macros/macro-deprecation.stderr
+++ b/src/test/ui/macros/macro-deprecation.stderr
@@ -1,4 +1,4 @@
-warning: use of deprecated item 'local_deprecated': local deprecation note
+warning: use of deprecated macro `local_deprecated`: local deprecation note
   --> $DIR/macro-deprecation.rs:11:5
    |
 LL |     local_deprecated!();
@@ -6,7 +6,7 @@ LL |     local_deprecated!();
    |
    = note: `#[warn(deprecated)]` on by default
 
-warning: use of deprecated item 'deprecated_macro': deprecation note
+warning: use of deprecated macro `deprecated_macro`: deprecation note
   --> $DIR/macro-deprecation.rs:12:5
    |
 LL |     deprecated_macro!();
diff --git a/src/test/ui/macros/macro-stability.rs b/src/test/ui/macros/macro-stability.rs
index 755f55c28de..e2eff7c1c2d 100644
--- a/src/test/ui/macros/macro-stability.rs
+++ b/src/test/ui/macros/macro-stability.rs
@@ -22,7 +22,7 @@ fn main() {
     // unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros'
 
     deprecated_macro!();
-    //~^ WARN use of deprecated item 'deprecated_macro': deprecation reason
+    //~^ WARN use of deprecated macro `deprecated_macro`: deprecation reason
     local_deprecated!();
-    //~^ WARN use of deprecated item 'local_deprecated': local deprecation reason
+    //~^ WARN use of deprecated macro `local_deprecated`: local deprecation reason
 }
diff --git a/src/test/ui/macros/macro-stability.stderr b/src/test/ui/macros/macro-stability.stderr
index 9e127a3b855..34b62b4b1c3 100644
--- a/src/test/ui/macros/macro-stability.stderr
+++ b/src/test/ui/macros/macro-stability.stderr
@@ -22,7 +22,7 @@ LL |     unstable_macro!();
    |
    = help: add `#![feature(unstable_macros)]` to the crate attributes to enable
 
-warning: use of deprecated item 'deprecated_macro': deprecation reason
+warning: use of deprecated macro `deprecated_macro`: deprecation reason
   --> $DIR/macro-stability.rs:24:5
    |
 LL |     deprecated_macro!();
@@ -30,7 +30,7 @@ LL |     deprecated_macro!();
    |
    = note: `#[warn(deprecated)]` on by default
 
-warning: use of deprecated item 'local_deprecated': local deprecation reason
+warning: use of deprecated macro `local_deprecated`: local deprecation reason
   --> $DIR/macro-stability.rs:26:5
    |
 LL |     local_deprecated!();
diff --git a/src/test/ui/pattern/issue-74539.rs b/src/test/ui/pattern/issue-74539.rs
new file mode 100644
index 00000000000..0b25f87ec53
--- /dev/null
+++ b/src/test/ui/pattern/issue-74539.rs
@@ -0,0 +1,15 @@
+enum E {
+    A(u8, u8),
+}
+
+fn main() {
+    let e = E::A(2, 3);
+    match e {
+        E::A(x @ ..) => {
+            //~^ ERROR: `x @` is not allowed in a tuple struct
+            //~| ERROR: `..` patterns are not allowed here
+            //~| ERROR: this pattern has 1 field, but the corresponding tuple variant has 2 fields
+            x
+        }
+    };
+}
diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr
new file mode 100644
index 00000000000..cbc90b5397d
--- /dev/null
+++ b/src/test/ui/pattern/issue-74539.stderr
@@ -0,0 +1,32 @@
+error: `x @` is not allowed in a tuple struct
+  --> $DIR/issue-74539.rs:8:14
+   |
+LL |         E::A(x @ ..) => {
+   |              ^^^^^^ this is only allowed in slice patterns
+   |
+   = help: remove this and bind each tuple field independently
+help: if you don't need to use the contents of x, discard the tuple's remaining fields
+   |
+LL |         E::A(..) => {
+   |              ^^
+
+error: `..` patterns are not allowed here
+  --> $DIR/issue-74539.rs:8:18
+   |
+LL |         E::A(x @ ..) => {
+   |                  ^^
+   |
+   = note: only allowed in tuple, tuple struct, and slice patterns
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
+  --> $DIR/issue-74539.rs:8:9
+   |
+LL |     A(u8, u8),
+   |     --------- tuple variant defined here
+...
+LL |         E::A(x @ ..) => {
+   |         ^^^^^^^^^^^^ expected 2 fields, found 1
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0023`.
diff --git a/src/test/ui/pattern/issue-74702.rs b/src/test/ui/pattern/issue-74702.rs
new file mode 100644
index 00000000000..0aeb3b217a2
--- /dev/null
+++ b/src/test/ui/pattern/issue-74702.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let (foo @ ..,) = (0, 0);
+    //~^ ERROR: `foo @` is not allowed in a tuple
+    //~| ERROR: `..` patterns are not allowed here
+    //~| ERROR: mismatched types
+    dbg!(foo);
+}
diff --git a/src/test/ui/pattern/issue-74702.stderr b/src/test/ui/pattern/issue-74702.stderr
new file mode 100644
index 00000000000..aca5c9aed96
--- /dev/null
+++ b/src/test/ui/pattern/issue-74702.stderr
@@ -0,0 +1,34 @@
+error: `foo @` is not allowed in a tuple
+  --> $DIR/issue-74702.rs:2:10
+   |
+LL |     let (foo @ ..,) = (0, 0);
+   |          ^^^^^^^^ this is only allowed in slice patterns
+   |
+   = help: remove this and bind each tuple field independently
+help: if you don't need to use the contents of foo, discard the tuple's remaining fields
+   |
+LL |     let (..,) = (0, 0);
+   |          ^^
+
+error: `..` patterns are not allowed here
+  --> $DIR/issue-74702.rs:2:16
+   |
+LL |     let (foo @ ..,) = (0, 0);
+   |                ^^
+   |
+   = note: only allowed in tuple, tuple struct, and slice patterns
+
+error[E0308]: mismatched types
+  --> $DIR/issue-74702.rs:2:9
+   |
+LL |     let (foo @ ..,) = (0, 0);
+   |         ^^^^^^^^^^^   ------ this expression has type `({integer}, {integer})`
+   |         |
+   |         expected a tuple with 2 elements, found one with 1 element
+   |
+   = note: expected tuple `({integer}, {integer})`
+              found tuple `(_,)`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/pattern/issue-74954.rs b/src/test/ui/pattern/issue-74954.rs
new file mode 100644
index 00000000000..269ec3c7abe
--- /dev/null
+++ b/src/test/ui/pattern/issue-74954.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+fn main() {
+    if let Some([b'@', filename @ ..]) = Some(b"@abc123") {
+        println!("filename {:?}", filename);
+    }
+}
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.rs b/src/test/ui/proc-macro/attributes-on-definitions.rs
index 055781d2c60..c0733c8b416 100644
--- a/src/test/ui/proc-macro/attributes-on-definitions.rs
+++ b/src/test/ui/proc-macro/attributes-on-definitions.rs
@@ -6,7 +6,7 @@
 extern crate attributes_on_definitions;
 
 attributes_on_definitions::with_attrs!();
-//~^ WARN use of deprecated item
+//~^ WARN use of deprecated
 // No errors about the use of unstable and unsafe code inside the macro.
 
 fn main() {}
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.stderr b/src/test/ui/proc-macro/attributes-on-definitions.stderr
index 3e6b8f6a435..c63dd00119a 100644
--- a/src/test/ui/proc-macro/attributes-on-definitions.stderr
+++ b/src/test/ui/proc-macro/attributes-on-definitions.stderr
@@ -1,4 +1,4 @@
-warning: use of deprecated item 'attributes_on_definitions::with_attrs': test
+warning: use of deprecated macro `attributes_on_definitions::with_attrs`: test
   --> $DIR/attributes-on-definitions.rs:8:1
    |
 LL | attributes_on_definitions::with_attrs!();
diff --git a/src/test/ui/proc-macro/auxiliary/raw-ident.rs b/src/test/ui/proc-macro/auxiliary/raw-ident.rs
new file mode 100644
index 00000000000..9daee21aa17
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/raw-ident.rs
@@ -0,0 +1,35 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::{TokenStream, TokenTree, Ident, Punct, Spacing, Span};
+
+#[proc_macro]
+pub fn make_struct(input: TokenStream) -> TokenStream {
+    match input.into_iter().next().unwrap() {
+        TokenTree::Ident(ident) => {
+            vec![
+                TokenTree::Ident(Ident::new("struct", Span::call_site())),
+                TokenTree::Ident(Ident::new_raw(&ident.to_string(), Span::call_site())),
+                TokenTree::Punct(Punct::new(';', Spacing::Alone))
+            ].into_iter().collect()
+        }
+        _ => panic!()
+    }
+}
+
+#[proc_macro]
+pub fn make_bad_struct(input: TokenStream) -> TokenStream {
+    match input.into_iter().next().unwrap() {
+        TokenTree::Ident(ident) => {
+            vec![
+                TokenTree::Ident(Ident::new_raw("struct", Span::call_site())),
+                TokenTree::Ident(Ident::new(&ident.to_string(), Span::call_site())),
+                TokenTree::Punct(Punct::new(';', Spacing::Alone))
+            ].into_iter().collect()
+        }
+        _ => panic!()
+    }
+}
diff --git a/src/test/ui/proc-macro/crt-static.rs b/src/test/ui/proc-macro/crt-static.rs
index 97f6265e308..4f11f81b00b 100644
--- a/src/test/ui/proc-macro/crt-static.rs
+++ b/src/test/ui/proc-macro/crt-static.rs
@@ -1,4 +1,4 @@
-// Test proc-macro crate can be built without addtional RUSTFLAGS
+// Test proc-macro crate can be built without additional RUSTFLAGS
 // on musl target
 // override -Ctarget-feature=-crt-static from compiletest
 // compile-flags: -Ctarget-feature=
diff --git a/src/test/ui/proc-macro/raw-ident.rs b/src/test/ui/proc-macro/raw-ident.rs
new file mode 100644
index 00000000000..03cb4571496
--- /dev/null
+++ b/src/test/ui/proc-macro/raw-ident.rs
@@ -0,0 +1,16 @@
+// aux-build:raw-ident.rs
+
+#[macro_use] extern crate raw_ident;
+
+fn main() {
+    make_struct!(fn);
+    make_struct!(Foo);
+    make_struct!(await);
+
+    r#fn;
+    r#Foo;
+    Foo;
+    r#await;
+
+    make_bad_struct!(S); //~ ERROR expected one of
+}
diff --git a/src/test/ui/proc-macro/raw-ident.stderr b/src/test/ui/proc-macro/raw-ident.stderr
new file mode 100644
index 00000000000..e82a1226b5a
--- /dev/null
+++ b/src/test/ui/proc-macro/raw-ident.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `S`
+  --> $DIR/raw-ident.rs:15:5
+   |
+LL |     make_bad_struct!(S);
+   |     ^^^^^^^^^^^^^^^^^^^^ expected one of 8 possible tokens
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/realloc-16687.rs b/src/test/ui/realloc-16687.rs
index 0687a9ce454..bdcd47a7260 100644
--- a/src/test/ui/realloc-16687.rs
+++ b/src/test/ui/realloc-16687.rs
@@ -5,8 +5,9 @@
 // well enough to reproduce (and illustrate) the bug from #16687.
 
 #![feature(allocator_api)]
+#![feature(slice_ptr_get)]
 
-use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout, ReallocPlacement};
+use std::alloc::{handle_alloc_error, AllocRef, Global, Layout};
 use std::ptr::{self, NonNull};
 
 fn main() {
@@ -41,15 +42,13 @@ unsafe fn test_triangle() -> bool {
             println!("allocate({:?})", layout);
         }
 
-        let memory = Global
-            .alloc(layout, AllocInit::Uninitialized)
-            .unwrap_or_else(|_| handle_alloc_error(layout));
+        let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
 
         if PRINT {
-            println!("allocate({:?}) = {:?}", layout, memory.ptr);
+            println!("allocate({:?}) = {:?}", layout, ptr);
         }
 
-        memory.ptr.cast().as_ptr()
+        ptr.as_non_null_ptr().as_ptr()
     }
 
     unsafe fn deallocate(ptr: *mut u8, layout: Layout) {
@@ -70,21 +69,19 @@ unsafe fn test_triangle() -> bool {
                 NonNull::new_unchecked(ptr),
                 old,
                 new.size(),
-                ReallocPlacement::MayMove,
-                AllocInit::Uninitialized,
             )
         } else {
-            Global.shrink(NonNull::new_unchecked(ptr), old, new.size(), ReallocPlacement::MayMove)
+            Global.shrink(NonNull::new_unchecked(ptr), old, new.size())
         };
 
-        let memory = memory.unwrap_or_else(|_| {
+        let ptr = memory.unwrap_or_else(|_| {
             handle_alloc_error(Layout::from_size_align_unchecked(new.size(), old.align()))
         });
 
         if PRINT {
-            println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, memory.ptr);
+            println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, ptr);
         }
-        memory.ptr.cast().as_ptr()
+        ptr.as_non_null_ptr().as_ptr()
     }
 
     fn idx_to_size(i: usize) -> usize {
diff --git a/src/test/ui/regions/regions-mock-codegen.rs b/src/test/ui/regions/regions-mock-codegen.rs
index 380310190be..ad4b9c352ae 100644
--- a/src/test/ui/regions/regions-mock-codegen.rs
+++ b/src/test/ui/regions/regions-mock-codegen.rs
@@ -4,7 +4,7 @@
 // pretty-expanded FIXME #23616
 #![feature(allocator_api)]
 
-use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout};
+use std::alloc::{handle_alloc_error, AllocRef, Global, Layout};
 use std::ptr::NonNull;
 
 struct arena(());
@@ -25,10 +25,8 @@ struct Ccx {
 fn alloc(_bcx: &arena) -> &Bcx<'_> {
     unsafe {
         let layout = Layout::new::<Bcx>();
-        let memory = Global
-            .alloc(layout, AllocInit::Uninitialized)
-            .unwrap_or_else(|_| handle_alloc_error(layout));
-        &*(memory.ptr.as_ptr() as *const _)
+        let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
+        &*(ptr.as_ptr() as *const _)
     }
 }
 
diff --git a/src/test/ui/rfc-2091-track-caller/error-with-main.rs b/src/test/ui/rfc-2091-track-caller/error-with-main.rs
new file mode 100644
index 00000000000..b2ea31bb517
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-main.rs
@@ -0,0 +1,4 @@
+#[track_caller] //~ ERROR `main` function is not allowed to be
+fn main() {
+    panic!("{}: oh no", std::panic::Location::caller());
+}
diff --git a/src/test/ui/rfc-2091-track-caller/error-with-main.stderr b/src/test/ui/rfc-2091-track-caller/error-with-main.stderr
new file mode 100644
index 00000000000..f05f88e7d71
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-main.stderr
@@ -0,0 +1,12 @@
+error: `main` function is not allowed to be `#[track_caller]`
+  --> $DIR/error-with-main.rs:1:1
+   |
+LL |   #[track_caller]
+   |   ^^^^^^^^^^^^^^^
+LL | / fn main() {
+LL | |     panic!("{}: oh no", std::panic::Location::caller());
+LL | | }
+   | |_- `main` function is not allowed to be `#[track_caller]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2091-track-caller/error-with-start.rs b/src/test/ui/rfc-2091-track-caller/error-with-start.rs
new file mode 100644
index 00000000000..0cab4717063
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-start.rs
@@ -0,0 +1,7 @@
+#![feature(start)]
+
+#[start]
+#[track_caller] //~ ERROR `start` is not allowed to be `#[track_caller]`
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
+    panic!("{}: oh no", std::panic::Location::caller());
+}
diff --git a/src/test/ui/rfc-2091-track-caller/error-with-start.stderr b/src/test/ui/rfc-2091-track-caller/error-with-start.stderr
new file mode 100644
index 00000000000..1a1f3e04491
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/error-with-start.stderr
@@ -0,0 +1,12 @@
+error: `start` is not allowed to be `#[track_caller]`
+  --> $DIR/error-with-start.rs:4:1
+   |
+LL |   #[track_caller]
+   |   ^^^^^^^^^^^^^^^
+LL | / fn start(_argc: isize, _argv: *const *const u8) -> isize {
+LL | |     panic!("{}: oh no", std::panic::Location::caller());
+LL | | }
+   | |_- `start` is not allowed to be `#[track_caller]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
index 35a2956ee26..d6a3a760b3e 100644
--- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
+++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
@@ -7,8 +7,10 @@
 //! Test that panic locations for `#[track_caller]` functions in std have the correct
 //! location reported.
 
+use std::cell::RefCell;
 use std::collections::{BTreeMap, HashMap, VecDeque};
 use std::ops::{Index, IndexMut};
+use std::panic::{AssertUnwindSafe, UnwindSafe};
 
 fn main() {
     // inspect the `PanicInfo` we receive to ensure the right file is the source
@@ -20,7 +22,7 @@ fn main() {
         }
     }));
 
-    fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) {
+    fn assert_panicked(f: impl FnOnce() + UnwindSafe) {
         std::panic::catch_unwind(f).unwrap_err();
     }
 
@@ -57,4 +59,9 @@ fn main() {
     let weirdo: VecDeque<()> = Default::default();
     assert_panicked(|| { weirdo.index(1); });
     assert_panicked(|| { weirdo[1]; });
+
+    let refcell: RefCell<()> = Default::default();
+    let _conflicting = refcell.borrow_mut();
+    assert_panicked(AssertUnwindSafe(|| { refcell.borrow(); }));
+    assert_panicked(AssertUnwindSafe(|| { refcell.borrow_mut(); }));
 }
diff --git a/src/test/ui/suggestions/issue-61226.fixed b/src/test/ui/suggestions/issue-61226.fixed
new file mode 100644
index 00000000000..6e9d74344bc
--- /dev/null
+++ b/src/test/ui/suggestions/issue-61226.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+struct X {}
+fn main() {
+    let _ = vec![X {}]; //…
+    //~^ ERROR expected value, found struct `X`
+}
diff --git a/src/test/ui/suggestions/issue-61226.rs b/src/test/ui/suggestions/issue-61226.rs
index e83b0b4d630..695fe73418a 100644
--- a/src/test/ui/suggestions/issue-61226.rs
+++ b/src/test/ui/suggestions/issue-61226.rs
@@ -1,5 +1,6 @@
+// run-rustfix
 struct X {}
 fn main() {
-    vec![X]; //…
+    let _ = vec![X]; //…
     //~^ ERROR expected value, found struct `X`
 }
diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr
index 7f6f082d7a8..cda962a9045 100644
--- a/src/test/ui/suggestions/issue-61226.stderr
+++ b/src/test/ui/suggestions/issue-61226.stderr
@@ -1,11 +1,11 @@
 error[E0423]: expected value, found struct `X`
-  --> $DIR/issue-61226.rs:3:10
+  --> $DIR/issue-61226.rs:4:18
    |
 LL | struct X {}
    | ----------- `X` defined here
 LL | fn main() {
-LL |     vec![X]; //…
-   |          ^ help: use struct literal syntax instead: `X {}`
+LL |     let _ = vec![X]; //…
+   |                  ^ help: use struct literal syntax instead: `X {}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.fixed b/src/test/ui/suggestions/type-ascription-instead-of-method.fixed
new file mode 100644
index 00000000000..56b740b0d5c
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-method.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+    let _ = Box::new("foo".to_string());
+    //~^ ERROR expected type, found
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.rs b/src/test/ui/suggestions/type-ascription-instead-of-method.rs
index 361729d50c2..a603e09e7e8 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-method.rs
+++ b/src/test/ui/suggestions/type-ascription-instead-of-method.rs
@@ -1,4 +1,5 @@
+// run-rustfix
 fn main() {
-    Box:new("foo".to_string())
+    let _ = Box:new("foo".to_string());
     //~^ ERROR expected type, found
 }
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
index c111b4a9bc7..83bc33f410a 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
@@ -1,10 +1,10 @@
 error: expected type, found `"foo"`
-  --> $DIR/type-ascription-instead-of-method.rs:2:13
+  --> $DIR/type-ascription-instead-of-method.rs:3:21
    |
-LL |     Box:new("foo".to_string())
-   |        -    ^^^^^ expected type
-   |        |
-   |        help: maybe write a path separator here: `::`
+LL |     let _ = Box:new("foo".to_string());
+   |                -    ^^^^^ expected type
+   |                |
+   |                help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
 
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed b/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed
new file mode 100644
index 00000000000..787fcc1208e
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+fn main() -> Result<(), ()> {
+    let _ = vec![Ok(2)].into_iter().collect::<Result<Vec<_>,_>>()?;
+    //~^ ERROR expected `::`, found `(`
+    Ok(())
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs
index 220fd1eebda..934016b3b81 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs
@@ -1,5 +1,6 @@
+// run-rustfix
 fn main() -> Result<(), ()> {
-    vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?;
+    let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?;
     //~^ ERROR expected `::`, found `(`
     Ok(())
 }
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
index 1d1999d350f..970b220b737 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
@@ -1,10 +1,10 @@
 error: expected `::`, found `(`
-  --> $DIR/type-ascription-instead-of-path-2.rs:2:55
+  --> $DIR/type-ascription-instead-of-path-2.rs:3:63
    |
-LL |     vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?;
-   |                                    -                  ^ expected `::`
-   |                                    |
-   |                                    help: maybe write a path separator here: `::`
+LL |     let _ = vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?;
+   |                                            -                  ^ expected `::`
+   |                                            |
+   |                                            help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
 
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed b/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed
new file mode 100644
index 00000000000..b3247e1287d
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+    let _ = Option::Some("");
+    //~^ ERROR expected type, found
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs
index b90867fef6b..6fd2c19541c 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs
+++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 fn main() {
     let _ = Option:Some("");
     //~^ ERROR expected type, found
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
index f38020dcc38..f59ba78d4d3 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
@@ -1,5 +1,5 @@
 error: expected type, found `""`
-  --> $DIR/type-ascription-instead-of-variant.rs:2:25
+  --> $DIR/type-ascription-instead-of-variant.rs:3:25
    |
 LL |     let _ = Option:Some("");
    |                   -     ^^ expected type
diff --git a/src/test/ui/type/ascription/issue-47666.fixed b/src/test/ui/type/ascription/issue-47666.fixed
new file mode 100644
index 00000000000..c4db747551e
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-47666.fixed
@@ -0,0 +1,4 @@
+// run-rustfix
+fn main() {
+    let _ = Option::Some(vec![0, 1]); //~ ERROR expected type, found
+}
diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs
index 8035de4a48a..c67202e2157 100644
--- a/src/test/ui/type/ascription/issue-47666.rs
+++ b/src/test/ui/type/ascription/issue-47666.rs
@@ -1,7 +1,4 @@
+// run-rustfix
 fn main() {
     let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found
-    //~^ ERROR expected value, found enum `Option`
-    //~| ERROR expected type, found variant `Some`
 }
-
-// This case isn't currently being handled gracefully due to the macro invocation.
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
index 72c7c144b53..ba393ff1a20 100644
--- a/src/test/ui/type/ascription/issue-47666.stderr
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -1,5 +1,5 @@
 error: expected type, found reserved keyword `box`
-  --> $DIR/issue-47666.rs:2:25
+  --> $DIR/issue-47666.rs:3:25
    |
 LL |     let _ = Option:Some(vec![0, 1]);
    |                   -     ^^^^^^^^^^
@@ -12,35 +12,5 @@ LL |     let _ = Option:Some(vec![0, 1]);
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0423]: expected value, found enum `Option`
-  --> $DIR/issue-47666.rs:2:13
-   |
-LL |     let _ = Option:Some(vec![0, 1]);
-   |             ^^^^^^
-   |
-help: try using one of the enum's variants
-   |
-LL |     let _ = std::option::Option::None:Some(vec![0, 1]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
-LL |     let _ = std::option::Option::Some:Some(vec![0, 1]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0573]: expected type, found variant `Some`
-  --> $DIR/issue-47666.rs:2:20
-   |
-LL |     let _ = Option:Some(vec![0, 1]);
-   |                    ^^^^^^^^^^^^^^^^ not a type
-   |
-help: try using the variant's enum
-   |
-LL |     let _ = Option:std::option::Option;
-   |                    ^^^^^^^^^^^^^^^^^^^
-help: maybe you meant to write a path separator here
-   |
-LL |     let _ = Option::Some(vec![0, 1]);
-   |                   ^^
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0423, E0573.
-For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/type/ascription/issue-54516.fixed b/src/test/ui/type/ascription/issue-54516.fixed
new file mode 100644
index 00000000000..181637b97bb
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-54516.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+use std::collections::BTreeMap;
+
+fn main() {
+    println!("{}", std::mem::size_of::<BTreeMap<u32, u32>>());
+    //~^ ERROR casts cannot be followed by a function call
+}
diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs
index 8d6fd2abb6d..f09ddd487d8 100644
--- a/src/test/ui/type/ascription/issue-54516.rs
+++ b/src/test/ui/type/ascription/issue-54516.rs
@@ -1,8 +1,7 @@
+// run-rustfix
 use std::collections::BTreeMap;
 
 fn main() {
     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
     //~^ ERROR casts cannot be followed by a function call
-    //~| ERROR expected value, found module `std::mem` [E0423]
-    //~| ERROR cannot find type `size_of` in this scope [E0412]
 }
diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr
index ec08cf209c2..2c7ff6bdc48 100644
--- a/src/test/ui/type/ascription/issue-54516.stderr
+++ b/src/test/ui/type/ascription/issue-54516.stderr
@@ -1,5 +1,5 @@
 error: casts cannot be followed by a function call
-  --> $DIR/issue-54516.rs:4:20
+  --> $DIR/issue-54516.rs:5:20
    |
 LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
    |                    ^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,23 +8,5 @@ LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
 
-error[E0423]: expected value, found module `std::mem`
-  --> $DIR/issue-54516.rs:4:20
-   |
-LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
-   |                    ^^^^^^^^- help: maybe you meant to write a path separator here: `::`
-   |                    |
-   |                    not a value
-
-error[E0412]: cannot find type `size_of` in this scope
-  --> $DIR/issue-54516.rs:4:29
-   |
-LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
-   |                            -^^^^^^^ not found in this scope
-   |                            |
-   |                            help: maybe you meant to write a path separator here: `::`
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0412, E0423.
-For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/type/ascription/issue-60933.fixed b/src/test/ui/type/ascription/issue-60933.fixed
new file mode 100644
index 00000000000..ac9f6a07031
--- /dev/null
+++ b/src/test/ui/type/ascription/issue-60933.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+    let _: usize = std::mem::size_of::<u32>();
+    //~^ ERROR casts cannot be followed by a function call
+}
diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs
index bcf9f88cb41..cb093735efa 100644
--- a/src/test/ui/type/ascription/issue-60933.rs
+++ b/src/test/ui/type/ascription/issue-60933.rs
@@ -1,6 +1,5 @@
+// run-rustfix
 fn main() {
-    let u: usize = std::mem:size_of::<u32>();
+    let _: usize = std::mem:size_of::<u32>();
     //~^ ERROR casts cannot be followed by a function call
-    //~| ERROR expected value, found module `std::mem` [E0423]
-    //~| ERROR cannot find type `size_of` in this scope [E0412]
 }
diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr
index 2006362e1bb..5c35de88e14 100644
--- a/src/test/ui/type/ascription/issue-60933.stderr
+++ b/src/test/ui/type/ascription/issue-60933.stderr
@@ -1,30 +1,12 @@
 error: casts cannot be followed by a function call
-  --> $DIR/issue-60933.rs:2:20
+  --> $DIR/issue-60933.rs:3:20
    |
-LL |     let u: usize = std::mem:size_of::<u32>();
+LL |     let _: usize = std::mem:size_of::<u32>();
    |                    ^^^^^^^^-^^^^^^^^^^^^^^
    |                            |
    |                            help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
 
-error[E0423]: expected value, found module `std::mem`
-  --> $DIR/issue-60933.rs:2:20
-   |
-LL |     let u: usize = std::mem:size_of::<u32>();
-   |                    ^^^^^^^^- help: maybe you meant to write a path separator here: `::`
-   |                    |
-   |                    not a value
-
-error[E0412]: cannot find type `size_of` in this scope
-  --> $DIR/issue-60933.rs:2:29
-   |
-LL |     let u: usize = std::mem:size_of::<u32>();
-   |                            -^^^^^^^ not found in this scope
-   |                            |
-   |                            help: maybe you meant to write a path separator here: `::`
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0412, E0423.
-For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/type/type-ascription-with-fn-call.fixed b/src/test/ui/type/type-ascription-with-fn-call.fixed
new file mode 100644
index 00000000000..6d96c4303c3
--- /dev/null
+++ b/src/test/ui/type/type-ascription-with-fn-call.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+#![feature(type_ascription)]
+
+fn main() {
+    f()  ;
+    f(); //~ ERROR expected type, found function
+}
+
+fn f() {}
diff --git a/src/test/ui/type/type-ascription-with-fn-call.rs b/src/test/ui/type/type-ascription-with-fn-call.rs
index 2bd2efa4d38..ed4f7c9041c 100644
--- a/src/test/ui/type/type-ascription-with-fn-call.rs
+++ b/src/test/ui/type/type-ascription-with-fn-call.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 #![feature(type_ascription)]
 
 fn main() {
diff --git a/src/test/ui/type/type-ascription-with-fn-call.stderr b/src/test/ui/type/type-ascription-with-fn-call.stderr
index eeaca5300f9..5f74724b59e 100644
--- a/src/test/ui/type/type-ascription-with-fn-call.stderr
+++ b/src/test/ui/type/type-ascription-with-fn-call.stderr
@@ -1,8 +1,8 @@
 error[E0573]: expected type, found function `f`
-  --> $DIR/type-ascription-with-fn-call.rs:5:5
+  --> $DIR/type-ascription-with-fn-call.rs:6:5
    |
 LL |     f()  :
-   |          - help: did you mean to use `;` here instead?
+   |          - help: maybe you meant to write `;` here
 LL |     f();
    |     ^^^
    |     |
diff --git a/src/test/ui/warn-path-statement.rs b/src/test/ui/warn-path-statement.rs
index e8525f8b892..2435be623f3 100644
--- a/src/test/ui/warn-path-statement.rs
+++ b/src/test/ui/warn-path-statement.rs
@@ -1,6 +1,17 @@
 // compile-flags: -D path-statements
-fn main() {
+struct Droppy;
+
+impl Drop for Droppy {
+    fn drop(&mut self) {}
+}
 
+fn main() {
     let x = 10;
     x; //~ ERROR path statement with no effect
+
+    let y = Droppy;
+    y; //~ ERROR path statement drops value
+
+    let z = (Droppy,);
+    z; //~ ERROR path statement drops value
 }
diff --git a/src/test/ui/warn-path-statement.stderr b/src/test/ui/warn-path-statement.stderr
index 30afb99e5f0..248d2ef299b 100644
--- a/src/test/ui/warn-path-statement.stderr
+++ b/src/test/ui/warn-path-statement.stderr
@@ -1,10 +1,22 @@
 error: path statement with no effect
-  --> $DIR/warn-path-statement.rs:5:5
+  --> $DIR/warn-path-statement.rs:10:5
    |
 LL |     x;
    |     ^^
    |
    = note: requested on the command line with `-D path-statements`
 
-error: aborting due to previous error
+error: path statement drops value
+  --> $DIR/warn-path-statement.rs:13:5
+   |
+LL |     y;
+   |     ^^ help: use `drop` to clarify the intent: `drop(y);`
+
+error: path statement drops value
+  --> $DIR/warn-path-statement.rs:16:5
+   |
+LL |     z;
+   |     ^^ help: use `drop` to clarify the intent: `drop(z);`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 6ac89f2b1b8..5dede95a858 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -156,6 +156,7 @@ static DOCS_TARGETS: &[&str] = &[
     "x86_64-pc-windows-gnu",
     "x86_64-pc-windows-msvc",
     "x86_64-unknown-linux-gnu",
+    "x86_64-unknown-linux-musl",
 ];
 
 static MINGW: &[&str] = &["i686-pc-windows-gnu", "x86_64-pc-windows-gnu"];
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 2d5c2381e4e50484bf281fc1bfe19743aa9eb37
+Subproject 1653f354644834073d6d2541e27fae94588e685
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index 27a7fa88622..40af6bb3d7b 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -286,14 +286,14 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
                     },
                     _ => {},
                 }
-                if items.is_empty() || !attr.check_name(sym!(deprecated)) {
+                if items.is_empty() || !attr.has_name(sym!(deprecated)) {
                     return;
                 }
                 for item in items {
                     if_chain! {
                         if let NestedMetaItem::MetaItem(mi) = &item;
                         if let MetaItemKind::NameValue(lit) = &mi.kind;
-                        if mi.check_name(sym!(since));
+                        if mi.has_name(sym!(since));
                         then {
                             check_semver(cx, item.span(), lit);
                         }
@@ -309,7 +309,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
         }
         match item.kind {
             ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
-                let skip_unused_imports = item.attrs.iter().any(|attr| attr.check_name(sym!(macro_use)));
+                let skip_unused_imports = item.attrs.iter().any(|attr| attr.has_name(sym!(macro_use)));
 
                 for attr in item.attrs {
                     if in_external_macro(cx.sess(), attr.span) {
@@ -524,7 +524,7 @@ fn check_attrs(cx: &LateContext<'_>, span: Span, name: Name, attrs: &[Attribute]
 
     for attr in attrs {
         if let Some(values) = attr.meta_item_list() {
-            if values.len() != 1 || !attr.check_name(sym!(inline)) {
+            if values.len() != 1 || !attr.has_name(sym!(inline)) {
                 continue;
             }
             if is_word(&values[0], sym!(always)) {
@@ -558,7 +558,7 @@ fn check_semver(cx: &LateContext<'_>, span: Span, lit: &Lit) {
 
 fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
     if let NestedMetaItem::MetaItem(mi) = &nmi {
-        mi.is_word() && mi.check_name(expected)
+        mi.is_word() && mi.has_name(expected)
     } else {
         false
     }
@@ -618,15 +618,15 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::as
 fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute) {
     if_chain! {
         // check cfg_attr
-        if attr.check_name(sym!(cfg_attr));
+        if attr.has_name(sym!(cfg_attr));
         if let Some(items) = attr.meta_item_list();
         if items.len() == 2;
         // check for `rustfmt`
         if let Some(feature_item) = items[0].meta_item();
-        if feature_item.check_name(sym!(rustfmt));
+        if feature_item.has_name(sym!(rustfmt));
         // check for `rustfmt_skip` and `rustfmt::skip`
         if let Some(skip_item) = &items[1].meta_item();
-        if skip_item.check_name(sym!(rustfmt_skip)) ||
+        if skip_item.has_name(sym!(rustfmt_skip)) ||
             skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym!(skip);
         // Only lint outer attributes, because custom inner attributes are unstable
         // Tracking issue: https://github.com/rust-lang/rust/issues/54726
@@ -685,7 +685,7 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) {
     }
 
     if_chain! {
-        if attr.check_name(sym!(cfg));
+        if attr.has_name(sym!(cfg));
         if let Some(list) = attr.meta_item_list();
         let mismatched = find_mismatched_target_os(&list);
         if !mismatched.is_empty();
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index d52bb8961fa..e87c33d1b09 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -323,7 +323,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
             let (comment, current_spans) = strip_doc_comment_decoration(&comment, attr.span);
             spans.extend_from_slice(&current_spans);
             doc.push_str(&comment);
-        } else if attr.check_name(sym!(doc)) {
+        } else if attr.has_name(sym!(doc)) {
             // ignore mix of sugared and non-sugared doc
             // don't trigger the safety or errors check
             return DocHeaders {
diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
index decbee27815..4b605fdb366 100644
--- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
+++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
@@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody {
 
 fn check_attrs(cx: &LateContext<'_>, name: Symbol, attrs: &[Attribute]) {
     for attr in attrs {
-        if !attr.check_name(sym!(inline)) {
+        if !attr.has_name(sym!(inline)) {
             continue;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index f3b8902e26f..ca1381852da 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -83,7 +83,7 @@ fn check_manual_non_exhaustive_enum(cx: &EarlyContext<'_>, item: &Item, variants
     }
 
     fn is_doc_hidden(attr: &Attribute) -> bool {
-        attr.check_name(sym!(doc))
+        attr.has_name(sym!(doc))
             && match attr.meta_item_list() {
                 Some(l) => attr::list_contains_name(&l, sym!(hidden)),
                 None => false,
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 06e0f43c10b..813f9c43948 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
     fn enter_lint_attrs(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) {
         let doc_hidden = self.doc_hidden()
             || attrs.iter().any(|attr| {
-                attr.check_name(sym!(doc))
+                attr.has_name(sym!(doc))
                     && match attr.meta_item_list() {
                         None => false,
                         Some(l) => attr::list_contains_name(&l[..], sym!(hidden)),
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 9c962673537..3eae45b2819 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -57,7 +57,7 @@ declare_clippy_lint! {
 }
 
 fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) {
-    let has_inline = attrs.iter().any(|a| a.check_name(sym!(inline)));
+    let has_inline = attrs.iter().any(|a| a.has_name(sym!(inline)));
     if !has_inline {
         span_lint(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrow.rs b/src/tools/clippy/clippy_lints/src/needless_borrow.rs
index 415ab556c9f..9391049c6e8 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrow.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrow.rs
@@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow {
     }
 
     fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'_>) {
-        if item.attrs.iter().any(|a| a.check_name(sym!(automatically_derived))) {
+        if item.attrs.iter().any(|a| a.has_name(sym!(automatically_derived))) {
             debug_assert!(self.derived_item.is_none());
             self.derived_item = Some(item.hir_id);
         }
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 09577877744..a7f7c97fc48 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -312,7 +312,7 @@ fn requires_exact_signature(attrs: &[Attribute]) -> bool {
     attrs.iter().any(|attr| {
         [sym!(proc_macro), sym!(proc_macro_attribute), sym!(proc_macro_derive)]
             .iter()
-            .any(|&allow| attr.check_name(allow))
+            .any(|&allow| attr.has_name(allow))
     })
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index faef7e724dd..8ed20995a70 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -235,7 +235,7 @@ impl EarlyLintPass for Return {
 }
 
 fn attr_is_cfg(attr: &ast::Attribute) -> bool {
-    attr.meta_item_list().is_some() && attr.check_name(sym!(cfg))
+    attr.meta_item_list().is_some() && attr.has_name(sym!(cfg))
 }
 
 // get the def site
diff --git a/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs b/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs
index 6a2b05e3e6d..7948d99162b 100644
--- a/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/trivially_copy_pass_by_ref.rs
@@ -155,7 +155,7 @@ impl<'tcx> LateLintPass<'tcx> for TriviallyCopyPassByRef {
                     return;
                 }
                 for a in attrs {
-                    if a.meta_item_list().is_some() && a.check_name(sym!(proc_macro_derive)) {
+                    if a.meta_item_list().is_some() && a.has_name(sym!(proc_macro_derive)) {
                         return;
                     }
                 }
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index de425211e38..ba3492a6fff 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -13,7 +13,7 @@ use std::{env, fmt, fs, io};
 /// Gets the configuration file from arguments.
 pub fn file_from_args(args: &[NestedMetaItem]) -> Result<Option<PathBuf>, (&'static str, Span)> {
     for arg in args.iter().filter_map(NestedMetaItem::meta_item) {
-        if arg.check_name(sym!(conf_file)) {
+        if arg.has_name(sym!(conf_file)) {
             return match arg.kind {
                 MetaItemKind::Word | MetaItemKind::List(_) => Err(("`conf_file` must be a named value", arg.span)),
                 MetaItemKind::NameValue(ref value) => {
diff --git a/src/tools/clippy/tests/ui/formatting.rs b/src/tools/clippy/tests/ui/formatting.rs
index 078811b8d88..f54b3f2bfe2 100644
--- a/src/tools/clippy/tests/ui/formatting.rs
+++ b/src/tools/clippy/tests/ui/formatting.rs
@@ -149,7 +149,7 @@ fn main() {
         1 + 2, 3 
                 - 4, 5
     ];
-    // lint if it doesnt
+    // lint if it doesn't
     let _ = &[
         -1
         -4,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 2ab764eb920..047fbe9da14 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -1,3 +1,4 @@
+use std::collections::HashSet;
 use std::env;
 use std::fs::File;
 use std::io::prelude::*;
@@ -186,6 +187,17 @@ impl EarlyProps {
             if config.system_llvm && line.starts_with("no-system-llvm") {
                 return true;
             }
+            if let Some(needed_components) =
+                config.parse_name_value_directive(line, "needs-llvm-components")
+            {
+                let components: HashSet<_> = config.llvm_components.split_whitespace().collect();
+                if !needed_components
+                    .split_whitespace()
+                    .all(|needed_component| components.contains(needed_component))
+                {
+                    return true;
+                }
+            }
             if let Some(actual_version) = config.llvm_version {
                 if let Some(rest) = line.strip_prefix("min-llvm-version:").map(str::trim) {
                     let min_version = extract_llvm_version(rest).unwrap();
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 9354cc16a9a..940e16720f6 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -178,27 +178,30 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
     results
 }
 
-fn print_diff(expected: &str, actual: &str, context_size: usize) {
+fn write_diff(expected: &str, actual: &str, context_size: usize) -> String {
+    use std::fmt::Write;
+    let mut output = String::new();
     let diff_results = make_diff(expected, actual, context_size);
     for result in diff_results {
         let mut line_number = result.line_number;
         for line in result.lines {
             match line {
                 DiffLine::Expected(e) => {
-                    println!("-\t{}", e);
+                    writeln!(output, "-\t{}", e).unwrap();
                     line_number += 1;
                 }
                 DiffLine::Context(c) => {
-                    println!("{}\t{}", line_number, c);
+                    writeln!(output, "{}\t{}", line_number, c).unwrap();
                     line_number += 1;
                 }
                 DiffLine::Resulting(r) => {
-                    println!("+\t{}", r);
+                    writeln!(output, "+\t{}", r).unwrap();
                 }
             }
         }
-        println!();
+        writeln!(output, "").unwrap();
     }
+    output
 }
 
 pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
@@ -655,8 +658,12 @@ impl<'test> TestCx<'test> {
                  ------------------------------------------\n\
                  {}\n\
                  ------------------------------------------\n\
-                 \n",
-                expected, actual
+                 diff:\n\
+                 ------------------------------------------\n\
+                 {}\n",
+                expected,
+                actual,
+                write_diff(expected, actual, 3),
             ));
         }
     }
@@ -3227,7 +3234,7 @@ impl<'test> TestCx<'test> {
                     }
                     let expected_string = fs::read_to_string(&expected_file).unwrap();
                     if dumped_string != expected_string {
-                        print_diff(&expected_string, &dumped_string, 3);
+                        print!("{}", write_diff(&expected_string, &dumped_string, 3));
                         panic!(
                             "Actual MIR output differs from expected MIR output {}",
                             expected_file.display()
@@ -3452,7 +3459,7 @@ impl<'test> TestCx<'test> {
                 println!("normalized {}:\n{}\n", kind, actual);
             } else {
                 println!("diff of {}:\n", kind);
-                print_diff(expected, actual, 3);
+                print!("{}", write_diff(expected, actual, 3));
             }
         }
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 55e17466a88..1f988f7d81b 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -138,7 +138,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
     "rand_chacha",
     "rand_core",
     "rand_hc",
-    "rand_isaac",
     "rand_pcg",
     "rand_xorshift",
     "redox_syscall",