about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--.reuse/dep528
-rw-r--r--Cargo.lock12
-rw-r--r--LICENSES/Apache-2.0.txt73
-rw-r--r--LICENSES/BSD-2-Clause.txt9
-rw-r--r--LICENSES/MIT.txt9
-rw-r--r--LICENSES/OFL-1.1.txt43
-rw-r--r--compiler/rustc_apfloat/src/lib.rs2
-rw-r--r--compiler/rustc_arena/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/ast.rs32
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs8
-rw-r--r--compiler/rustc_ast/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs3
-rw-r--r--compiler/rustc_ast/src/util/literal.rs18
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs58
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs14
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs67
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs13
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs32
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/edition_panic.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs1
-rw-r--r--compiler/rustc_const_eval/src/errors.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs5
-rw-r--r--compiler/rustc_data_structures/src/lib.rs2
-rw-r--r--compiler/rustc_data_structures/src/sync.rs2
-rw-r--r--compiler/rustc_error_codes/src/lib.rs2
-rw-r--r--compiler/rustc_error_messages/locales/en-US/expand.ftl17
-rw-r--r--compiler/rustc_error_messages/locales/en-US/interface.ftl6
-rw-r--r--compiler/rustc_error_messages/locales/en-US/parser.ftl9
-rw-r--r--compiler/rustc_error_messages/locales/en-US/typeck.ftl14
-rw-r--r--compiler/rustc_error_messages/src/lib.rs3
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs19
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs3
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs32
-rw-r--r--compiler/rustc_errors/src/emitter.rs128
-rw-r--r--compiler/rustc_errors/src/json.rs19
-rw-r--r--compiler/rustc_errors/src/lib.rs85
-rw-r--r--compiler/rustc_errors/src/translation.rs103
-rw-r--r--compiler/rustc_expand/src/build.rs25
-rw-r--r--compiler/rustc_expand/src/errors.rs48
-rw-r--r--compiler/rustc_expand/src/expand.rs24
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs34
-rw-r--r--compiler/rustc_expand/src/placeholders.rs6
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs18
-rw-r--r--compiler/rustc_feature/src/lib.rs2
-rw-r--r--compiler/rustc_fs_util/src/lib.rs3
-rw-r--r--compiler/rustc_graphviz/src/lib.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs1
-rw-r--r--compiler/rustc_hir/src/intravisit.rs5
-rw-r--r--compiler/rustc_hir/src/lib.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs4
-rw-r--r--compiler/rustc_index/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs136
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs12
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs14
-rw-r--r--compiler/rustc_infer/src/infer/outlives/test_type_match.rs9
-rw-r--r--compiler/rustc_interface/Cargo.toml1
-rw-r--r--compiler/rustc_interface/src/passes.rs40
-rw-r--r--compiler/rustc_lexer/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/hidden_unicode_codepoints.rs4
-rw-r--r--compiler/rustc_lint/src/types.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs51
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp25
-rw-r--r--compiler/rustc_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_log/src/lib.rs3
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs82
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs87
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs4
-rw-r--r--compiler/rustc_macros/src/lib.rs10
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs257
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs5
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs191
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs6
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs4
-rw-r--r--compiler/rustc_middle/src/mir/query.rs22
-rw-r--r--compiler/rustc_middle/src/query/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/error.rs12
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs4
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs9
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs88
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs13
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs52
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs10
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs1
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs2
-rw-r--r--compiler/rustc_parse/src/parser/path.rs14
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs35
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs4
-rw-r--r--compiler/rustc_parse_format/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/errors.rs171
-rw-r--r--compiler/rustc_privacy/src/errors.rs14
-rw-r--r--compiler/rustc_query_impl/Cargo.toml1
-rw-r--r--compiler/rustc_query_impl/src/lib.rs2
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs58
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs13
-rw-r--r--compiler/rustc_query_impl/src/values.rs20
-rw-r--r--compiler/rustc_resolve/src/imports.rs40
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs12
-rw-r--r--compiler/rustc_serialize/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/parse.rs63
-rw-r--r--compiler/rustc_smir/src/lib.rs2
-rw-r--r--compiler/rustc_span/src/lib.rs8
-rw-r--r--compiler/rustc_span/src/source_map.rs5
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs4
-rw-r--r--compiler/rustc_target/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/apple_sdk_base.rs1
-rw-r--r--compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv4t_none_eabi.rs4
-rw-r--r--compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs30
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs75
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs18
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--compiler/rustc_traits/src/lib.rs2
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs57
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs4
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs50
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs11
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs12
-rw-r--r--compiler/rustc_typeck/src/check/inherited.rs6
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs5
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs26
-rw-r--r--compiler/rustc_typeck/src/check_unused.rs63
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs8
-rw-r--r--compiler/rustc_typeck/src/collect.rs7
-rw-r--r--compiler/rustc_typeck/src/errors.rs73
-rw-r--r--library/alloc/src/lib.rs9
-rw-r--r--library/alloc/src/str.rs2
-rw-r--r--library/alloc/src/string.rs16
-rw-r--r--library/alloc/src/sync/tests.rs19
-rw-r--r--library/core/src/cmp.rs9
-rw-r--r--library/core/src/iter/adapters/flatten.rs375
-rw-r--r--library/core/src/num/f32.rs6
-rw-r--r--library/core/src/num/f64.rs6
-rw-r--r--library/core/src/num/mod.rs2
-rw-r--r--library/core/src/str/lossy.rs244
-rw-r--r--library/core/src/str/mod.rs6
-rw-r--r--library/core/tests/iter/adapters/flatten.rs42
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/str_lossy.rs138
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/collections/hash/map/tests.rs24
-rw-r--r--library/std/src/io/tests.rs3
-rw-r--r--library/std/src/lib.rs20
-rw-r--r--library/std/src/net/ip.rs51
-rw-r--r--library/std/src/net/ip/display_buffer.rs40
-rw-r--r--library/std/src/os/fortanix_sgx/mod.rs1
-rw-r--r--library/std/src/os/unix/net/listener.rs12
-rw-r--r--library/std/src/path/tests.rs5
-rw-r--r--library/std/src/sync/mpsc/mpsc_queue/tests.rs2
-rw-r--r--library/std/src/sync/mpsc/spsc_queue/tests.rs5
-rw-r--r--library/std/src/sync/mpsc/sync_tests.rs21
-rw-r--r--library/std/src/sync/mpsc/tests.rs12
-rw-r--r--library/std/src/sync/rwlock/tests.rs2
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/alloc.rs161
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/mod.rs8
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/raw.rs24
-rw-r--r--library/std/src/sys/sgx/abi/usercalls/tests.rs30
-rw-r--r--library/std/src/sys/unix/fs.rs2
-rw-r--r--library/std/src/sys/unix/os_str.rs40
-rw-r--r--library/std/src/sys/unix/os_str/tests.rs8
-rw-r--r--library/std/src/sys/windows/c.rs26
-rw-r--r--library/std/src/sys/windows/compat.rs121
-rw-r--r--library/std/src/sys/windows/mod.rs18
-rw-r--r--library/std/src/sys/windows/thread_parker.rs27
-rw-r--r--library/std/src/thread/tests.rs19
-rw-r--r--library/std/src/time/tests.rs3
-rw-r--r--library/unwind/build.rs8
-rw-r--r--src/bootstrap/bin/rustc.rs15
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/config.rs39
-rw-r--r--src/bootstrap/native.rs89
-rw-r--r--src/bootstrap/util.rs4
-rw-r--r--src/ci/docker/host-x86_64/arm-android/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/armhf-gnu/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile9
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in22
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt145
-rw-r--r--src/ci/docker/host-x86_64/test-various/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/wasm32/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile4
-rw-r--r--src/ci/docker/static/gitconfig2
-rw-r--r--src/ci/github-actions/ci.yml18
-rwxr-xr-xsrc/ci/run.sh22
-rwxr-xr-xsrc/ci/scripts/install-clang.sh4
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/platform-support/fuchsia.md20
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/clean/types.rs6
-rw-r--r--src/librustdoc/html/render/mod.rs29
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css70
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css65
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css65
-rw-r--r--src/librustdoc/html/static/css/themes/light.css67
-rw-r--r--src/librustdoc/json/mod.rs4
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs21
-rw-r--r--src/test/codegen/README.md22
-rw-r--r--src/test/codegen/try_question_mark_nop.rs54
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-1.rs1
-rw-r--r--src/test/mir-opt/inline/polymorphic-recursion.rs25
-rw-r--r--src/test/mir-opt/issue-91633.rs31
-rw-r--r--src/test/mir-opt/issue_91633.bar.mir_map.0.mir39
-rw-r--r--src/test/mir-opt/issue_91633.foo.mir_map.0.mir57
-rw-r--r--src/test/mir-opt/issue_91633.fun.mir_map.0.mir35
-rw-r--r--src/test/mir-opt/issue_91633.hey.mir_map.0.mir35
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt6
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt6
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt6
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt5
-rw-r--r--src/test/rustdoc-gui/pocket-menu.goml2
-rw-r--r--src/test/rustdoc-gui/search-filter.goml2
-rw-r--r--src/test/rustdoc-gui/search-form-elements.goml243
-rw-r--r--src/test/rustdoc-gui/search-input.goml7
-rw-r--r--src/test/rustdoc-json/nested.rs13
-rw-r--r--src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs11
-rw-r--r--src/test/rustdoc-json/reexport/glob_extern.rs9
-rw-r--r--src/test/rustdoc-json/reexport/glob_private.rs9
-rw-r--r--src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs4
-rw-r--r--src/test/rustdoc-json/reexport/macro.rs6
-rw-r--r--src/test/rustdoc-json/reexport/private_twice_one_inline.rs18
-rw-r--r--src/test/rustdoc-json/reexport/private_two_names.rs14
-rw-r--r--src/test/rustdoc-json/reexport/rename_public.rs6
-rw-r--r--src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs16
-rw-r--r--src/test/rustdoc-json/reexport/simple_private.rs4
-rw-r--r--src/test/rustdoc-json/reexport/simple_public.rs6
-rw-r--r--src/test/rustdoc-json/type/fn_lifetime.rs3
-rw-r--r--src/test/rustdoc/issue-100679-sidebar-links-deref.rs30
-rw-r--r--src/test/rustdoc/issue-32374.rs14
-rw-r--r--src/test/ui-fulldeps/internal-lints/diagnostics.rs2
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs211
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr338
-rw-r--r--src/test/ui/associated-types/associated-types-path-2.stderr4
-rw-r--r--src/test/ui/associated-types/defaults-suitability.stderr6
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.badbase.stderr17
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.badnll.stderr2
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-2.stderr4
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.stderr4
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.stderr2
-rw-r--r--src/test/ui/associated-types/issue-44153.stderr2
-rw-r--r--src/test/ui/associated-types/issue-65774-1.stderr2
-rw-r--r--src/test/ui/associated-types/substs-ppaux.normal.stderr2
-rw-r--r--src/test/ui/associated-types/substs-ppaux.verbose.stderr2
-rw-r--r--src/test/ui/async-await/issue-68112.stderr2
-rw-r--r--src/test/ui/async-await/issue-70594.stderr2
-rw-r--r--src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr2
-rw-r--r--src/test/ui/async-await/unnecessary-await.stderr2
-rw-r--r--src/test/ui/attempted-access-non-fatal.rs4
-rw-r--r--src/test/ui/attempted-access-non-fatal.stderr46
-rw-r--r--src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr2
-rw-r--r--src/test/ui/block-result/issue-22645.stderr2
-rw-r--r--src/test/ui/borrowck/issue-64453.stderr1
-rw-r--r--src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr5
-rw-r--r--src/test/ui/check-static-values-constraints.stderr1
-rw-r--r--src/test/ui/closures/closure-move-sync.stderr4
-rw-r--r--src/test/ui/coherence/issue-100191-2.stderr4
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr8
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr4
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr8
-rw-r--r--src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr2
-rw-r--r--src/test/ui/consts/const-blocks/migrate-fail.stderr4
-rw-r--r--src/test/ui/consts/const-blocks/nll-fail.stderr4
-rw-r--r--src/test/ui/consts/const-blocks/trait-error.stderr2
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr26
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr26
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.rs6
-rw-r--r--src/test/ui/consts/issue-32829-2.stderr2
-rw-r--r--src/test/ui/consts/mir_check_nonconst.stderr1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr22
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.rs3
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.stderr22
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.stderr22
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr22
-rw-r--r--src/test/ui/derives/deriving-copyclone.stderr6
-rw-r--r--src/test/ui/derives/deriving-no-inner-impl-error-message.rs1
-rw-r--r--src/test/ui/derives/deriving-no-inner-impl-error-message.stderr24
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.stdout57
-rw-r--r--src/test/ui/drop/drop-foreign-fundamental.rs23
-rw-r--r--src/test/ui/drop/drop-foreign-fundamental.stderr9
-rw-r--r--src/test/ui/dropck/drop-on-non-struct.rs7
-rw-r--r--src/test/ui/dropck/drop-on-non-struct.stderr4
-rw-r--r--src/test/ui/error-codes/E0117.rs2
-rw-r--r--src/test/ui/error-codes/E0117.stderr4
-rw-r--r--src/test/ui/error-codes/E0120.stderr4
-rw-r--r--src/test/ui/error-codes/E0275.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr9
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs30
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr21
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs26
-rw-r--r--src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr24
-rw-r--r--src/test/ui/fmt/ifmt-unimpl.stderr2
-rw-r--r--src/test/ui/fmt/send-sync.stderr2
-rw-r--r--src/test/ui/for/for-c-in-str.rs2
-rw-r--r--src/test/ui/for/for-c-in-str.stderr2
-rw-r--r--src/test/ui/for/for-loop-bogosity.stderr2
-rw-r--r--src/test/ui/generator/issue-68112.rs2
-rw-r--r--src/test/ui/generator/issue-68112.stderr2
-rw-r--r--src/test/ui/generator/not-send-sync.stderr2
-rw-r--r--src/test/ui/generator/print/generator-print-verbose-1.stderr2
-rw-r--r--src/test/ui/generator/print/generator-print-verbose-2.stderr2
-rw-r--r--src/test/ui/generator/yield-outside-generator-issue-78653.stderr2
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.base.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.base.stderr2
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr2
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr6
-rw-r--r--src/test/ui/impl-trait/issues/issue-86800.rs9
-rw-r--r--src/test/ui/impl-trait/issues/issue-86800.stderr25
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait.rs10
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait.stderr16
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait2.rs2
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait2.stderr8
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait3.rs2
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait3.stderr8
-rw-r--r--src/test/ui/impl-trait/nested-return-type2.rs8
-rw-r--r--src/test/ui/impl-trait/nested-return-type2.stderr16
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.stderr4
-rw-r--r--src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr2
-rw-r--r--src/test/ui/implied-bounds/issue-100690.rs45
-rw-r--r--src/test/ui/implied-bounds/issue-100690.stderr22
-rw-r--r--src/test/ui/index-help.stderr2
-rw-r--r--src/test/ui/indexing-requires-a-uint.stderr2
-rw-r--r--src/test/ui/integral-indexing.stderr16
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.stderr2
-rw-r--r--src/test/ui/issues/issue-100605.rs9
-rw-r--r--src/test/ui/issues/issue-100605.stderr46
-rw-r--r--src/test/ui/issues/issue-16538.mir.stderr1
-rw-r--r--src/test/ui/issues/issue-16538.thir.stderr1
-rw-r--r--src/test/ui/issues/issue-20413.stderr16
-rw-r--r--src/test/ui/issues/issue-20605.stderr2
-rw-r--r--src/test/ui/issues/issue-21763.stderr2
-rw-r--r--src/test/ui/issues/issue-22872.stderr2
-rw-r--r--src/test/ui/issues/issue-23122-2.stderr2
-rw-r--r--src/test/ui/issues/issue-25901.stderr1
-rw-r--r--src/test/ui/issues/issue-31173.stderr10
-rw-r--r--src/test/ui/issues/issue-32709.stderr2
-rw-r--r--src/test/ui/issues/issue-33941.stderr6
-rw-r--r--src/test/ui/issues/issue-38821.stderr2
-rw-r--r--src/test/ui/issues/issue-39970.stderr2
-rw-r--r--src/test/ui/issues/issue-40827.stderr4
-rw-r--r--src/test/ui/issues/issue-41974.stderr4
-rw-r--r--src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr2
-rw-r--r--src/test/ui/issues/issue-7364.stderr2
-rw-r--r--src/test/ui/iterators/integral.stderr24
-rw-r--r--src/test/ui/iterators/issue-28098.rs2
-rw-r--r--src/test/ui/iterators/issue-28098.stderr32
-rw-r--r--src/test/ui/iterators/ranges.stderr4
-rw-r--r--src/test/ui/iterators/string.stderr4
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params-2.stderr2
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params.stderr12
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr4
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr4
-rw-r--r--src/test/ui/kindck/kindck-send-object.stderr4
-rw-r--r--src/test/ui/kindck/kindck-send-object1.stderr4
-rw-r--r--src/test/ui/kindck/kindck-send-object2.stderr4
-rw-r--r--src/test/ui/kindck/kindck-send-owned.stderr2
-rw-r--r--src/test/ui/lexical-scopes.stderr2
-rw-r--r--src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs30
-rw-r--r--src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr27
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr2
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr2
-rw-r--r--src/test/ui/macros/stringify.rs7
-rw-r--r--src/test/ui/mismatched_types/E0631.rs2
-rw-r--r--src/test/ui/mismatched_types/E0631.stderr8
-rw-r--r--src/test/ui/mismatched_types/closure-arg-count.rs2
-rw-r--r--src/test/ui/mismatched_types/closure-arg-count.stderr8
-rw-r--r--src/test/ui/mutexguard-sync.stderr2
-rw-r--r--src/test/ui/not-panic/not-panic-safe-2.stderr4
-rw-r--r--src/test/ui/not-panic/not-panic-safe-3.stderr4
-rw-r--r--src/test/ui/not-panic/not-panic-safe-4.stderr4
-rw-r--r--src/test/ui/not-panic/not-panic-safe-5.stderr2
-rw-r--r--src/test/ui/not-panic/not-panic-safe-6.stderr4
-rw-r--r--src/test/ui/object-safety/issue-19538.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr4
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.rs3
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.stderr39
-rw-r--r--src/test/ui/on-unimplemented/on-impl.rs1
-rw-r--r--src/test/ui/on-unimplemented/on-impl.stderr11
-rw-r--r--src/test/ui/on-unimplemented/slice-index.stderr4
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass.rs16
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr13
-rw-r--r--src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs4
-rw-r--r--src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr24
-rw-r--r--src/test/ui/parser/fn-defined-using-def.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-def.stderr10
-rw-r--r--src/test/ui/parser/fn-defined-using-fun.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-fun.stderr10
-rw-r--r--src/test/ui/parser/fn-defined-using-func.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-func.stderr10
-rw-r--r--src/test/ui/parser/fn-defined-using-function.rs10
-rw-r--r--src/test/ui/parser/fn-defined-using-function.stderr10
-rw-r--r--src/test/ui/parser/struct-literal-in-for.stderr2
-rw-r--r--src/test/ui/pattern/rest-pat-syntactic.rs5
-rw-r--r--src/test/ui/pattern/rest-pat-syntactic.stderr24
-rw-r--r--src/test/ui/phantom-auto-trait.stderr4
-rw-r--r--src/test/ui/range/range-1.stderr4
-rw-r--r--src/test/ui/recursion/issue-83150.stderr2
-rw-r--r--src/test/ui/regions/outlives-with-missing.rs16
-rw-r--r--src/test/ui/regions/outlives-with-missing.stderr12
-rw-r--r--src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs21
-rw-r--r--src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr12
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr4
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr2
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/span/issue-35987.stderr4
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.rs4
-rw-r--r--src/test/ui/span/lint-unused-unsafe-thir.stderr18
-rw-r--r--src/test/ui/span/lint-unused-unsafe.mir.stderr548
-rw-r--r--src/test/ui/span/lint-unused-unsafe.rs74
-rw-r--r--src/test/ui/specialization/default-generic-associated-type-bound.stderr2
-rw-r--r--src/test/ui/specialization/issue-38091-2.stderr2
-rw-r--r--src/test/ui/specialization/issue-39448.stderr4
-rw-r--r--src/test/ui/specialization/issue-45814.stderr4
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.stderr4
-rw-r--r--src/test/ui/static/static-vec-repeat-not-constant.stderr1
-rw-r--r--src/test/ui/stats/hir-stats.stderr110
-rw-r--r--src/test/ui/str/str-idx.stderr4
-rw-r--r--src/test/ui/str/str-mut-idx.stderr4
-rw-r--r--src/test/ui/suggestions/as-ref-2.fixed13
-rw-r--r--src/test/ui/suggestions/as-ref-2.rs2
-rw-r--r--src/test/ui/suggestions/as-ref-2.stderr10
-rw-r--r--src/test/ui/suggestions/derive-clone-for-eq.stderr2
-rw-r--r--src/test/ui/suggestions/derive-macro-missing-bounds.stderr16
-rw-r--r--src/test/ui/suggestions/into-str.stderr2
-rw-r--r--src/test/ui/suggestions/issue-62843.stderr2
-rw-r--r--src/test/ui/suggestions/issue-71394-no-from-impl.stderr2
-rw-r--r--src/test/ui/suggestions/issue-96223.stderr4
-rw-r--r--src/test/ui/suggestions/issue-96555.stderr6
-rw-r--r--src/test/ui/suggestions/many-type-ascription.rs4
-rw-r--r--src/test/ui/suggestions/many-type-ascription.stderr12
-rw-r--r--src/test/ui/suggestions/option-content-move.fixed39
-rw-r--r--src/test/ui/suggestions/option-content-move.rs2
-rw-r--r--src/test/ui/suggestions/option-content-move.stderr14
-rw-r--r--src/test/ui/suggestions/return-cycle-2.rs14
-rw-r--r--src/test/ui/suggestions/return-cycle-2.stderr12
-rw-r--r--src/test/ui/suggestions/return-cycle.rs14
-rw-r--r--src/test/ui/suggestions/return-cycle.stderr12
-rw-r--r--src/test/ui/suggestions/slice-issue-87994.stderr8
-rw-r--r--src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed15
-rw-r--r--src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs15
-rw-r--r--src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr25
-rw-r--r--src/test/ui/suggestions/suggest-dereferencing-index.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-remove-refs-1.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-remove-refs-2.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-remove-refs-3.stderr2
-rw-r--r--src/test/ui/suggestions/type-ascription-and-other-error.rs6
-rw-r--r--src/test/ui/suggestions/type-ascription-and-other-error.stderr8
-rw-r--r--src/test/ui/traits/alias/cross-crate.stderr4
-rw-r--r--src/test/ui/traits/alias/self-in-const-generics.rs12
-rw-r--r--src/test/ui/traits/alias/self-in-const-generics.stderr11
-rw-r--r--src/test/ui/traits/alias/self-in-generics.rs7
-rw-r--r--src/test/ui/traits/alias/self-in-generics.stderr2
-rw-r--r--src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs2
-rw-r--r--src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr2
-rw-r--r--src/test/ui/traits/cycle-cache-err-60010.stderr4
-rw-r--r--src/test/ui/traits/inductive-overflow/lifetime.rs2
-rw-r--r--src/test/ui/traits/inductive-overflow/lifetime.stderr4
-rw-r--r--src/test/ui/traits/inductive-overflow/simultaneous.stderr2
-rw-r--r--src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr2
-rw-r--r--src/test/ui/traits/inductive-overflow/supertrait.stderr2
-rw-r--r--src/test/ui/traits/issue-18400.stderr4
-rw-r--r--src/test/ui/traits/issue-20692.stderr2
-rw-r--r--src/test/ui/traits/issue-38604.stderr2
-rw-r--r--src/test/ui/traits/issue-71036.rs2
-rw-r--r--src/test/ui/traits/issue-71036.stderr2
-rw-r--r--src/test/ui/traits/issue-71136.stderr2
-rw-r--r--src/test/ui/traits/issue-82830.stderr2
-rw-r--r--src/test/ui/traits/issue-91594.stderr2
-rw-r--r--src/test/ui/traits/issue-91949-hangs-on-recursion.stderr4
-rw-r--r--src/test/ui/traits/issue-97576.stderr2
-rw-r--r--src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr6
-rw-r--r--src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr2
-rw-r--r--src/test/ui/traits/object/safety.stderr2
-rw-r--r--src/test/ui/traits/suggest-deferences/issue-39029.stderr12
-rw-r--r--src/test/ui/traits/suggest-deferences/issue-62530.stderr10
-rw-r--r--src/test/ui/traits/suggest-deferences/multiple-0.stderr10
-rw-r--r--src/test/ui/traits/suggest-deferences/root-obligation.stderr4
-rw-r--r--src/test/ui/traits/test-2.stderr2
-rw-r--r--src/test/ui/try-block/try-block-bad-type.stderr2
-rw-r--r--src/test/ui/try-trait/bad-interconversion.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-2.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr2
-rw-r--r--src/test/ui/typeck/issue-90101.stderr2
-rw-r--r--src/test/ui/typeck/issue-91633.rs8
-rw-r--r--src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr14
-rw-r--r--src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs8
-rw-r--r--src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr17
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr38
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs2
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr24
-rw-r--r--src/test/ui/unsized/issue-30355.stderr9
-rw-r--r--src/test/ui/wf/hir-wf-check-erase-regions.stderr4
-rw-r--r--src/test/ui/wf/wf-const-type.stderr2
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr6
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr6
-rw-r--r--src/test/ui/wf/wf-static-type.stderr2
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.stderr4
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/octal_escapes.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs10
-rw-r--r--src/tools/compiletest/src/runtest.rs2
-rw-r--r--src/tools/jsondocck/src/main.rs42
m---------src/tools/miri16
-rw-r--r--src/tools/rust-analyzer/.github/workflows/ci.yaml2
-rw-r--r--src/tools/rust-analyzer/.github/workflows/release.yaml10
-rw-r--r--src/tools/rust-analyzer/.vscode/launch.json2
-rw-r--r--src/tools/rust-analyzer/Cargo.lock1
-rw-r--r--src/tools/rust-analyzer/bench_data/glorious_old_parser2
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs22
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs190
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/name.rs52
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/quote.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs33
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs45
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs157
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs112
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs59
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs54
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/source_change.rs136
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs310
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs18
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs33
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/runnables.rs186
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/status.rs2
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs11
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs26
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs34
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast43
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs3
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast116
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs10
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast49
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast23
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs5
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs5
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs105
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs156
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs529
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs32
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs89
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs493
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs304
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs81
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs84
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs339
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs166
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs1125
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs139
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs792
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs11
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs6
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs26
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs1
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs18
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs7
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs399
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/fuzz.rs5
-rw-r--r--src/tools/rust-analyzer/editors/code/package-lock.json3974
-rw-r--r--src/tools/rust-analyzer/editors/code/src/client.ts16
-rw-r--r--src/tools/rust-analyzer/editors/code/src/commands.ts18
-rw-r--r--src/tools/rust-analyzer/lib/la-arena/src/lib.rs1
-rw-r--r--src/tools/rustfmt/src/expr.rs8
-rw-r--r--src/tools/rustfmt/src/parse/session.rs52
-rw-r--r--triagebot.toml29
685 files changed, 11816 insertions, 8982 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7eb41fec36a..11b115cb2ff 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -391,24 +391,28 @@ jobs:
             env:
               RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --set llvm.allow-old-toolchain"
               SCRIPT: make ci-mingw-subset-1
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             os: windows-latest-xl
           - name: i686-mingw-2
             env:
               RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --set llvm.allow-old-toolchain"
               SCRIPT: make ci-mingw-subset-2
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             os: windows-latest-xl
           - name: x86_64-mingw-1
             env:
               SCRIPT: make ci-mingw-subset-1
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-profiler --set llvm.allow-old-toolchain"
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             os: windows-latest-xl
           - name: x86_64-mingw-2
             env:
               SCRIPT: make ci-mingw-subset-2
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-profiler --set llvm.allow-old-toolchain"
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             os: windows-latest-xl
           - name: dist-x86_64-msvc
@@ -433,6 +437,7 @@ jobs:
           - name: dist-i686-mingw
             env:
               RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --enable-full-tools --enable-profiler --set llvm.allow-old-toolchain"
+              NO_DOWNLOAD_CI_LLVM: 1
               SCRIPT: python x.py dist
               CUSTOM_MINGW: 1
               DIST_REQUIRE_ALL_TOOLS: 1
@@ -441,6 +446,7 @@ jobs:
             env:
               SCRIPT: python x.py dist
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler --set llvm.allow-old-toolchain"
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
               DIST_REQUIRE_ALL_TOOLS: 1
             os: windows-latest-xl
diff --git a/.reuse/dep5 b/.reuse/dep5
new file mode 100644
index 00000000000..e040f73b9e1
--- /dev/null
+++ b/.reuse/dep5
@@ -0,0 +1,28 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Files-Excluded:
+ src/llvm-project
+
+Files: *
+Copyright: The Rust Project Developers (see https://thanks.rust-lang.org)
+License: MIT or Apache-2.0
+
+Files: library/std/src/sync/mpsc/mpsc_queue.rs
+       library/std/src/sync/mpsc/spsc_queue.rs
+Copyright: 2010-2011 Dmitry Vyukov
+License: BSD-2-Clause
+
+Files: src/librustdoc/html/static/fonts/FiraSans*
+Copyright: 2014, Mozilla Foundation, 2014, Telefonica S.A.
+License: OFL-1.1
+
+Files: src/librustdoc/html/static/fonts/NanumBarun*
+Copyright: 2010 NAVER Corporation
+License: OFL-1.1
+
+Files: src/librustdoc/html/static/fonts/SourceCodePro*
+Copyright: 2010, 2012 Adobe Systems Incorporated
+License: OFL-1.1
+
+Files: src/librustdoc/html/static/fonts/SourceSerif4*
+Copyright: 2014-2021 Adobe Systems Incorporated
+License: OFL-1.1
diff --git a/Cargo.lock b/Cargo.lock
index 395f5a127bd..3a35985836c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -321,7 +321,7 @@ dependencies = [
 
 [[package]]
 name = "cargo"
-version = "0.65.0"
+version = "0.66.0"
 dependencies = [
  "anyhow",
  "atty",
@@ -1421,9 +1421,9 @@ dependencies = [
 
 [[package]]
 name = "fortanix-sgx-abi"
-version = "0.3.3"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6"
+checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
 dependencies = [
  "compiler_builtins",
  "rustc-std-workspace-core",
@@ -2415,9 +2415,9 @@ dependencies = [
 
 [[package]]
 name = "minifier"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac96d1e7a65f206443f95afff6de8f1690c77c97d6fc9c9bb2d2cd0662e9ff9f"
+checksum = "8eb022374af2f446981254e6bf9efb6e2c9e1a53176d395fca02792fd4435729"
 
 [[package]]
 name = "minimal-lexical"
@@ -4011,6 +4011,7 @@ dependencies = [
  "rustc_hir",
  "rustc_incremental",
  "rustc_lint",
+ "rustc_macros",
  "rustc_metadata",
  "rustc_middle",
  "rustc_mir_build",
@@ -4359,6 +4360,7 @@ dependencies = [
  "rustc_serialize",
  "rustc_session",
  "rustc_span",
+ "rustc_target",
  "tracing",
 ]
 
diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt
new file mode 100644
index 00000000000..137069b8238
--- /dev/null
+++ b/LICENSES/Apache-2.0.txt
@@ -0,0 +1,73 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+     (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+     (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+     (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+     (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+     You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!)  The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/LICENSES/BSD-2-Clause.txt b/LICENSES/BSD-2-Clause.txt
new file mode 100644
index 00000000000..5f662b354cd
--- /dev/null
+++ b/LICENSES/BSD-2-Clause.txt
@@ -0,0 +1,9 @@
+Copyright (c) <year> <owner> 
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt
new file mode 100644
index 00000000000..2071b23b0e0
--- /dev/null
+++ b/LICENSES/MIT.txt
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) <year> <copyright holders>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/LICENSES/OFL-1.1.txt b/LICENSES/OFL-1.1.txt
new file mode 100644
index 00000000000..6fe84ee21eb
--- /dev/null
+++ b/LICENSES/OFL-1.1.txt
@@ -0,0 +1,43 @@
+SIL OPEN FONT LICENSE
+
+Version 1.1 - 26 February 2007
+
+PREAMBLE
+
+The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+
+"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting, or substituting — in part or in whole — any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
+
+5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
+
+TERMINATION
+
+This license becomes null and void if any of the above conditions are not met.
+
+DISCLAIMER
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/compiler/rustc_apfloat/src/lib.rs b/compiler/rustc_apfloat/src/lib.rs
index cfc3d5b15a6..dde368e7b92 100644
--- a/compiler/rustc_apfloat/src/lib.rs
+++ b/compiler/rustc_apfloat/src/lib.rs
@@ -33,6 +33,8 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![no_std]
 #![forbid(unsafe_code)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate alloc;
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index 6529f11100d..98faacdc1fb 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -19,6 +19,8 @@
 #![feature(rustc_attrs)]
 #![cfg_attr(test, feature(test))]
 #![feature(strict_provenance)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 use smallvec::SmallVec;
 
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 3a55396248e..d5180b46aaf 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -497,7 +497,6 @@ pub struct WhereRegionPredicate {
 /// E.g., `T = int`.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WhereEqPredicate {
-    pub id: NodeId,
     pub span: Span,
     pub lhs_ty: P<Ty>,
     pub rhs_ty: P<Ty>,
@@ -771,7 +770,7 @@ pub enum PatKind {
     Paren(P<Pat>),
 
     /// A macro pattern; pre-expansion.
-    MacCall(MacCall),
+    MacCall(P<MacCall>),
 }
 
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
@@ -981,7 +980,7 @@ pub enum StmtKind {
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct MacCallStmt {
-    pub mac: MacCall,
+    pub mac: P<MacCall>,
     pub style: MacStmtStyle,
     pub attrs: AttrVec,
     pub tokens: Option<LazyTokenStream>,
@@ -1438,7 +1437,7 @@ pub enum ExprKind {
     InlineAsm(P<InlineAsm>),
 
     /// A macro invocation; pre-expansion.
-    MacCall(MacCall),
+    MacCall(P<MacCall>),
 
     /// A struct literal expression.
     ///
@@ -1690,7 +1689,7 @@ pub enum StrStyle {
 #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct Lit {
     /// The original literal token as written in source code.
-    pub token: token::Lit,
+    pub token_lit: token::Lit,
     /// The "semantic" representation of the literal lowered from the original tokens.
     /// Strings are unescaped, hexadecimal forms are eliminated, etc.
     /// FIXME: Remove this and only create the semantic representation during lowering to HIR.
@@ -1718,7 +1717,7 @@ impl StrLit {
             StrStyle::Raw(n) => token::StrRaw(n),
         };
         Lit {
-            token: token::Lit::new(token_kind, self.symbol, self.suffix),
+            token_lit: token::Lit::new(token_kind, self.symbol, self.suffix),
             span: self.span,
             kind: LitKind::Str(self.symbol_unescaped, self.style),
         }
@@ -2041,7 +2040,7 @@ pub enum TyKind {
     /// Inferred type of a `self` or `&self` argument in a method.
     ImplicitSelf,
     /// A macro in the type position.
-    MacCall(MacCall),
+    MacCall(P<MacCall>),
     /// Placeholder for a kind that has failed to be defined.
     Err,
     /// Placeholder for a `va_list`.
@@ -2878,7 +2877,7 @@ pub enum ItemKind {
     /// A macro invocation.
     ///
     /// E.g., `foo!(..)`.
-    MacCall(MacCall),
+    MacCall(P<MacCall>),
 
     /// A macro definition.
     MacroDef(MacroDef),
@@ -2952,7 +2951,7 @@ pub enum AssocItemKind {
     /// An associated type.
     TyAlias(Box<TyAlias>),
     /// A macro expanding to associated items.
-    MacCall(MacCall),
+    MacCall(P<MacCall>),
 }
 
 impl AssocItemKind {
@@ -3001,7 +3000,7 @@ pub enum ForeignItemKind {
     /// An foreign type.
     TyAlias(Box<TyAlias>),
     /// A macro expanding to foreign items.
-    MacCall(MacCall),
+    MacCall(P<MacCall>),
 }
 
 impl From<ForeignItemKind> for ItemKind {
@@ -3037,23 +3036,28 @@ mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
     // These are in alphabetical order, which is easy to maintain.
-    static_assert_size!(AssocItem, 160);
-    static_assert_size!(AssocItemKind, 72);
+    static_assert_size!(AssocItem, 120);
+    static_assert_size!(AssocItemKind, 32);
     static_assert_size!(Attribute, 32);
     static_assert_size!(Block, 48);
     static_assert_size!(Expr, 104);
+    static_assert_size!(ExprKind, 72);
     static_assert_size!(Fn, 192);
-    static_assert_size!(ForeignItem, 160);
-    static_assert_size!(ForeignItemKind, 72);
+    static_assert_size!(ForeignItem, 112);
+    static_assert_size!(ForeignItemKind, 24);
     static_assert_size!(GenericBound, 88);
     static_assert_size!(Generics, 72);
     static_assert_size!(Impl, 200);
     static_assert_size!(Item, 200);
     static_assert_size!(ItemKind, 112);
     static_assert_size!(Lit, 48);
+    static_assert_size!(LitKind, 24);
     static_assert_size!(Pat, 120);
+    static_assert_size!(PatKind, 96);
     static_assert_size!(Path, 40);
     static_assert_size!(PathSegment, 24);
     static_assert_size!(Stmt, 32);
+    static_assert_size!(StmtKind, 16);
     static_assert_size!(Ty, 96);
+    static_assert_size!(TyKind, 72);
 }
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index bc4f183d9b1..0d114f1366c 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -184,13 +184,7 @@ impl MetaItem {
     }
 
     pub fn value_str(&self) -> Option<Symbol> {
-        match self.kind {
-            MetaItemKind::NameValue(ref v) => match v.kind {
-                LitKind::Str(ref s, _) => Some(*s),
-                _ => None,
-            },
-            _ => None,
-        }
+        self.kind.value_str()
     }
 
     pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 528fc4816e9..2426a0cb7dd 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -19,6 +19,8 @@
 #![feature(slice_internals)]
 #![feature(stmt_expr_attributes)]
 #![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 54e2f7557e5..0520319e3be 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -935,8 +935,7 @@ pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis:
             visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
         }
         WherePredicate::EqPredicate(ep) => {
-            let WhereEqPredicate { id, span, lhs_ty, rhs_ty } = ep;
-            vis.visit_id(id);
+            let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep;
             vis.visit_span(span);
             vis.visit_ty(lhs_ty);
             vis.visit_ty(rhs_ty);
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 9c18f55c03b..e6351d89c6c 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -23,7 +23,7 @@ pub enum LitError {
 
 impl LitKind {
     /// Converts literal token into a semantic literal.
-    pub fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
+    pub fn from_token_lit(lit: token::Lit) -> Result<LitKind, LitError> {
         let token::Lit { kind, symbol, suffix } = lit;
         if suffix.is_some() && !kind.may_have_suffix() {
             return Err(LitError::InvalidSuffix);
@@ -153,7 +153,7 @@ impl LitKind {
     /// Attempts to recover a token from semantic literal.
     /// This function is used when the original token doesn't exist (e.g. the literal is created
     /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
-    pub fn to_lit_token(&self) -> token::Lit {
+    pub fn to_token_lit(&self) -> token::Lit {
         let (kind, symbol, suffix) = match *self {
             LitKind::Str(symbol, ast::StrStyle::Cooked) => {
                 // Don't re-intern unless the escaped string is different.
@@ -208,8 +208,8 @@ impl LitKind {
 
 impl Lit {
     /// Converts literal token into an AST literal.
-    pub fn from_lit_token(token: token::Lit, span: Span) -> Result<Lit, LitError> {
-        Ok(Lit { token, kind: LitKind::from_lit_token(token)?, span })
+    pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<Lit, LitError> {
+        Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
     }
 
     /// Converts arbitrary token into an AST literal.
@@ -232,21 +232,21 @@ impl Lit {
             _ => return Err(LitError::NotLiteral),
         };
 
-        Lit::from_lit_token(lit, token.span)
+        Lit::from_token_lit(lit, token.span)
     }
 
     /// Attempts to recover an AST literal from semantic literal.
     /// This function is used when the original token doesn't exist (e.g. the literal is created
     /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
     pub fn from_lit_kind(kind: LitKind, span: Span) -> Lit {
-        Lit { token: kind.to_lit_token(), kind, span }
+        Lit { token_lit: kind.to_token_lit(), kind, span }
     }
 
     /// Losslessly convert an AST literal into a token.
     pub fn to_token(&self) -> Token {
-        let kind = match self.token.kind {
-            token::Bool => token::Ident(self.token.symbol, false),
-            _ => token::Literal(self.token),
+        let kind = match self.token_lit.kind {
+            token::Bool => token::Ident(self.token_lit.symbol, false),
+            _ => token::Literal(self.token_lit),
         };
         Token::new(kind, self.span)
     }
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index ee4c0036f76..0f1bab24f96 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1498,9 +1498,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ),
                 in_where_clause: true,
             }),
-            WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
+            WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span }) => {
                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                    hir_id: self.lower_node_id(id),
                     lhs_ty: self
                         .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
                     rhs_ty: self
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5f5667ce905..1ac1d689efb 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -927,7 +927,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     lit.clone()
                 } else {
                     Lit {
-                        token: token::Lit::new(token::LitKind::Err, kw::Empty, None),
+                        token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
                         kind: LitKind::Err(kw::Empty),
                         span: DUMMY_SP,
                     }
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 97eee56f948..68fca081018 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -2,10 +2,10 @@ use rustc_ast as ast;
 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
 use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
 use rustc_ast::{PatKind, RangeEnd, VariantData};
-use rustc_errors::{struct_span_err, Applicability};
+use rustc_errors::{struct_span_err, Applicability, StashKey};
+use rustc_feature::Features;
 use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
-use rustc_feature::{Features, GateIssue};
-use rustc_session::parse::{feature_err, feature_err_issue};
+use rustc_session::parse::{feature_err, feature_warn};
 use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
@@ -20,9 +20,7 @@ macro_rules! gate_feature_fn {
         let has_feature: bool = has_feature(visitor.features);
         debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
         if !has_feature && !span.allows_unstable($name) {
-            feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
-                .help(help)
-                .emit();
+            feature_err(&visitor.sess.parse_sess, name, span, explain).help(help).emit();
         }
     }};
     ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
@@ -31,8 +29,19 @@ macro_rules! gate_feature_fn {
         let has_feature: bool = has_feature(visitor.features);
         debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
         if !has_feature && !span.allows_unstable($name) {
-            feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
-                .emit();
+            feature_err(&visitor.sess.parse_sess, name, span, explain).emit();
+        }
+    }};
+    (future_incompatible; $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
+        let (visitor, has_feature, span, name, explain) =
+            (&*$visitor, $has_feature, $span, $name, $explain);
+        let has_feature: bool = has_feature(visitor.features);
+        debug!(
+            "gate_feature(feature = {:?}, span = {:?}); has? {} (future_incompatible)",
+            name, span, has_feature
+        );
+        if !has_feature && !span.allows_unstable($name) {
+            feature_warn(&visitor.sess.parse_sess, name, span, explain);
         }
     }};
 }
@@ -44,6 +53,9 @@ macro_rules! gate_feature_post {
     ($visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
         gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
     };
+    (future_incompatible; $visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
+        gate_feature_fn!(future_incompatible; $visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
+    };
 }
 
 pub fn check_attribute(attr: &ast::Attribute, sess: &Session, features: &Features) {
@@ -588,11 +600,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         {
             // When we encounter a statement of the form `foo: Ty = val;`, this will emit a type
             // ascription error, but the likely intention was to write a `let` statement. (#78907).
-            feature_err_issue(
+            feature_err(
                 &self.sess.parse_sess,
                 sym::type_ascription,
                 lhs.span,
-                GateIssue::Language,
                 "type ascription is experimental",
             ).span_suggestion_verbose(
                 lhs.span.shrink_to_lo(),
@@ -615,15 +626,22 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 );
             }
             ast::ExprKind::Type(..) => {
-                // To avoid noise about type ascription in common syntax errors, only emit if it
-                // is the *only* error.
                 if self.sess.parse_sess.span_diagnostic.err_count() == 0 {
+                    // To avoid noise about type ascription in common syntax errors,
+                    // only emit if it is the *only* error.
                     gate_feature_post!(
                         &self,
                         type_ascription,
                         e.span,
                         "type ascription is experimental"
                     );
+                } else {
+                    // And if it isn't, cancel the early-pass warning.
+                    self.sess
+                        .parse_sess
+                        .span_diagnostic
+                        .steal_diagnostic(e.span, StashKey::EarlySyntaxWarning)
+                        .map(|err| err.cancel());
                 }
             }
             ast::ExprKind::TryBlock(_) => {
@@ -789,14 +807,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
 
     // All uses of `gate_all!` below this point were added in #65742,
     // and subsequently disabled (with the non-early gating readded).
+    // We emit an early future-incompatible warning for these.
+    // New syntax gates should go above here to get a hard error gate.
     macro_rules! gate_all {
         ($gate:ident, $msg:literal) => {
-            // FIXME(eddyb) do something more useful than always
-            // disabling these uses of early feature-gatings.
-            if false {
-                for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
-                    gate_feature_post!(&visitor, $gate, *span, $msg);
-                }
+            for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
+                gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg);
             }
         };
     }
@@ -809,11 +825,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
     gate_all!(try_blocks, "`try` blocks are unstable");
     gate_all!(label_break_value, "labels on blocks are unstable");
     gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
-    // To avoid noise about type ascription in common syntax errors,
-    // only emit if it is the *only* error. (Also check it last.)
-    if sess.parse_sess.span_diagnostic.err_count() == 0 {
-        gate_all!(type_ascription, "type ascription is experimental");
-    }
+    gate_all!(type_ascription, "type ascription is experimental");
 
     visit::walk_crate(&mut visitor, krate);
 }
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 79178830bf9..bf094af5f7b 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -1,3 +1,5 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
 #![feature(with_negative_coherence)]
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index c454034efa7..8749a13c5dd 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -372,7 +372,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
 
     fn print_literal(&mut self, lit: &ast::Lit) {
         self.maybe_print_comment(lit.span.lo());
-        self.word(lit.token.to_string())
+        self.word(lit.token_lit.to_string())
     }
 
     fn print_string(&mut self, st: &str, style: ast::StrStyle) {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 098e8de9420..683084cf09d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1086,14 +1086,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             ),
                         );
                     }
-                    if is_option_or_result && maybe_reinitialized_locations_is_empty {
-                        err.span_suggestion_verbose(
-                            fn_call_span.shrink_to_lo(),
-                            "consider calling `.as_ref()` to borrow the type's contents",
-                            "as_ref().",
-                            Applicability::MachineApplicable,
-                        );
-                    }
                     // Avoid pointing to the same function in multiple different
                     // error messages.
                     if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
@@ -1102,6 +1094,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             &format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
                         );
                     }
+                    if is_option_or_result && maybe_reinitialized_locations_is_empty {
+                        err.span_label(
+                            var_span,
+                            "help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents",
+                        );
+                    }
                 }
                 // Other desugarings takes &self, which cannot cause a move
                 _ => {}
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 895723d44ff..8c9676e4bfa 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -3,7 +3,7 @@ use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
 #[derive(SessionDiagnostic)]
-#[error(borrowck::move_unsized, code = "E0161")]
+#[diag(borrowck::move_unsized, code = "E0161")]
 pub(crate) struct MoveUnsized<'tcx> {
     pub ty: Ty<'tcx>,
     #[primary_span]
@@ -12,7 +12,7 @@ pub(crate) struct MoveUnsized<'tcx> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(borrowck::higher_ranked_lifetime_error)]
+#[diag(borrowck::higher_ranked_lifetime_error)]
 pub(crate) struct HigherRankedLifetimeError {
     #[subdiagnostic]
     pub cause: Option<HigherRankedErrorCause>,
@@ -29,14 +29,14 @@ pub(crate) enum HigherRankedErrorCause {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(borrowck::higher_ranked_subtype_error)]
+#[diag(borrowck::higher_ranked_subtype_error)]
 pub(crate) struct HigherRankedSubtypeError {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(borrowck::generic_does_not_live_long_enough)]
+#[diag(borrowck::generic_does_not_live_long_enough)]
 pub(crate) struct GenericDoesNotLiveLongEnough {
     pub kind: String,
     #[primary_span]
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 925c36edb51..119724b5049 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -52,7 +52,7 @@ pub fn expand_assert<'cx>(
     let expr = if let Some(tokens) = custom_message {
         let then = cx.expr(
             call_site_span,
-            ExprKind::MacCall(MacCall {
+            ExprKind::MacCall(P(MacCall {
                 path: panic_path(),
                 args: P(MacArgs::Delimited(
                     DelimSpan::from_single(call_site_span),
@@ -60,7 +60,7 @@ pub fn expand_assert<'cx>(
                     tokens,
                 )),
                 prior_type_ascription: None,
-            }),
+            })),
         );
         expr_if_not(cx, call_site_span, cond_expr, then, None)
     }
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index c04d04020cc..d30fd479015 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -177,7 +177,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
         });
         self.cx.expr(
             self.span,
-            ExprKind::MacCall(MacCall {
+            ExprKind::MacCall(P(MacCall {
                 path: panic_path,
                 args: P(MacArgs::Delimited(
                     DelimSpan::from_single(self.span),
@@ -185,7 +185,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
                     initial.into_iter().chain(captures).collect::<TokenStream>(),
                 )),
                 prior_type_ascription: None,
-            }),
+            })),
         )
     }
 
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index aa355150b4f..9046bf13059 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -36,7 +36,7 @@ pub fn expand_cfg(
 }
 
 #[derive(SessionDiagnostic)]
-#[error(builtin_macros::requires_cfg_pattern)]
+#[diag(builtin_macros::requires_cfg_pattern)]
 struct RequiresCfgPattern {
     #[primary_span]
     #[label]
@@ -44,7 +44,7 @@ struct RequiresCfgPattern {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(builtin_macros::expected_one_cfg_pattern)]
+#[diag(builtin_macros::expected_one_cfg_pattern)]
 struct OneCfgPattern {
     #[primary_span]
     span: Span,
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index a1afec410c1..c0f35d122f8 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -1,6 +1,5 @@
 use rustc_ast as ast;
 use rustc_ast::{ptr::P, tokenstream::TokenStream};
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::Applicability;
 use rustc_expand::base::{self, DummyResult};
 
@@ -185,5 +184,5 @@ pub fn expand_concat_bytes(
         return base::MacEager::expr(DummyResult::raw_expr(sp, true));
     }
     let sp = cx.with_def_site_ctxt(sp);
-    base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(accumulator))))
+    base::MacEager::expr(cx.expr_byte_str(sp, accumulator))
 }
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index d3de10ca4a2..467ac34ded9 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -126,9 +126,9 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
 }
 
 fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
-    let help_msg = match lit.token.kind {
-        token::Str if rustc_lexer::is_ident(lit.token.symbol.as_str()) => {
-            format!("try using `#[derive({})]`", lit.token.symbol)
+    let help_msg = match lit.token_lit.kind {
+        token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => {
+            format!("try using `#[derive({})]`", lit.token_lit.symbol)
         }
         _ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
     };
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 5ef68c6aeaa..77e0b6c55a8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -15,7 +15,6 @@ pub fn expand_deriving_copy(
 ) {
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: path_std!(marker::Copy),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index 7755ff779c4..ee4c5aea1a3 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -71,7 +71,6 @@ pub fn expand_deriving_clone(
     let attrs = vec![cx.attribute(inline)];
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: path_std!(clone::Clone),
         additional_bounds: bounds,
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 4e798bf6acb..f99ee8cb2d5 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -23,7 +23,6 @@ pub fn expand_deriving_eq(
     let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: path_std!(cmp::Eq),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 1612be86237..8aa16dfeb0f 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -18,7 +18,6 @@ pub fn expand_deriving_ord(
     let attrs = vec![cx.attribute(inline)];
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: path_std!(cmp::Ord),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 0141b337726..6f86092ba49 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -15,14 +15,8 @@ pub fn expand_deriving_partial_eq(
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
 ) {
-    fn cs_op(
-        cx: &mut ExtCtxt<'_>,
-        span: Span,
-        substr: &Substructure<'_>,
-        op: BinOpKind,
-        combiner: BinOpKind,
-        base: bool,
-    ) -> BlockOrExpr {
+    fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
+        let base = true;
         let expr = cs_fold(
             true, // use foldl
             cx,
@@ -47,39 +41,22 @@ pub fn expand_deriving_partial_eq(
                             cx.expr_deref(field.span, expr.clone())
                         }
                     };
-                    cx.expr_binary(field.span, op, convert(&field.self_expr), convert(other_expr))
+                    cx.expr_binary(
+                        field.span,
+                        BinOpKind::Eq,
+                        convert(&field.self_expr),
+                        convert(other_expr),
+                    )
+                }
+                CsFold::Combine(span, expr1, expr2) => {
+                    cx.expr_binary(span, BinOpKind::And, expr1, expr2)
                 }
-                CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2),
                 CsFold::Fieldless => cx.expr_bool(span, base),
             },
         );
         BlockOrExpr::new_expr(expr)
     }
 
-    fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
-        cs_op(cx, span, substr, BinOpKind::Eq, BinOpKind::And, true)
-    }
-    fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
-        cs_op(cx, span, substr, BinOpKind::Ne, BinOpKind::Or, false)
-    }
-
-    macro_rules! md {
-        ($name:expr, $f:ident) => {{
-            let inline = cx.meta_word(span, sym::inline);
-            let attrs = vec![cx.attribute(inline)];
-            MethodDef {
-                name: $name,
-                generics: Bounds::empty(),
-                explicit_self: true,
-                nonself_args: vec![(self_ref(), sym::other)],
-                ret_ty: Path(path_local!(bool)),
-                attributes: attrs,
-                unify_fieldless_variants: true,
-                combine_substructure: combine_substructure(Box::new(|a, b, c| $f(a, b, c))),
-            }
-        }};
-    }
-
     super::inject_impl_of_structural_trait(
         cx,
         span,
@@ -88,17 +65,23 @@ pub fn expand_deriving_partial_eq(
         push,
     );
 
-    // avoid defining `ne` if we can
-    // c-like enums, enums without any fields and structs without fields
-    // can safely define only `eq`.
-    let mut methods = vec![md!(sym::eq, cs_eq)];
-    if !is_type_without_fields(item) {
-        methods.push(md!(sym::ne, cs_ne));
-    }
+    // No need to generate `ne`, the default suffices, and not generating it is
+    // faster.
+    let inline = cx.meta_word(span, sym::inline);
+    let attrs = vec![cx.attribute(inline)];
+    let methods = vec![MethodDef {
+        name: sym::eq,
+        generics: Bounds::empty(),
+        explicit_self: true,
+        nonself_args: vec![(self_ref(), sym::other)],
+        ret_ty: Path(path_local!(bool)),
+        attributes: attrs,
+        unify_fieldless_variants: true,
+        combine_substructure: combine_substructure(Box::new(|a, b, c| cs_eq(a, b, c))),
+    }];
 
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: path_std!(cmp::PartialEq),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 2ebb01cc8a0..137c779f81b 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -36,7 +36,6 @@ pub fn expand_deriving_partial_ord(
 
     let trait_def = TraitDef {
         span,
-        attributes: vec![],
         path: path_std!(cmp::PartialOrd),
         additional_bounds: vec![],
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index ceef893e862..f82175af4f6 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -19,7 +19,6 @@ pub fn expand_deriving_debug(
 
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: path_std!(fmt::Debug),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
@@ -52,7 +51,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
 
     // We want to make sure we have the ctxt set so that we can use unstable methods
     let span = cx.with_def_site_ctxt(span);
-    let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
+    let name = cx.expr_str(span, ident.name);
     let fmt = substr.nonselflike_args[0].clone();
 
     // Struct and tuples are similar enough that we use the same code for both,
@@ -89,10 +88,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         for i in 0..fields.len() {
             let field = &fields[i];
             if is_struct {
-                let name = cx.expr_lit(
-                    field.span,
-                    ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
-                );
+                let name = cx.expr_str(field.span, field.name.unwrap().name);
                 args.push(name);
             }
             // Use an extra indirection to make sure this works for unsized types.
@@ -108,10 +104,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
 
         for field in fields {
             if is_struct {
-                name_exprs.push(cx.expr_lit(
-                    field.span,
-                    ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
-                ));
+                name_exprs.push(cx.expr_str(field.span, field.name.unwrap().name));
             }
 
             // Use an extra indirection to make sure this works for unsized types.
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index d688143a2a5..47da0862b52 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -22,7 +22,6 @@ pub fn expand_deriving_rustc_decodable(
 
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 5177690917f..a431832080c 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -25,7 +25,6 @@ pub fn expand_deriving_default(
     let attrs = vec![cx.attribute(inline)];
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: Path::new(vec![kw::Default, sym::Default]),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index 70167cac68a..d43c66a5fa6 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -106,7 +106,6 @@ pub fn expand_deriving_rustc_encodable(
 
     let trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index ef64f52d40b..a39b97d07ef 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -184,8 +184,6 @@ pub struct TraitDef<'a> {
     /// The span for the current #[derive(Foo)] header.
     pub span: Span,
 
-    pub attributes: Vec<ast::Attribute>,
-
     /// Path of the trait, including any type parameters
     pub path: Path,
 
@@ -605,7 +603,7 @@ impl<'a> TraitDef<'a> {
                         param.bounds.iter().cloned()
                     ).collect();
 
-                cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, vec![], bounds, None)
+                cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None)
             }
             GenericParamKind::Const { ty, kw_span, .. } => {
                 let const_nodefault_kind = GenericParamKind::Const {
@@ -640,11 +638,7 @@ impl<'a> TraitDef<'a> {
                 }
                 ast::WherePredicate::EqPredicate(we) => {
                     let span = we.span.with_ctxt(ctxt);
-                    ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
-                        id: ast::DUMMY_NODE_ID,
-                        span,
-                        ..we.clone()
-                    })
+                    ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { span, ..we.clone() })
                 }
             }
         }));
@@ -722,15 +716,13 @@ impl<'a> TraitDef<'a> {
         let self_type = cx.ty_path(path);
 
         let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
+        let attrs = vec![attr];
         let opt_trait_ref = Some(trait_ref);
 
-        let mut a = vec![attr];
-        a.extend(self.attributes.iter().cloned());
-
         cx.item(
             self.span,
             Ident::empty(),
-            a,
+            attrs,
             ast::ItemKind::Impl(Box::new(ast::Impl {
                 unsafety: ast::Unsafe::No,
                 polarity: ast::ImplPolarity::Positive,
@@ -1633,19 +1625,3 @@ where
         StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
     }
 }
-
-/// Returns `true` if the type has no value fields
-/// (for an enum, no variant has any fields)
-pub fn is_type_without_fields(item: &Annotatable) -> bool {
-    if let Annotatable::Item(ref item) = *item {
-        match item.kind {
-            ast::ItemKind::Enum(ref enum_def, _) => {
-                enum_def.variants.iter().all(|v| v.data.fields().is_empty())
-            }
-            ast::ItemKind::Struct(ref variant_data, _) => variant_data.fields().is_empty(),
-            _ => false,
-        }
-    } else {
-        false
-    }
-}
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 4d46f7cd48a..36e2e293086 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -146,7 +146,6 @@ fn mk_ty_param(
     cx: &ExtCtxt<'_>,
     span: Span,
     name: Symbol,
-    attrs: &[ast::Attribute],
     bounds: &[Path],
     self_ident: Ident,
     self_generics: &Generics,
@@ -158,7 +157,7 @@ fn mk_ty_param(
             cx.trait_bound(path)
         })
         .collect();
-    cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
+    cx.typaram(span, Ident::new(name, span), bounds, None)
 }
 
 /// Bounds on type parameters.
@@ -183,7 +182,7 @@ impl Bounds {
             .iter()
             .map(|t| {
                 let (name, ref bounds) = *t;
-                mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
+                mk_ty_param(cx, span, name, &bounds, self_ty, self_generics)
             })
             .collect();
 
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 32ae3d34478..9aa170bec14 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -21,7 +21,6 @@ pub fn expand_deriving_hash(
     let arg = Path::new_local(typaram);
     let hash_trait_def = TraitDef {
         span,
-        attributes: Vec::new(),
         path,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs
index ea0e768a58f..3f1a8b3bc2c 100644
--- a/compiler/rustc_builtin_macros/src/edition_panic.rs
+++ b/compiler/rustc_builtin_macros/src/edition_panic.rs
@@ -48,7 +48,7 @@ fn expand<'cx>(
     MacEager::expr(
         cx.expr(
             sp,
-            ExprKind::MacCall(MacCall {
+            ExprKind::MacCall(P(MacCall {
                 path: Path {
                     span: sp,
                     segments: cx
@@ -64,7 +64,7 @@ fn expand<'cx>(
                     tts,
                 )),
                 prior_type_ascription: None,
-            }),
+            })),
         ),
     )
 }
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 53c13873b10..08026c9d357 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -923,7 +923,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 }
 
                 // Build the format
-                let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill));
+                let fill = self.ecx.expr_char(sp, fill);
                 let align = |name| {
                     let mut p = Context::rtpath(self.ecx, sym::Alignment);
                     p.push(Ident::new(name, sp));
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 8bf3a0799b6..d78bbc3c932 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -216,7 +216,7 @@ pub fn expand_include_bytes(
         }
     };
     match cx.source_map().load_binary_file(&file) {
-        Ok(bytes) => base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(bytes.into()))),
+        Ok(bytes) => base::MacEager::expr(cx.expr_byte_str(sp, bytes)),
         Err(e) => {
             cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
             DummyResult::any(sp)
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index 052ca0a082b..dd9d891ddbd 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -29,6 +29,7 @@ pub(crate) fn unsized_info<'tcx>(
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
             if data_a.principal_def_id() == data_b.principal_def_id() {
+                // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
                 return old_info;
             }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index dbd55590e5c..2930d09d71f 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::profiling::TimingGuard;
 use rustc_data_structures::profiling::VerboseTimingGuard;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::Emitter;
-use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
+use rustc_errors::{translation::Translate, DiagnosticId, FatalError, Handler, Level};
 use rustc_fs_util::link_or_copy;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_incremental::{
@@ -1740,6 +1740,16 @@ impl SharedEmitter {
     }
 }
 
+impl Translate for SharedEmitter {
+    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+        None
+    }
+
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+        panic!("shared emitter attempted to translate a diagnostic");
+    }
+}
+
 impl Emitter for SharedEmitter {
     fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
         let fluent_args = self.to_fluent_args(diag.args());
@@ -1761,14 +1771,6 @@ impl Emitter for SharedEmitter {
     fn source_map(&self) -> Option<&Lrc<SourceMap>> {
         None
     }
-
-    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
-        None
-    }
-
-    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
-        panic!("shared emitter attempted to translate a diagnostic");
-    }
 }
 
 impl SharedEmitterMain {
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index a840b270974..4c6be3f9108 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -151,6 +151,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
             if data_a.principal_def_id() == data_b.principal_def_id() {
+                // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
                 return old_info;
             }
 
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index a463fe7b970..01619dee0e4 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -3,7 +3,7 @@ use rustc_macros::SessionDiagnostic;
 use rustc_span::Span;
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::unstable_in_stable)]
+#[diag(const_eval::unstable_in_stable)]
 pub(crate) struct UnstableInStable {
     pub gate: String,
     #[primary_span]
@@ -22,14 +22,14 @@ pub(crate) struct UnstableInStable {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::thread_local_access, code = "E0625")]
+#[diag(const_eval::thread_local_access, code = "E0625")]
 pub(crate) struct NonConstOpErr {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::static_access, code = "E0013")]
+#[diag(const_eval::static_access, code = "E0013")]
 #[help]
 pub(crate) struct StaticAccessErr {
     #[primary_span]
@@ -41,7 +41,7 @@ pub(crate) struct StaticAccessErr {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::raw_ptr_to_int)]
+#[diag(const_eval::raw_ptr_to_int)]
 #[note]
 #[note(const_eval::note2)]
 pub(crate) struct RawPtrToIntErr {
@@ -50,7 +50,7 @@ pub(crate) struct RawPtrToIntErr {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::raw_ptr_comparison)]
+#[diag(const_eval::raw_ptr_comparison)]
 #[note]
 pub(crate) struct RawPtrComparisonErr {
     #[primary_span]
@@ -58,14 +58,14 @@ pub(crate) struct RawPtrComparisonErr {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::panic_non_str)]
+#[diag(const_eval::panic_non_str)]
 pub(crate) struct PanicNonStrErr {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::mut_deref, code = "E0658")]
+#[diag(const_eval::mut_deref, code = "E0658")]
 pub(crate) struct MutDerefErr {
     #[primary_span]
     pub span: Span,
@@ -73,7 +73,7 @@ pub(crate) struct MutDerefErr {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::transient_mut_borrow, code = "E0658")]
+#[diag(const_eval::transient_mut_borrow, code = "E0658")]
 pub(crate) struct TransientMutBorrowErr {
     #[primary_span]
     pub span: Span,
@@ -81,7 +81,7 @@ pub(crate) struct TransientMutBorrowErr {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(const_eval::transient_mut_borrow_raw, code = "E0658")]
+#[diag(const_eval::transient_mut_borrow_raw, code = "E0658")]
 pub(crate) struct TransientMutBorrowErrRaw {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index c97c31eb9da..14eb2a1537b 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -298,7 +298,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.write_immediate(val, dest)
             }
             (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
-                let (old_data, old_vptr) = self.read_immediate(src)?.to_scalar_pair()?;
+                let val = self.read_immediate(src)?;
+                if data_a.principal() == data_b.principal() {
+                    // A NOP cast that doesn't actually change anything, should be allowed even with mismatching vtables.
+                    return self.write_immediate(*val, dest);
+                }
+                let (old_data, old_vptr) = val.to_scalar_pair()?;
                 let old_vptr = old_vptr.to_pointer(self)?;
                 let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?;
                 if old_trait != data_a.principal() {
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index d563e35f910..c8557d172ed 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -534,7 +534,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                             let mut non_zst_field = None;
                             for i in 0..receiver.layout.fields.count() {
                                 let field = self.operand_field(&receiver, i)?;
-                                if !field.layout.is_zst() {
+                                let zst =
+                                    field.layout.is_zst() && field.layout.align.abi.bytes() == 1;
+                                if !zst {
                                     assert!(
                                         non_zst_field.is_none(),
                                         "multiple non-ZST fields in dyn receiver type {}",
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 33802261644..c9cfc1f3f46 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -1,6 +1,7 @@
 //! Concrete error types for all operations which may be invalid in a certain const context.
 
 use hir::def_id::LocalDefId;
+use hir::ConstContext;
 use rustc_errors::{
     error_code, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
 };
@@ -331,6 +332,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
             ccx.const_kind(),
         ));
 
+        if let ConstContext::Static(_) = ccx.const_kind() {
+            err.note("consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell");
+        }
+
         err
     }
 }
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 265f45b72d1..c8b09cffe01 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -28,6 +28,8 @@
 #![feature(vec_into_raw_parts)]
 #![allow(rustc::default_hash_types)]
 #![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 52952a7932d..258780ecaea 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -56,9 +56,7 @@ cfg_if! {
             pub fn new(v: T) -> Self {
                 Atomic(Cell::new(v))
             }
-        }
 
-        impl<T: Copy> Atomic<T> {
             #[inline]
             pub fn into_inner(self) -> T {
                 self.0.into_inner()
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index f2432f61653..bd424dd9d06 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -1,4 +1,6 @@
 #![deny(rustdoc::invalid_codeblock_attributes)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 //! This library is used to gather all error codes into one place,
 //! the goal being to make their maintenance easier.
 
diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_error_messages/locales/en-US/expand.ftl
index bdfa22e77eb..ee76a4f4500 100644
--- a/compiler/rustc_error_messages/locales/en-US/expand.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/expand.ftl
@@ -3,3 +3,20 @@ expand_explain_doc_comment_outer =
 
 expand_explain_doc_comment_inner =
     inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
+
+expand_expr_repeat_no_syntax_vars = 
+    attempted to repeat an expression containing no syntax variables matched as repeating at this depth
+
+expand_must_repeat_once = 
+    this must repeat at least once
+
+expand_count_repetition_misplaced =
+    `count` can not be placed inside the inner-most repetition
+
+expand_meta_var_expr_unrecognized_var =
+    variable `{$key}` is not recognized in meta-variable expression
+
+expand_var_still_repeating =
+    variable '{$ident}' is still repeating at this depth
+
+expand_meta_var_dif_seq_matchers = {$msg}
\ No newline at end of file
diff --git a/compiler/rustc_error_messages/locales/en-US/interface.ftl b/compiler/rustc_error_messages/locales/en-US/interface.ftl
new file mode 100644
index 00000000000..2c05abd8c09
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/interface.ftl
@@ -0,0 +1,6 @@
+interface_ferris_identifier =
+    Ferris cannot be used as an identifier
+    .suggestion = try using their name instead
+
+interface_emoji_identifier =
+    identifiers cannot contain emoji: `{$ident}`
diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl
index 7e583753618..2d378013dd0 100644
--- a/compiler/rustc_error_messages/locales/en-US/parser.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl
@@ -32,3 +32,12 @@ parser_incorrect_use_of_await =
 parser_in_in_typo =
     expected iterable, found keyword `in`
     .suggestion = remove the duplicated `in`
+
+parser_invalid_variable_declaration =
+    invalid variable declaration
+
+parser_switch_mut_let_order =
+    switch the order of `mut` and `let`
+parser_missing_let_before_mut = missing keyword
+parser_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
+parser_use_let_not_var = write `let` instead of `var` to introduce a new variable
diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
index 494b8f91393..272731d9914 100644
--- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
@@ -24,8 +24,8 @@ typeck_lifetimes_or_bounds_mismatch_on_trait =
     .generics_label = lifetimes in impl do not match this {$item_kind} in trait
 
 typeck_drop_impl_on_wrong_item =
-    the `Drop` trait may only be implemented for structs, enums, and unions
-    .label = must be a struct, enum, or union
+    the `Drop` trait may only be implemented for local structs, enums, and unions
+    .label = must be a struct, enum, or union in the current crate
 
 typeck_field_already_declared =
     field `{$field_name}` is already declared
@@ -123,3 +123,13 @@ typeck_manual_implementation =
     .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 typeck_substs_on_overridden_impl = could not resolve substs on overridden impl
+
+typeck_unused_extern_crate =
+    unused extern crate
+    .suggestion = remove it
+
+typeck_extern_crate_not_idiomatic =
+    `extern crate` is not idiomatic in the new edition
+    .suggestion = convert it to a `{$msg_code}`
+
+typeck_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 9e73a399809..ee978f04be2 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -1,6 +1,8 @@
 #![feature(once_cell)]
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 use fluent_bundle::FluentResource;
 use fluent_syntax::parser::ParserError;
@@ -34,6 +36,7 @@ fluent_messages! {
     builtin_macros => "../locales/en-US/builtin_macros.ftl",
     const_eval => "../locales/en-US/const_eval.ftl",
     expand => "../locales/en-US/expand.ftl",
+    interface => "../locales/en-US/interface.ftl",
     lint => "../locales/en-US/lint.ftl",
     parser => "../locales/en-US/parser.ftl",
     passes => "../locales/en-US/passes.ftl",
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 3df562c7eda..b32fc3c719b 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -7,6 +7,7 @@
 
 use crate::emitter::FileWithAnnotatedLines;
 use crate::snippet::Line;
+use crate::translation::Translate;
 use crate::{
     CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Emitter, FluentBundle,
     LazyFallbackBundle, Level, MultiSpan, Style, SubDiagnostic,
@@ -32,6 +33,16 @@ pub struct AnnotateSnippetEmitterWriter {
     macro_backtrace: bool,
 }
 
+impl Translate for AnnotateSnippetEmitterWriter {
+    fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
+        self.fluent_bundle.as_ref()
+    }
+
+    fn fallback_fluent_bundle(&self) -> &FluentBundle {
+        &**self.fallback_bundle
+    }
+}
+
 impl Emitter for AnnotateSnippetEmitterWriter {
     /// The entry point for the diagnostics generation
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
@@ -63,14 +74,6 @@ impl Emitter for AnnotateSnippetEmitterWriter {
         self.source_map.as_ref()
     }
 
-    fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
-        self.fluent_bundle.as_ref()
-    }
-
-    fn fallback_fluent_bundle(&self) -> &FluentBundle {
-        &**self.fallback_bundle
-    }
-
     fn should_show_explain(&self) -> bool {
         !self.short_message
     }
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 17e6c9e9575..356f9dfdb3b 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -8,7 +8,7 @@ use rustc_error_messages::FluentValue;
 use rustc_hir as hir;
 use rustc_lint_defs::{Applicability, LintExpectationId};
 use rustc_span::edition::LATEST_STABLE_EDITION;
-use rustc_span::symbol::{Ident, Symbol};
+use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
 use rustc_span::{edition::Edition, Span, DUMMY_SP};
 use std::borrow::Cow;
 use std::fmt;
@@ -87,6 +87,7 @@ into_diagnostic_arg_using_display!(
     hir::Target,
     Edition,
     Ident,
+    MacroRulesNormalizedIdent,
 );
 
 impl IntoDiagnosticArg for bool {
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 9e68ee282e6..61d767a1cc6 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -84,6 +84,13 @@ pub trait EmissionGuarantee: Sized {
     /// of `Self` without actually performing the emission.
     #[track_caller]
     fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self;
+
+    /// Creates a new `DiagnosticBuilder` that will return this type of guarantee.
+    #[track_caller]
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self>;
 }
 
 /// Private module for sealing the `IsError` helper trait.
@@ -166,6 +173,15 @@ impl EmissionGuarantee for ErrorGuaranteed {
             }
         }
     }
+
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self> {
+        DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(
+            handler, msg,
+        )
+    }
 }
 
 impl<'a> DiagnosticBuilder<'a, ()> {
@@ -208,6 +224,13 @@ impl EmissionGuarantee for () {
             DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
         }
     }
+
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self> {
+        DiagnosticBuilder::new(handler, Level::Warning(None), msg)
+    }
 }
 
 impl<'a> DiagnosticBuilder<'a, !> {
@@ -247,6 +270,13 @@ impl EmissionGuarantee for ! {
         // Then fatally error, returning `!`
         crate::FatalError.raise()
     }
+
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self> {
+        DiagnosticBuilder::new_fatal(handler, msg)
+    }
 }
 
 /// In general, the `DiagnosticBuilder` uses deref to allow access to
@@ -566,7 +596,7 @@ impl Drop for DiagnosticBuilderInner<'_> {
                         ),
                     ));
                     handler.emit_diagnostic(&mut self.diagnostic);
-                    panic!();
+                    panic!("error was constructed but not emitted");
                 }
             }
             // `.emit()` was previously called, or maybe we're during `.cancel()`.
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 753e2f07c04..6c1bfcb9919 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -14,10 +14,10 @@ use rustc_span::{FileLines, SourceFile, Span};
 
 use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString};
 use crate::styled_buffer::StyledBuffer;
+use crate::translation::Translate;
 use crate::{
-    CodeSuggestion, Diagnostic, DiagnosticArg, DiagnosticId, DiagnosticMessage, FluentBundle,
-    Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight,
-    SuggestionStyle,
+    CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, FluentBundle, Handler,
+    LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle,
 };
 
 use rustc_lint_defs::pluralize;
@@ -200,7 +200,7 @@ impl Margin {
 const ANONYMIZED_LINE_NUM: &str = "LL";
 
 /// Emitter trait for emitting errors.
-pub trait Emitter {
+pub trait Emitter: Translate {
     /// Emit a structured diagnostic.
     fn emit_diagnostic(&mut self, diag: &Diagnostic);
 
@@ -231,102 +231,6 @@ pub trait Emitter {
 
     fn source_map(&self) -> Option<&Lrc<SourceMap>>;
 
-    /// Return `FluentBundle` with localized diagnostics for the locale requested by the user. If no
-    /// language was requested by the user then this will be `None` and `fallback_fluent_bundle`
-    /// should be used.
-    fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>>;
-
-    /// Return `FluentBundle` with localized diagnostics for the default locale of the compiler.
-    /// Used when the user has not requested a specific language or when a localized diagnostic is
-    /// unavailable for the requested locale.
-    fn fallback_fluent_bundle(&self) -> &FluentBundle;
-
-    /// Convert diagnostic arguments (a rustc internal type that exists to implement
-    /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
-    ///
-    /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
-    /// passed around as a reference thereafter.
-    fn to_fluent_args<'arg>(&self, args: &[DiagnosticArg<'arg>]) -> FluentArgs<'arg> {
-        FromIterator::from_iter(args.to_vec().drain(..))
-    }
-
-    /// Convert `DiagnosticMessage`s to a string, performing translation if necessary.
-    fn translate_messages(
-        &self,
-        messages: &[(DiagnosticMessage, Style)],
-        args: &FluentArgs<'_>,
-    ) -> Cow<'_, str> {
-        Cow::Owned(
-            messages.iter().map(|(m, _)| self.translate_message(m, args)).collect::<String>(),
-        )
-    }
-
-    /// Convert a `DiagnosticMessage` to a string, performing translation if necessary.
-    fn translate_message<'a>(
-        &'a self,
-        message: &'a DiagnosticMessage,
-        args: &'a FluentArgs<'_>,
-    ) -> Cow<'_, str> {
-        trace!(?message, ?args);
-        let (identifier, attr) = match message {
-            DiagnosticMessage::Str(msg) => return Cow::Borrowed(&msg),
-            DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
-        };
-
-        let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
-            let message = bundle.get_message(&identifier)?;
-            let value = match attr {
-                Some(attr) => message.get_attribute(attr)?.value(),
-                None => message.value()?,
-            };
-            debug!(?message, ?value);
-
-            let mut errs = vec![];
-            let translated = bundle.format_pattern(value, Some(&args), &mut errs);
-            debug!(?translated, ?errs);
-            Some((translated, errs))
-        };
-
-        self.fluent_bundle()
-            .and_then(|bundle| translate_with_bundle(bundle))
-            // If `translate_with_bundle` returns `None` with the primary bundle, this is likely
-            // just that the primary bundle doesn't contain the message being translated, so
-            // proceed to the fallback bundle.
-            //
-            // However, when errors are produced from translation, then that means the translation
-            // is broken (e.g. `{$foo}` exists in a translation but `foo` isn't provided).
-            //
-            // In debug builds, assert so that compiler devs can spot the broken translation and
-            // fix it..
-            .inspect(|(_, errs)| {
-                debug_assert!(
-                    errs.is_empty(),
-                    "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
-                    identifier,
-                    attr,
-                    args,
-                    errs
-                );
-            })
-            // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
-            // just hide it and try with the fallback bundle.
-            .filter(|(_, errs)| errs.is_empty())
-            .or_else(|| translate_with_bundle(self.fallback_fluent_bundle()))
-            .map(|(translated, errs)| {
-                // Always bail out for errors with the fallback bundle.
-                assert!(
-                    errs.is_empty(),
-                    "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
-                    identifier,
-                    attr,
-                    args,
-                    errs
-                );
-                translated
-            })
-            .expect("failed to find message in primary or fallback fluent bundles")
-    }
-
     /// Formats the substitutions of the primary_span
     ///
     /// There are a lot of conditions to this method, but in short:
@@ -616,11 +520,7 @@ pub trait Emitter {
     }
 }
 
-impl Emitter for EmitterWriter {
-    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
-        self.sm.as_ref()
-    }
-
+impl Translate for EmitterWriter {
     fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
         self.fluent_bundle.as_ref()
     }
@@ -628,6 +528,12 @@ impl Emitter for EmitterWriter {
     fn fallback_fluent_bundle(&self) -> &FluentBundle {
         &**self.fallback_bundle
     }
+}
+
+impl Emitter for EmitterWriter {
+    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+        self.sm.as_ref()
+    }
 
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
         let fluent_args = self.to_fluent_args(diag.args());
@@ -672,11 +578,7 @@ pub struct SilentEmitter {
     pub fatal_note: Option<String>,
 }
 
-impl Emitter for SilentEmitter {
-    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
-        None
-    }
-
+impl Translate for SilentEmitter {
     fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
         None
     }
@@ -684,6 +586,12 @@ impl Emitter for SilentEmitter {
     fn fallback_fluent_bundle(&self) -> &FluentBundle {
         panic!("silent emitter attempted to translate message")
     }
+}
+
+impl Emitter for SilentEmitter {
+    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+        None
+    }
 
     fn emit_diagnostic(&mut self, d: &Diagnostic) {
         if d.level == Level::Fatal {
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index b8cd334b4c6..1680c6accd7 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -13,6 +13,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
 
 use crate::emitter::{Emitter, HumanReadableErrorType};
 use crate::registry::Registry;
+use crate::translation::Translate;
 use crate::DiagnosticId;
 use crate::{
     CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, SubDiagnostic,
@@ -122,6 +123,16 @@ impl JsonEmitter {
     }
 }
 
+impl Translate for JsonEmitter {
+    fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
+        self.fluent_bundle.as_ref()
+    }
+
+    fn fallback_fluent_bundle(&self) -> &FluentBundle {
+        &**self.fallback_bundle
+    }
+}
+
 impl Emitter for JsonEmitter {
     fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) {
         let data = Diagnostic::from_errors_diagnostic(diag, self);
@@ -189,14 +200,6 @@ impl Emitter for JsonEmitter {
         Some(&self.sm)
     }
 
-    fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
-        self.fluent_bundle.as_ref()
-    }
-
-    fn fallback_fluent_bundle(&self) -> &FluentBundle {
-        &**self.fallback_bundle
-    }
-
     fn should_show_explain(&self) -> bool {
         !matches!(self.json_rendered, HumanReadableErrorType::Short(_))
     }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 395bf5aad01..9b9c334d4df 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -58,6 +58,7 @@ mod lock;
 pub mod registry;
 mod snippet;
 mod styled_buffer;
+pub mod translation;
 
 pub use snippet::Style;
 
@@ -458,6 +459,7 @@ struct HandlerInner {
 pub enum StashKey {
     ItemNoType,
     UnderscoreForArrayLengths,
+    EarlySyntaxWarning,
 }
 
 fn default_track_diagnostic(_: &Diagnostic) {}
@@ -625,19 +627,13 @@ impl Handler {
     /// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing.
     pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) {
         let mut inner = self.inner.borrow_mut();
-        // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
-        // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
-        // See the PR for a discussion.
-        inner.stashed_diagnostics.insert((span, key), diag);
+        inner.stash((span, key), diag);
     }
 
     /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key.
     pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> {
-        self.inner
-            .borrow_mut()
-            .stashed_diagnostics
-            .remove(&(span, key))
-            .map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
+        let mut inner = self.inner.borrow_mut();
+        inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
     }
 
     /// Emit all stashed diagnostics.
@@ -645,6 +641,15 @@ impl Handler {
         self.inner.borrow_mut().emit_stashed_diagnostics()
     }
 
+    /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`.
+    #[rustc_lint_diagnostics]
+    pub fn struct_diagnostic<G: EmissionGuarantee>(
+        &self,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, G> {
+        G::make_diagnostic_builder(self, msg)
+    }
+
     /// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
     ///
     /// Attempting to `.emit()` the builder will only emit if either:
@@ -1105,13 +1110,31 @@ impl HandlerInner {
 
     /// Emit all stashed diagnostics.
     fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
+        let has_errors = self.has_errors();
         let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
         let mut reported = None;
         for mut diag in diags {
+            // Decrement the count tracking the stash; emitting will increment it.
             if diag.is_error() {
-                reported = Some(ErrorGuaranteed(()));
+                if matches!(diag.level, Level::Error { lint: true }) {
+                    self.lint_err_count -= 1;
+                } else {
+                    self.err_count -= 1;
+                }
+            } else {
+                if diag.is_force_warn() {
+                    self.warn_count -= 1;
+                } else {
+                    // Unless they're forced, don't flush stashed warnings when
+                    // there are errors, to avoid causing warning overload. The
+                    // stash would've been stolen already if it were important.
+                    if has_errors {
+                        continue;
+                    }
+                }
             }
-            self.emit_diagnostic(&mut diag);
+            let reported_this = self.emit_diagnostic(&mut diag);
+            reported = reported.or(reported_this);
         }
         reported
     }
@@ -1301,9 +1324,47 @@ impl HandlerInner {
         }
     }
 
+    fn stash(&mut self, key: (Span, StashKey), diagnostic: Diagnostic) {
+        // Track the diagnostic for counts, but don't panic-if-treat-err-as-bug
+        // yet; that happens when we actually emit the diagnostic.
+        if diagnostic.is_error() {
+            if matches!(diagnostic.level, Level::Error { lint: true }) {
+                self.lint_err_count += 1;
+            } else {
+                self.err_count += 1;
+            }
+        } else {
+            // Warnings are only automatically flushed if they're forced.
+            if diagnostic.is_force_warn() {
+                self.warn_count += 1;
+            }
+        }
+
+        // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
+        // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
+        // See the PR for a discussion.
+        self.stashed_diagnostics.insert(key, diagnostic);
+    }
+
+    fn steal(&mut self, key: (Span, StashKey)) -> Option<Diagnostic> {
+        let diagnostic = self.stashed_diagnostics.remove(&key)?;
+        if diagnostic.is_error() {
+            if matches!(diagnostic.level, Level::Error { lint: true }) {
+                self.lint_err_count -= 1;
+            } else {
+                self.err_count -= 1;
+            }
+        } else {
+            if diagnostic.is_force_warn() {
+                self.warn_count -= 1;
+            }
+        }
+        Some(diagnostic)
+    }
+
     #[inline]
     fn err_count(&self) -> usize {
-        self.err_count + self.stashed_diagnostics.len()
+        self.err_count
     }
 
     fn has_errors(&self) -> bool {
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
new file mode 100644
index 00000000000..65338f56d9c
--- /dev/null
+++ b/compiler/rustc_errors/src/translation.rs
@@ -0,0 +1,103 @@
+use crate::snippet::Style;
+use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle};
+use rustc_data_structures::sync::Lrc;
+use rustc_error_messages::FluentArgs;
+use std::borrow::Cow;
+
+pub trait Translate {
+    /// Return `FluentBundle` with localized diagnostics for the locale requested by the user. If no
+    /// language was requested by the user then this will be `None` and `fallback_fluent_bundle`
+    /// should be used.
+    fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>>;
+
+    /// Return `FluentBundle` with localized diagnostics for the default locale of the compiler.
+    /// Used when the user has not requested a specific language or when a localized diagnostic is
+    /// unavailable for the requested locale.
+    fn fallback_fluent_bundle(&self) -> &FluentBundle;
+
+    /// Convert diagnostic arguments (a rustc internal type that exists to implement
+    /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
+    ///
+    /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
+    /// passed around as a reference thereafter.
+    fn to_fluent_args<'arg>(&self, args: &[DiagnosticArg<'arg>]) -> FluentArgs<'arg> {
+        FromIterator::from_iter(args.to_vec().drain(..))
+    }
+
+    /// Convert `DiagnosticMessage`s to a string, performing translation if necessary.
+    fn translate_messages(
+        &self,
+        messages: &[(DiagnosticMessage, Style)],
+        args: &FluentArgs<'_>,
+    ) -> Cow<'_, str> {
+        Cow::Owned(
+            messages.iter().map(|(m, _)| self.translate_message(m, args)).collect::<String>(),
+        )
+    }
+
+    /// Convert a `DiagnosticMessage` to a string, performing translation if necessary.
+    fn translate_message<'a>(
+        &'a self,
+        message: &'a DiagnosticMessage,
+        args: &'a FluentArgs<'_>,
+    ) -> Cow<'_, str> {
+        trace!(?message, ?args);
+        let (identifier, attr) = match message {
+            DiagnosticMessage::Str(msg) => return Cow::Borrowed(&msg),
+            DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
+        };
+
+        let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
+            let message = bundle.get_message(&identifier)?;
+            let value = match attr {
+                Some(attr) => message.get_attribute(attr)?.value(),
+                None => message.value()?,
+            };
+            debug!(?message, ?value);
+
+            let mut errs = vec![];
+            let translated = bundle.format_pattern(value, Some(&args), &mut errs);
+            debug!(?translated, ?errs);
+            Some((translated, errs))
+        };
+
+        self.fluent_bundle()
+            .and_then(|bundle| translate_with_bundle(bundle))
+            // If `translate_with_bundle` returns `None` with the primary bundle, this is likely
+            // just that the primary bundle doesn't contain the message being translated, so
+            // proceed to the fallback bundle.
+            //
+            // However, when errors are produced from translation, then that means the translation
+            // is broken (e.g. `{$foo}` exists in a translation but `foo` isn't provided).
+            //
+            // In debug builds, assert so that compiler devs can spot the broken translation and
+            // fix it..
+            .inspect(|(_, errs)| {
+                debug_assert!(
+                    errs.is_empty(),
+                    "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+                    identifier,
+                    attr,
+                    args,
+                    errs
+                );
+            })
+            // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
+            // just hide it and try with the fallback bundle.
+            .filter(|(_, errs)| errs.is_empty())
+            .or_else(|| translate_with_bundle(self.fallback_fluent_bundle()))
+            .map(|(translated, errs)| {
+                // Always bail out for errors with the fallback bundle.
+                assert!(
+                    errs.is_empty(),
+                    "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
+                    identifier,
+                    attr,
+                    args,
+                    errs
+                );
+                translated
+            })
+            .expect("failed to find message in primary or fallback fluent bundles")
+    }
+}
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index fa3e2a4a5b8..0440bca53b2 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -3,6 +3,7 @@ use crate::base::ExtCtxt;
 use rustc_ast::attr;
 use rustc_ast::ptr::P;
 use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp};
+use rustc_data_structures::sync::Lrc;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 
@@ -106,14 +107,13 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         ident: Ident,
-        attrs: Vec<ast::Attribute>,
         bounds: ast::GenericBounds,
         default: Option<P<ast::Ty>>,
     ) -> ast::GenericParam {
         ast::GenericParam {
             ident: ident.with_span_pos(span),
             id: ast::DUMMY_NODE_ID,
-            attrs: attrs.into(),
+            attrs: AttrVec::new(),
             bounds,
             kind: ast::GenericParamKind::Type { default },
             is_placeholder: false,
@@ -330,23 +330,38 @@ impl<'a> ExtCtxt<'a> {
         self.expr_struct(span, self.path_ident(span, id), fields)
     }
 
-    pub fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> {
+    fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> {
         let lit = ast::Lit::from_lit_kind(lit_kind, span);
         self.expr(span, ast::ExprKind::Lit(lit))
     }
+
     pub fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> {
         self.expr_lit(
             span,
             ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)),
         )
     }
+
     pub fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> {
         self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32)))
     }
+
     pub fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> {
         self.expr_lit(sp, ast::LitKind::Bool(value))
     }
 
+    pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> {
+        self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked))
+    }
+
+    pub fn expr_char(&self, sp: Span, ch: char) -> P<ast::Expr> {
+        self.expr_lit(sp, ast::LitKind::Char(ch))
+    }
+
+    pub fn expr_byte_str(&self, sp: Span, bytes: Vec<u8>) -> P<ast::Expr> {
+        self.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(bytes)))
+    }
+
     /// `[expr1, expr2, ...]`
     pub fn expr_array(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::Array(exprs))
@@ -357,10 +372,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr_addr_of(sp, self.expr_array(sp, exprs))
     }
 
-    pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> {
-        self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked))
-    }
-
     pub fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::Cast(expr, ty))
     }
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
new file mode 100644
index 00000000000..0feae0debd2
--- /dev/null
+++ b/compiler/rustc_expand/src/errors.rs
@@ -0,0 +1,48 @@
+use rustc_macros::SessionDiagnostic;
+use rustc_span::symbol::MacroRulesNormalizedIdent;
+use rustc_span::Span;
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::expr_repeat_no_syntax_vars)]
+pub(crate) struct NoSyntaxVarsExprRepeat {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::must_repeat_once)]
+pub(crate) struct MustRepeatOnce {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::count_repetition_misplaced)]
+pub(crate) struct CountRepetitionMisplaced {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::meta_var_expr_unrecognized_var)]
+pub(crate) struct MetaVarExprUnrecognizedVar {
+    #[primary_span]
+    pub span: Span,
+    pub key: MacroRulesNormalizedIdent,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::var_still_repeating)]
+pub(crate) struct VarStillRepeating {
+    #[primary_span]
+    pub span: Span,
+    pub ident: MacroRulesNormalizedIdent,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(expand::meta_var_dif_seq_matchers)]
+pub(crate) struct MetaVarsDifSeqMatchers {
+    #[primary_span]
+    pub span: Span,
+    pub msg: String,
+}
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 93eeca5b289..cc72dab84af 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -306,7 +306,7 @@ pub struct Invocation {
 
 pub enum InvocationKind {
     Bang {
-        mac: ast::MacCall,
+        mac: P<ast::MacCall>,
         span: Span,
     },
     Attr {
@@ -1017,7 +1017,7 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
     fn is_mac_call(&self) -> bool {
         false
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         unreachable!()
     }
     fn pre_flat_map_node_collect_attr(_cfg: &StripUnconfigured<'_>, _attr: &ast::Attribute) {}
@@ -1046,7 +1046,7 @@ impl InvocationCollectorNode for P<ast::Item> {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let node = self.into_inner();
         match node.kind {
             ItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1154,7 +1154,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let item = self.wrapped.into_inner();
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1179,7 +1179,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let item = self.wrapped.into_inner();
         match item.kind {
             AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1202,7 +1202,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ForeignItemKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let node = self.into_inner();
         match node.kind {
             ForeignItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1323,7 +1323,7 @@ impl InvocationCollectorNode for ast::Stmt {
             StmtKind::Local(..) | StmtKind::Empty => false,
         }
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         // We pull macro invocations (both attributes and fn-like macro calls) out of their
         // `StmtKind`s and treat them as statement macro invocations, not as items or expressions.
         let (add_semicolon, mac, attrs) = match self.kind {
@@ -1387,7 +1387,7 @@ impl InvocationCollectorNode for P<ast::Ty> {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ast::TyKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let node = self.into_inner();
         match node.kind {
             TyKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No),
@@ -1411,7 +1411,7 @@ impl InvocationCollectorNode for P<ast::Pat> {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, PatKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let node = self.into_inner();
         match node.kind {
             PatKind::MacCall(mac) => (mac, Vec::new(), AddSemicolon::No),
@@ -1439,7 +1439,7 @@ impl InvocationCollectorNode for P<ast::Expr> {
     fn is_mac_call(&self) -> bool {
         matches!(self.kind, ExprKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let node = self.into_inner();
         match node.kind {
             ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1466,7 +1466,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
     fn is_mac_call(&self) -> bool {
         matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
     }
-    fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) {
+    fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
         let node = self.wrapped.into_inner();
         match node.kind {
             ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1512,7 +1512,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
     }
 
-    fn collect_bang(&mut self, mac: ast::MacCall, kind: AstFragmentKind) -> AstFragment {
+    fn collect_bang(&mut self, mac: P<ast::MacCall>, kind: AstFragmentKind) -> AstFragment {
         // cache the macro call span so that it can be
         // easily adjusted for incremental compilation
         let span = mac.span();
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 91a18342784..e1dde1672c1 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -25,6 +25,7 @@ pub mod base;
 pub mod build;
 #[macro_use]
 pub mod config;
+pub mod errors;
 pub mod expand;
 pub mod module;
 pub mod proc_macro;
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index fc808401a5e..99fe474541e 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -112,7 +112,7 @@ fn parse_depth<'sess>(
             "meta-variable expression depth must be a literal"
         ));
     };
-    if let Ok(lit_kind) = LitKind::from_lit_token(*lit)
+    if let Ok(lit_kind) = LitKind::from_token_lit(*lit)
         && let LitKind::Int(n_u128, LitIntType::Unsuffixed) = lit_kind
         && let Ok(n_usize) = usize::try_from(n_u128)
     {
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index e47ea83ac38..bec6d1a2df7 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -1,4 +1,8 @@
 use crate::base::ExtCtxt;
+use crate::errors::{
+    CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, MustRepeatOnce,
+    NoSyntaxVarsExprRepeat, VarStillRepeating,
+};
 use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch};
 use crate::mbe::{self, MetaVarExpr};
 use rustc_ast::mut_visit::{self, MutVisitor};
@@ -165,11 +169,7 @@ pub(super) fn transcribe<'a>(
             seq @ mbe::TokenTree::Sequence(_, delimited) => {
                 match lockstep_iter_size(&seq, interp, &repeats) {
                     LockstepIterSize::Unconstrained => {
-                        return Err(cx.struct_span_err(
-                            seq.span(), /* blame macro writer */
-                            "attempted to repeat an expression containing no syntax variables \
-                             matched as repeating at this depth",
-                        ));
+                        return Err(cx.create_err(NoSyntaxVarsExprRepeat { span: seq.span() }));
                     }
 
                     LockstepIterSize::Contradiction(msg) => {
@@ -177,7 +177,7 @@ pub(super) fn transcribe<'a>(
                         // happens when two meta-variables are used in the same repetition in a
                         // sequence, but they come from different sequence matchers and repeat
                         // different amounts.
-                        return Err(cx.struct_span_err(seq.span(), &msg));
+                        return Err(cx.create_err(MetaVarsDifSeqMatchers { span: seq.span(), msg }));
                     }
 
                     LockstepIterSize::Constraint(len, _) => {
@@ -193,10 +193,7 @@ pub(super) fn transcribe<'a>(
                                 // FIXME: this really ought to be caught at macro definition
                                 // time... It happens when the Kleene operator in the matcher and
                                 // the body for the same meta-variable do not match.
-                                return Err(cx.struct_span_err(
-                                    sp.entire(),
-                                    "this must repeat at least once",
-                                ));
+                                return Err(cx.create_err(MustRepeatOnce { span: sp.entire() }));
                             }
                         } else {
                             // 0 is the initial counter (we have done 0 repetitions so far). `len`
@@ -239,10 +236,7 @@ pub(super) fn transcribe<'a>(
                         }
                         MatchedSeq(..) => {
                             // We were unable to descend far enough. This is an error.
-                            return Err(cx.struct_span_err(
-                                sp, /* blame the macro writer */
-                                &format!("variable '{}' is still repeating at this depth", ident),
-                            ));
+                            return Err(cx.create_err(VarStillRepeating { span: sp, ident }));
                         }
                     }
                 } else {
@@ -448,10 +442,7 @@ fn count_repetitions<'a>(
         match matched {
             MatchedTokenTree(_) | MatchedNonterminal(_) => {
                 if declared_lhs_depth == 0 {
-                    return Err(cx.struct_span_err(
-                        sp.entire(),
-                        "`count` can not be placed inside the inner-most repetition",
-                    ));
+                    return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
                 }
                 match depth_opt {
                     None => Ok(1),
@@ -499,12 +490,7 @@ where
 {
     let span = ident.span;
     let key = MacroRulesNormalizedIdent::new(ident);
-    interp.get(&key).ok_or_else(|| {
-        cx.struct_span_err(
-            span,
-            &format!("variable `{}` is not recognized in meta-variable expression", key),
-        )
-    })
+    interp.get(&key).ok_or_else(|| cx.create_err(MetaVarExprUnrecognizedVar { span, key }))
 }
 
 /// Used by meta-variable expressions when an user input is out of the actual declared bounds. For
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 0d5d6ee0794..48918541e72 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -15,12 +15,12 @@ pub fn placeholder(
     id: ast::NodeId,
     vis: Option<ast::Visibility>,
 ) -> AstFragment {
-    fn mac_placeholder() -> ast::MacCall {
-        ast::MacCall {
+    fn mac_placeholder() -> P<ast::MacCall> {
+        P(ast::MacCall {
             path: ast::Path { span: DUMMY_SP, segments: Vec::new(), tokens: None },
             args: P(ast::MacArgs::Empty),
             prior_type_ascription: None,
-        }
+        })
     }
 
     let ident = Ident::empty();
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 7d9a4aed0bf..beb33c05913 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -486,20 +486,26 @@ impl server::TokenStream for Rustc<'_, '_> {
         // We don't use `TokenStream::from_ast` as the tokenstream currently cannot
         // be recovered in the general case.
         match &expr.kind {
-            ast::ExprKind::Lit(l) if l.token.kind == token::Bool => Ok(
-                tokenstream::TokenStream::token_alone(token::Ident(l.token.symbol, false), l.span),
-            ),
+            ast::ExprKind::Lit(l) if l.token_lit.kind == token::Bool => {
+                Ok(tokenstream::TokenStream::token_alone(
+                    token::Ident(l.token_lit.symbol, false),
+                    l.span,
+                ))
+            }
             ast::ExprKind::Lit(l) => {
-                Ok(tokenstream::TokenStream::token_alone(token::Literal(l.token), l.span))
+                Ok(tokenstream::TokenStream::token_alone(token::Literal(l.token_lit), l.span))
             }
             ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind {
-                ast::ExprKind::Lit(l) => match l.token {
+                ast::ExprKind::Lit(l) => match l.token_lit {
                     token::Lit { kind: token::Integer | token::Float, .. } => {
                         Ok(Self::TokenStream::from_iter([
                             // FIXME: The span of the `-` token is lost when
                             // parsing, so we cannot faithfully recover it here.
                             tokenstream::TokenTree::token_alone(token::BinOp(token::Minus), e.span),
-                            tokenstream::TokenTree::token_alone(token::Literal(l.token), l.span),
+                            tokenstream::TokenTree::token_alone(
+                                token::Literal(l.token_lit),
+                                l.span,
+                            ),
                         ]))
                     }
                     _ => Err(()),
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index efb83052768..e44c9291f84 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -12,6 +12,8 @@
 //! symbol to the `accepted` or `removed` modules respectively.
 
 #![feature(once_cell)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 mod accepted;
 mod active;
diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs
index 87e97c746ef..63998bb6b00 100644
--- a/compiler/rustc_fs_util/src/lib.rs
+++ b/compiler/rustc_fs_util/src/lib.rs
@@ -1,3 +1,6 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
 use std::ffi::CString;
 use std::fs;
 use std::io;
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index 6eaff5c2f74..3c1bb553266 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -273,6 +273,8 @@
     html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
     test(attr(allow(unused_variables), deny(warnings)))
 )]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 use LabelText::*;
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 584e86d51d9..ca1705f26b5 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -778,7 +778,6 @@ impl<'hir> WhereRegionPredicate<'hir> {
 /// An equality predicate (e.g., `T = int`); currently unsupported.
 #[derive(Debug, HashStable_Generic)]
 pub struct WhereEqPredicate<'hir> {
-    pub hir_id: HirId,
     pub span: Span,
     pub lhs_ty: &'hir Ty<'hir>,
     pub rhs_ty: &'hir Ty<'hir>,
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 900370937f7..3d5e22add71 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -876,10 +876,7 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
             visitor.visit_lifetime(lifetime);
             walk_list!(visitor, visit_param_bound, bounds);
         }
-        WherePredicate::EqPredicate(WhereEqPredicate {
-            hir_id, ref lhs_ty, ref rhs_ty, ..
-        }) => {
-            visitor.visit_id(hir_id);
+        WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => {
             visitor.visit_ty(lhs_ty);
             visitor.visit_ty(rhs_ty);
         }
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 0f9e6fa7b98..7097f998beb 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -11,6 +11,8 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index e6fcb84730e..42663da8a3f 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1,4 +1,6 @@
 #![recursion_limit = "256"]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 use rustc_ast as ast;
 use rustc_ast::util::parser::{self, AssocOp, Fixity};
@@ -1247,7 +1249,7 @@ impl<'a> State<'a> {
 
     fn print_literal(&mut self, lit: &hir::Lit) {
         self.maybe_print_comment(lit.span.lo());
-        self.word(lit.node.to_lit_token().to_string())
+        self.word(lit.node.to_token_lit().to_string())
     }
 
     fn print_inline_asm(&mut self, asm: &hir::InlineAsm<'_>) {
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 33c3c536f11..aa34673de81 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -1,3 +1,5 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(allow_internal_unstable)]
 #![feature(bench_black_box)]
 #![feature(extend_one)]
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index fcb87a9f32f..8fb5f159136 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -66,6 +66,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::Node;
 use rustc_middle::dep_graph::DepContext;
 use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
 use rustc_middle::ty::{
     self, error::TypeError, Binder, List, Region, Subst, Ty, TyCtxt, TypeFoldable,
     TypeSuperVisitable, TypeVisitable,
@@ -1750,6 +1751,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
             && let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
             && let Some(def_id) = def_id.as_local()
+            && terr.involves_regions()
         {
             let span = self.tcx.def_span(def_id);
             diag.span_note(span, "this closure does not fulfill the lifetime requirements");
@@ -2078,7 +2080,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             diag.span_suggestion(
                                 span,
                                 *msg,
-                                format!("{}.as_ref()", snippet),
+                                // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&`
+                                format!("{}.as_ref()", snippet.trim_start_matches('&')),
                                 Applicability::MachineApplicable,
                             );
                         }
@@ -2659,67 +2662,92 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// Float types, respectively). When comparing two ADTs, these rules apply recursively.
     pub fn same_type_modulo_infer(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
         let (a, b) = self.resolve_vars_if_possible((a, b));
-        match (a.kind(), b.kind()) {
-            (&ty::Adt(def_a, substs_a), &ty::Adt(def_b, substs_b)) => {
-                if def_a != def_b {
-                    return false;
-                }
+        SameTypeModuloInfer(self).relate(a, b).is_ok()
+    }
+}
 
-                substs_a
-                    .types()
-                    .zip(substs_b.types())
-                    .all(|(a, b)| self.same_type_modulo_infer(a, b))
-            }
-            (&ty::FnDef(did_a, substs_a), &ty::FnDef(did_b, substs_b)) => {
-                if did_a != did_b {
-                    return false;
-                }
+struct SameTypeModuloInfer<'a, 'tcx>(&'a InferCtxt<'a, 'tcx>);
 
-                substs_a
-                    .types()
-                    .zip(substs_b.types())
-                    .all(|(a, b)| self.same_type_modulo_infer(a, b))
-            }
-            (&ty::Int(_) | &ty::Uint(_), &ty::Infer(ty::InferTy::IntVar(_)))
+impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.0.tcx
+    }
+
+    fn param_env(&self) -> ty::ParamEnv<'tcx> {
+        // Unused, only for consts which we treat as always equal
+        ty::ParamEnv::empty()
+    }
+
+    fn tag(&self) -> &'static str {
+        "SameTypeModuloInfer"
+    }
+
+    fn a_is_expected(&self) -> bool {
+        true
+    }
+
+    fn relate_with_variance<T: relate::Relate<'tcx>>(
+        &mut self,
+        _variance: ty::Variance,
+        _info: ty::VarianceDiagInfo<'tcx>,
+        a: T,
+        b: T,
+    ) -> relate::RelateResult<'tcx, T> {
+        self.relate(a, b)
+    }
+
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        match (a.kind(), b.kind()) {
+            (ty::Int(_) | ty::Uint(_), ty::Infer(ty::InferTy::IntVar(_)))
             | (
-                &ty::Infer(ty::InferTy::IntVar(_)),
-                &ty::Int(_) | &ty::Uint(_) | &ty::Infer(ty::InferTy::IntVar(_)),
+                ty::Infer(ty::InferTy::IntVar(_)),
+                ty::Int(_) | ty::Uint(_) | ty::Infer(ty::InferTy::IntVar(_)),
             )
-            | (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_)))
+            | (ty::Float(_), ty::Infer(ty::InferTy::FloatVar(_)))
             | (
-                &ty::Infer(ty::InferTy::FloatVar(_)),
-                &ty::Float(_) | &ty::Infer(ty::InferTy::FloatVar(_)),
+                ty::Infer(ty::InferTy::FloatVar(_)),
+                ty::Float(_) | ty::Infer(ty::InferTy::FloatVar(_)),
             )
-            | (&ty::Infer(ty::InferTy::TyVar(_)), _)
-            | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true,
-            (&ty::Ref(_, ty_a, mut_a), &ty::Ref(_, ty_b, mut_b)) => {
-                mut_a == mut_b && self.same_type_modulo_infer(ty_a, ty_b)
-            }
-            (&ty::RawPtr(a), &ty::RawPtr(b)) => {
-                a.mutbl == b.mutbl && self.same_type_modulo_infer(a.ty, b.ty)
-            }
-            (&ty::Slice(a), &ty::Slice(b)) => self.same_type_modulo_infer(a, b),
-            (&ty::Array(a_ty, a_ct), &ty::Array(b_ty, b_ct)) => {
-                self.same_type_modulo_infer(a_ty, b_ty) && a_ct == b_ct
-            }
-            (&ty::Tuple(a), &ty::Tuple(b)) => {
-                if a.len() != b.len() {
-                    return false;
-                }
-                std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b))
-            }
-            (&ty::FnPtr(a), &ty::FnPtr(b)) => {
-                let a = a.skip_binder().inputs_and_output;
-                let b = b.skip_binder().inputs_and_output;
-                if a.len() != b.len() {
-                    return false;
-                }
-                std::iter::zip(a.iter(), b.iter()).all(|(a, b)| self.same_type_modulo_infer(a, b))
-            }
-            // FIXME(compiler-errors): This needs to be generalized more
-            _ => a == b,
+            | (ty::Infer(ty::InferTy::TyVar(_)), _)
+            | (_, ty::Infer(ty::InferTy::TyVar(_))) => Ok(a),
+            (ty::Infer(_), _) | (_, ty::Infer(_)) => Err(TypeError::Mismatch),
+            _ => relate::super_relate_tys(self, a, b),
         }
     }
+
+    fn regions(
+        &mut self,
+        a: ty::Region<'tcx>,
+        b: ty::Region<'tcx>,
+    ) -> RelateResult<'tcx, ty::Region<'tcx>> {
+        if (a.is_var() && b.is_free_or_static()) || (b.is_var() && a.is_free_or_static()) || a == b
+        {
+            Ok(a)
+        } else {
+            Err(TypeError::Mismatch)
+        }
+    }
+
+    fn binders<T>(
+        &mut self,
+        a: ty::Binder<'tcx, T>,
+        b: ty::Binder<'tcx, T>,
+    ) -> relate::RelateResult<'tcx, ty::Binder<'tcx, T>>
+    where
+        T: relate::Relate<'tcx>,
+    {
+        Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
+    }
+
+    fn consts(
+        &mut self,
+        a: ty::Const<'tcx>,
+        _b: ty::Const<'tcx>,
+    ) -> relate::RelateResult<'tcx, ty::Const<'tcx>> {
+        // FIXME(compiler-errors): This could at least do some first-order
+        // relation
+        Ok(a)
+    }
 }
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 1e26e7bb86e..444817f396e 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1935,6 +1935,18 @@ impl<'tcx> TypeTrace<'tcx> {
         }
     }
 
+    pub fn poly_trait_refs(
+        cause: &ObligationCause<'tcx>,
+        a_is_expected: bool,
+        a: ty::PolyTraitRef<'tcx>,
+        b: ty::PolyTraitRef<'tcx>,
+    ) -> TypeTrace<'tcx> {
+        TypeTrace {
+            cause: cause.clone(),
+            values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a.into(), b.into())),
+        }
+    }
+
     pub fn consts(
         cause: &ObligationCause<'tcx>,
         a_is_expected: bool,
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index a1c7b70bd9c..e579afbf389 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -40,15 +40,17 @@ pub struct OpaqueTypeDecl<'tcx> {
 }
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-    pub fn replace_opaque_types_with_inference_vars(
+    /// This is a backwards compatibility hack to prevent breaking changes from
+    /// lazy TAIT around RPIT handling.
+    pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>(
         &self,
-        ty: Ty<'tcx>,
+        value: T,
         body_id: HirId,
         span: Span,
         param_env: ty::ParamEnv<'tcx>,
-    ) -> InferOk<'tcx, Ty<'tcx>> {
-        if !ty.has_opaque_types() {
-            return InferOk { value: ty, obligations: vec![] };
+    ) -> InferOk<'tcx, T> {
+        if !value.has_opaque_types() {
+            return InferOk { value, obligations: vec![] };
         }
         let mut obligations = vec![];
         let replace_opaque_type = |def_id: DefId| {
@@ -56,7 +58,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 .as_local()
                 .map_or(false, |def_id| self.opaque_type_origin(def_id, span).is_some())
         };
-        let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
+        let value = value.fold_with(&mut ty::fold::BottomUpFolder {
             tcx: self.tcx,
             lt_op: |lt| lt,
             ct_op: |ct| ct,
diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
index 772e297b7b4..be03c8b5bae 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -174,7 +174,14 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
-        if pattern == value { Ok(pattern) } else { relate::super_relate_tys(self, pattern, value) }
+        if let ty::Error(_) = pattern.kind() {
+            // Unlike normal `TypeRelation` rules, `ty::Error` does not equal any type.
+            self.no_match()
+        } else if pattern == value {
+            Ok(pattern)
+        } else {
+            relate::super_relate_tys(self, pattern, value)
+        }
     }
 
     #[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 1ecbc876c8d..da4002d09ad 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -17,6 +17,7 @@ rustc_attr = { path = "../rustc_attr" }
 rustc_borrowck = { path = "../rustc_borrowck" }
 rustc_builtin_macros = { path = "../rustc_builtin_macros" }
 rustc_expand = { path = "../rustc_expand" }
+rustc_macros = { path = "../rustc_macros" }
 rustc_parse = { path = "../rustc_parse" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 8f083591786..014cf88389e 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -8,11 +8,12 @@ use rustc_borrowck as mir_borrowck;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::parallel;
 use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
-use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, PResult};
+use rustc_errors::{ErrorGuaranteed, PResult};
 use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
 use rustc_hir::def_id::StableCrateId;
 use rustc_hir::definitions::Definitions;
 use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore};
+use rustc_macros::SessionDiagnostic;
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
@@ -30,7 +31,7 @@ use rustc_session::output::filename_for_input;
 use rustc_session::search_paths::PathKind;
 use rustc_session::{Limit, Session};
 use rustc_span::symbol::{sym, Symbol};
-use rustc_span::FileName;
+use rustc_span::{FileName, Span};
 use rustc_trait_selection::traits;
 use rustc_typeck as typeck;
 use tracing::{info, warn};
@@ -263,6 +264,23 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> {
     }
 }
 
+#[derive(SessionDiagnostic)]
+#[diag(interface::ferris_identifier)]
+struct FerrisIdentifier {
+    #[primary_span]
+    spans: Vec<Span>,
+    #[suggestion(code = "ferris", applicability = "maybe-incorrect")]
+    first_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::emoji_identifier)]
+struct EmojiIdentifier {
+    #[primary_span]
+    spans: Vec<Span>,
+    ident: Symbol,
+}
+
 /// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
 /// syntax expansion, secondary `cfg` expansion, synthesis of a test
 /// harness if one is to be provided, injection of a dependency on the
@@ -443,23 +461,9 @@ pub fn configure_and_expand(
             spans.sort();
             if ident == sym::ferris {
                 let first_span = spans[0];
-                sess.diagnostic()
-                    .struct_span_err(
-                        MultiSpan::from(spans),
-                        "Ferris cannot be used as an identifier",
-                    )
-                    .span_suggestion(
-                        first_span,
-                        "try using their name instead",
-                        "ferris",
-                        Applicability::MaybeIncorrect,
-                    )
-                    .emit();
+                sess.emit_err(FerrisIdentifier { spans, first_span });
             } else {
-                sess.diagnostic().span_err(
-                    MultiSpan::from(spans),
-                    &format!("identifiers cannot contain emoji: `{}`", ident),
-                );
+                sess.emit_err(EmojiIdentifier { spans, ident });
             }
         }
     });
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 6d311af9007..178366f7d80 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -18,6 +18,8 @@
 //! lexeme types.
 //!
 //! [`rustc_parse::lexer`]: ../rustc_parse/lexer/index.html
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 // We want to be able to build this crate with a stable compiler, so no
 // `#![feature]` attributes should be added.
 
diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
index fe2712525ee..8f22221324a 100644
--- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
+++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
@@ -120,8 +120,8 @@ impl EarlyLintPass for HiddenUnicodeCodepoints {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
         // byte strings are already handled well enough by `EscapeError::NonAsciiCharInByteString`
         let (text, span, padding) = match &expr.kind {
-            ast::ExprKind::Lit(ast::Lit { token, kind, span }) => {
-                let text = token.symbol;
+            ast::ExprKind::Lit(ast::Lit { token_lit, kind, span }) => {
+                let text = token_lit.symbol;
                 if !contains_text_flow_control_chars(text.as_str()) {
                     return;
                 }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index cafd2c6e679..484e541afc5 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1546,7 +1546,7 @@ impl InvalidAtomicOrdering {
 
         if matches!(fail_ordering, sym::Release | sym::AcqRel) {
             #[derive(LintDiagnostic)]
-            #[lint(lint::atomic_ordering_invalid)]
+            #[diag(lint::atomic_ordering_invalid)]
             #[help]
             struct InvalidAtomicOrderingDiag {
                 method: Symbol,
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index f00165cd3b3..95e34da734d 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3212,6 +3212,56 @@ declare_lint! {
     };
 }
 
+declare_lint! {
+    /// The `unstable_syntax_pre_expansion` lint detects the use of unstable
+    /// syntax that is discarded during attribute expansion.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #[cfg(FALSE)]
+    /// macro foo() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// The input to active attributes such as `#[cfg]` or procedural macro
+    /// attributes is required to be valid syntax. Previously, the compiler only
+    /// gated the use of unstable syntax features after resolving `#[cfg]` gates
+    /// and expanding procedural macros.
+    ///
+    /// To avoid relying on unstable syntax, move the use of unstable syntax
+    /// into a position where the compiler does not parse the syntax, such as a
+    /// functionlike macro.
+    ///
+    /// ```rust
+    /// # #![deny(unstable_syntax_pre_expansion)]
+    ///
+    /// macro_rules! identity {
+    ///    ( $($tokens:tt)* ) => { $($tokens)* }
+    /// }
+    ///
+    /// #[cfg(FALSE)]
+    /// identity! {
+    ///    macro foo() {}
+    /// }
+    /// ```
+    ///
+    /// This is a [future-incompatible] lint to transition this
+    /// to a hard error in the future. See [issue #65860] for more details.
+    ///
+    /// [issue #65860]: https://github.com/rust-lang/rust/issues/65860
+    /// [future-incompatible]: ../index.md#future-incompatible-lints
+    pub UNSTABLE_SYNTAX_PRE_EXPANSION,
+    Warn,
+    "unstable syntax can change at any point in the future, causing a hard error!",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #65860 <https://github.com/rust-lang/rust/issues/65860>",
+    };
+}
+
 declare_lint_pass! {
     /// Does nothing as a lint pass, but registers some `Lint`s
     /// that are used by other parts of the compiler.
@@ -3280,6 +3330,7 @@ declare_lint_pass! {
         POINTER_STRUCTURAL_MATCH,
         NONTRIVIAL_STRUCTURAL_MATCH,
         SOFT_UNSTABLE,
+        UNSTABLE_SYNTAX_PRE_EXPANSION,
         INLINE_NO_SANITIZE,
         BAD_ASM_STYLE,
         ASM_SUB_REGISTER,
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 6acbe97a7a1..a826f599e9c 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -1,4 +1,6 @@
 #![feature(min_specialization)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index b4314223722..05d2a214d0b 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -31,6 +31,9 @@
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/FunctionImport.h"
+#if LLVM_VERSION_GE(15, 0)
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
+#endif
 #include "llvm/Transforms/Utils/AddDiscriminators.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
 #include "llvm/LTO/LTO.h"
@@ -1587,13 +1590,31 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
   {
     raw_string_ostream OS(Ret->data);
     {
-      legacy::PassManager PM;
       if (is_thin) {
+#if LLVM_VERSION_LT(15, 0)
+        legacy::PassManager PM;
         PM.add(createWriteThinLTOBitcodePass(OS));
+        PM.run(*unwrap(M));
+#else
+        PassBuilder PB;
+        LoopAnalysisManager LAM;
+        FunctionAnalysisManager FAM;
+        CGSCCAnalysisManager CGAM;
+        ModuleAnalysisManager MAM;
+        PB.registerModuleAnalyses(MAM);
+        PB.registerCGSCCAnalyses(CGAM);
+        PB.registerFunctionAnalyses(FAM);
+        PB.registerLoopAnalyses(LAM);
+        PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+        ModulePassManager MPM;
+        MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
+        MPM.run(*unwrap(M), MAM);
+#endif
       } else {
+        legacy::PassManager PM;
         PM.add(createBitcodeWriterPass(OS));
+        PM.run(*unwrap(M));
       }
-      PM.run(*unwrap(M));
     }
   }
   return Ret.release();
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index 8eade02a408..8542dcf5bf0 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -1,3 +1,5 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 
 // NOTE: This crate only exists to allow linking on mingw targets.
diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs
index f2ec80b0c1b..458f5e87bae 100644
--- a/compiler/rustc_log/src/lib.rs
+++ b/compiler/rustc_log/src/lib.rs
@@ -38,6 +38,9 @@
 //! debugging, you can make changes inside those crates and quickly run main.rs
 //! to read the debug logs.
 
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
 use std::env::{self, VarError};
 use std::fmt::{self, Display};
 use std::io;
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index 6b5b8b59320..244edec2841 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -21,7 +21,7 @@ impl<'a> SessionDiagnosticDerive<'a> {
             builder: DiagnosticDeriveBuilder {
                 diag,
                 fields: build_field_mapping(&structure),
-                kind: None,
+                kind: DiagnosticDeriveKind::SessionDiagnostic,
                 code: None,
                 slug: None,
             },
@@ -34,49 +34,31 @@ impl<'a> SessionDiagnosticDerive<'a> {
         let SessionDiagnosticDerive { mut structure, sess, mut builder } = self;
 
         let ast = structure.ast();
-        let (implementation, param_ty) = {
+        let implementation = {
             if let syn::Data::Struct(..) = ast.data {
                 let preamble = builder.preamble(&structure);
                 let (attrs, args) = builder.body(&mut structure);
 
                 let span = ast.span().unwrap();
                 let diag = &builder.diag;
-                let init = match (builder.kind.value(), builder.slug.value()) {
-                    (None, _) => {
-                        span_err(span, "diagnostic kind not specified")
-                            .help("use the `#[error(...)]` attribute to create an error")
-                            .emit();
-                        return DiagnosticDeriveError::ErrorHandled.to_compile_error();
-                    }
-                    (Some(kind), None) => {
+                let init = match builder.slug.value() {
+                    None => {
                         span_err(span, "diagnostic slug not specified")
                             .help(&format!(
-                                "specify the slug as the first argument to the attribute, such as \
-                                 `#[{}(typeck::example_error)]`",
-                                kind.descr()
+                                "specify the slug as the first argument to the `#[diag(...)]` attribute, \
+                                such as `#[diag(typeck::example_error)]`",
                             ))
                             .emit();
                         return DiagnosticDeriveError::ErrorHandled.to_compile_error();
                     }
-                    (Some(DiagnosticDeriveKind::Lint), _) => {
-                        span_err(span, "only `#[error(..)]` and `#[warning(..)]` are supported")
-                            .help("use the `#[error(...)]` attribute to create a error")
-                            .emit();
-                        return DiagnosticDeriveError::ErrorHandled.to_compile_error();
-                    }
-                    (Some(DiagnosticDeriveKind::Error), Some(slug)) => {
-                        quote! {
-                            let mut #diag = #sess.struct_err(rustc_errors::fluent::#slug);
-                        }
-                    }
-                    (Some(DiagnosticDeriveKind::Warn), Some(slug)) => {
+                    Some(slug) => {
                         quote! {
-                            let mut #diag = #sess.struct_warn(rustc_errors::fluent::#slug);
+                            let mut #diag = #sess.struct_diagnostic(rustc_errors::fluent::#slug);
                         }
                     }
                 };
 
-                let implementation = quote! {
+                quote! {
                     #init
                     #preamble
                     match self {
@@ -86,18 +68,7 @@ impl<'a> SessionDiagnosticDerive<'a> {
                         #args
                     }
                     #diag
-                };
-                let param_ty = match builder.kind {
-                    Some((DiagnosticDeriveKind::Error, _)) => {
-                        quote! { rustc_errors::ErrorGuaranteed }
-                    }
-                    Some((DiagnosticDeriveKind::Lint | DiagnosticDeriveKind::Warn, _)) => {
-                        quote! { () }
-                    }
-                    _ => unreachable!(),
-                };
-
-                (implementation, param_ty)
+                }
             } else {
                 span_err(
                     ast.span().unwrap(),
@@ -105,20 +76,20 @@ impl<'a> SessionDiagnosticDerive<'a> {
                 )
                 .emit();
 
-                let implementation = DiagnosticDeriveError::ErrorHandled.to_compile_error();
-                let param_ty = quote! { rustc_errors::ErrorGuaranteed };
-                (implementation, param_ty)
+                DiagnosticDeriveError::ErrorHandled.to_compile_error()
             }
         };
 
         structure.gen_impl(quote! {
-            gen impl<'__session_diagnostic_sess> rustc_session::SessionDiagnostic<'__session_diagnostic_sess, #param_ty>
+            gen impl<'__session_diagnostic_sess, G>
+                    rustc_session::SessionDiagnostic<'__session_diagnostic_sess, G>
                     for @Self
+                where G: rustc_errors::EmissionGuarantee
             {
                 fn into_diagnostic(
                     self,
                     #sess: &'__session_diagnostic_sess rustc_session::parse::ParseSess
-                ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, #param_ty> {
+                ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, G> {
                     use rustc_errors::IntoDiagnosticArg;
                     #implementation
                 }
@@ -139,7 +110,7 @@ impl<'a> LintDiagnosticDerive<'a> {
             builder: DiagnosticDeriveBuilder {
                 diag,
                 fields: build_field_mapping(&structure),
-                kind: None,
+                kind: DiagnosticDeriveKind::LintDiagnostic,
                 code: None,
                 slug: None,
             },
@@ -158,30 +129,17 @@ impl<'a> LintDiagnosticDerive<'a> {
 
                 let diag = &builder.diag;
                 let span = ast.span().unwrap();
-                let init = match (builder.kind.value(), builder.slug.value()) {
-                    (None, _) => {
-                        span_err(span, "diagnostic kind not specified")
-                            .help("use the `#[error(...)]` attribute to create an error")
-                            .emit();
-                        return DiagnosticDeriveError::ErrorHandled.to_compile_error();
-                    }
-                    (Some(kind), None) => {
+                let init = match builder.slug.value() {
+                    None => {
                         span_err(span, "diagnostic slug not specified")
                             .help(&format!(
                                 "specify the slug as the first argument to the attribute, such as \
-                                 `#[{}(typeck::example_error)]`",
-                                kind.descr()
+                                 `#[diag(typeck::example_error)]`",
                             ))
                             .emit();
                         return DiagnosticDeriveError::ErrorHandled.to_compile_error();
                     }
-                    (Some(DiagnosticDeriveKind::Error | DiagnosticDeriveKind::Warn), _) => {
-                        span_err(span, "only `#[lint(..)]` is supported")
-                            .help("use the `#[lint(...)]` attribute to create a lint")
-                            .emit();
-                        return DiagnosticDeriveError::ErrorHandled.to_compile_error();
-                    }
-                    (Some(DiagnosticDeriveKind::Lint), Some(slug)) => {
+                    Some(slug) => {
                         quote! {
                             let mut #diag = #diag.build(rustc_errors::fluent::#slug);
                         }
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 6c9561925fe..9df9fa4e9bf 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -18,30 +18,15 @@ use syn::{
 };
 use synstructure::{BindingInfo, Structure};
 
-/// What kind of diagnostic is being derived - an error, a warning or a lint?
-#[derive(Copy, Clone)]
+/// What kind of diagnostic is being derived - a fatal/error/warning or a lint?
+#[derive(Copy, Clone, PartialEq, Eq)]
 pub(crate) enum DiagnosticDeriveKind {
-    /// `#[error(..)]`
-    Error,
-    /// `#[warn(..)]`
-    Warn,
-    /// `#[lint(..)]`
-    Lint,
-}
-
-impl DiagnosticDeriveKind {
-    /// Returns human-readable string corresponding to the kind.
-    pub fn descr(&self) -> &'static str {
-        match self {
-            DiagnosticDeriveKind::Error => "error",
-            DiagnosticDeriveKind::Warn => "warning",
-            DiagnosticDeriveKind::Lint => "lint",
-        }
-    }
+    SessionDiagnostic,
+    LintDiagnostic,
 }
 
 /// Tracks persistent information required for building up individual calls to diagnostic methods
-/// for generated diagnostic derives - both `SessionDiagnostic` for errors/warnings and
+/// for generated diagnostic derives - both `SessionDiagnostic` for fatal/errors/warnings and
 /// `LintDiagnostic` for lints.
 pub(crate) struct DiagnosticDeriveBuilder {
     /// The identifier to use for the generated `DiagnosticBuilder` instance.
@@ -51,8 +36,8 @@ pub(crate) struct DiagnosticDeriveBuilder {
     /// derive builder.
     pub fields: HashMap<String, TokenStream>,
 
-    /// Kind of diagnostic requested via the struct attribute.
-    pub kind: Option<(DiagnosticDeriveKind, proc_macro::Span)>,
+    /// Kind of diagnostic that should be derived.
+    pub kind: DiagnosticDeriveKind,
     /// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that
     /// has the actual diagnostic message.
     pub slug: Option<(Path, proc_macro::Span)>,
@@ -143,7 +128,7 @@ impl DiagnosticDeriveBuilder {
     }
 
     /// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct
-    /// attributes like `#[error(..)`, such as the diagnostic kind and slug. Generates
+    /// attributes like `#[diag(..)]`, such as the slug and error code. Generates
     /// diagnostic builder calls for setting error code and creating note/help messages.
     fn generate_structure_code_for_attr(
         &mut self,
@@ -156,15 +141,15 @@ impl DiagnosticDeriveBuilder {
         let name = name.as_str();
         let meta = attr.parse_meta()?;
 
-        let is_help_note_or_warn = matches!(name, "help" | "note" | "warn_");
+        let is_diag = name == "diag";
 
         let nested = match meta {
-            // Most attributes are lists, like `#[error(..)]`/`#[warning(..)]` for most cases or
+            // Most attributes are lists, like `#[diag(..)]` for most cases or
             // `#[help(..)]`/`#[note(..)]` when the user is specifying a alternative slug.
             Meta::List(MetaList { ref nested, .. }) => nested,
             // Subdiagnostics without spans can be applied to the type too, and these are just
-            // paths: `#[help]` and `#[note]`
-            Meta::Path(_) if is_help_note_or_warn => {
+            // paths: `#[help]`, `#[note]` and `#[warn_]`
+            Meta::Path(_) if !is_diag => {
                 let fn_name = if name == "warn_" {
                     Ident::new("warn", attr.span())
                 } else {
@@ -178,23 +163,21 @@ impl DiagnosticDeriveBuilder {
         // Check the kind before doing any further processing so that there aren't misleading
         // "no kind specified" errors if there are failures later.
         match name {
-            "error" => self.kind.set_once((DiagnosticDeriveKind::Error, span)),
-            "warning" => self.kind.set_once((DiagnosticDeriveKind::Warn, span)),
-            "lint" => self.kind.set_once((DiagnosticDeriveKind::Lint, span)),
-            "help" | "note" | "warn_" => (),
+            "error" | "warning" | "lint" => throw_invalid_attr!(attr, &meta, |diag| {
+                diag.help("`error`, `warning` and `lint` have been replaced by `diag`")
+            }),
+            "diag" | "help" | "note" | "warn_" => (),
             _ => throw_invalid_attr!(attr, &meta, |diag| {
-                diag.help(
-                    "only `error`, `warning`, `help`, `note` and `warn_` are valid attributes",
-                )
+                diag.help("only `diag`, `help`, `note` and `warn_` are valid attributes")
             }),
         }
 
-        // First nested element should always be the path, e.g. `#[error(typeck::invalid)]` or
+        // First nested element should always be the path, e.g. `#[diag(typeck::invalid)]` or
         // `#[help(typeck::another_help)]`.
         let mut nested_iter = nested.into_iter();
         if let Some(nested_attr) = nested_iter.next() {
             // Report an error if there are any other list items after the path.
-            if is_help_note_or_warn && nested_iter.next().is_some() {
+            if !is_diag && nested_iter.next().is_some() {
                 throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
                     diag.help(
                         "`help`, `note` and `warn_` struct attributes can only have one argument",
@@ -203,16 +186,16 @@ impl DiagnosticDeriveBuilder {
             }
 
             match nested_attr {
-                NestedMeta::Meta(Meta::Path(path)) if is_help_note_or_warn => {
-                    let fn_name = proc_macro2::Ident::new(name, attr.span());
-                    return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); });
-                }
                 NestedMeta::Meta(Meta::Path(path)) => {
-                    self.slug.set_once((path.clone(), span));
+                    if is_diag {
+                        self.slug.set_once((path.clone(), span));
+                    } else {
+                        let fn_name = proc_macro2::Ident::new(name, attr.span());
+                        return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); });
+                    }
                 }
                 NestedMeta::Meta(meta @ Meta::NameValue(_))
-                    if !is_help_note_or_warn
-                        && meta.path().segments.last().unwrap().ident == "code" =>
+                    if is_diag && meta.path().segments.last().unwrap().ident == "code" =>
                 {
                     // don't error for valid follow-up attributes
                 }
@@ -346,10 +329,20 @@ impl DiagnosticDeriveBuilder {
                 Ok(quote! {})
             }
             "primary_span" => {
-                report_error_if_not_applied_to_span(attr, &info)?;
-                Ok(quote! {
-                    #diag.set_span(#binding);
-                })
+                match self.kind {
+                    DiagnosticDeriveKind::SessionDiagnostic => {
+                        report_error_if_not_applied_to_span(attr, &info)?;
+
+                        Ok(quote! {
+                            #diag.set_span(#binding);
+                        })
+                    }
+                    DiagnosticDeriveKind::LintDiagnostic => {
+                        throw_invalid_attr!(attr, &meta, |diag| {
+                            diag.help("the `primary_span` field attribute is not valid for lint diagnostics")
+                        })
+                    }
+                }
             }
             "label" => {
                 report_error_if_not_applied_to_span(attr, &info)?;
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index 733454cb2a7..2ff21e18ff8 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -23,7 +23,7 @@ use synstructure::Structure;
 /// # extern crate rust_middle;
 /// # use rustc_middle::ty::Ty;
 /// #[derive(SessionDiagnostic)]
-/// #[error(borrowck::move_out_of_borrow, code = "E0505")]
+/// #[diag(borrowck::move_out_of_borrow, code = "E0505")]
 /// pub struct MoveOutOfBorrowError<'tcx> {
 ///     pub name: Ident,
 ///     pub ty: Ty<'tcx>,
@@ -67,7 +67,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 ///
 /// ```ignore (rust)
 /// #[derive(LintDiagnostic)]
-/// #[lint(lint::atomic_ordering_invalid_fail_success)]
+/// #[diag(lint::atomic_ordering_invalid_fail_success)]
 /// pub struct AtomicOrderingInvalidLint {
 ///     method: Symbol,
 ///     success_ordering: Symbol,
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 2f9c13cf817..87d7ab6ed51 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -4,6 +4,8 @@
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_span)]
 #![allow(rustc::default_hash_types)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 #![recursion_limit = "128"]
 
 use synstructure::decl_derive;
@@ -127,9 +129,7 @@ decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
 decl_derive!(
     [SessionDiagnostic, attributes(
         // struct attributes
-        warning,
-        error,
-        lint,
+        diag,
         help,
         note,
         warn_,
@@ -146,9 +146,7 @@ decl_derive!(
 decl_derive!(
     [LintDiagnostic, attributes(
         // struct attributes
-        warning,
-        error,
-        lint,
+        diag,
         help,
         note,
         warn_,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 40dc4fb052d..889001d0a84 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -99,7 +99,7 @@ pub(crate) struct CrateMetadata {
     /// 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.
-    source_map_import_info: OnceCell<Vec<ImportedSourceFile>>,
+    source_map_import_info: Lock<Vec<Option<ImportedSourceFile>>>,
     /// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`.
     def_path_hash_map: DefPathHashMapRef<'static>,
     /// Likewise for ExpnHash.
@@ -143,7 +143,8 @@ pub(crate) struct CrateMetadata {
 }
 
 /// Holds information about a rustc_span::SourceFile imported from another crate.
-/// See `imported_source_files()` for more information.
+/// See `imported_source_file()` for more information.
+#[derive(Clone)]
 struct ImportedSourceFile {
     /// This SourceFile's byte-offset within the source_map of its original crate
     original_start_pos: rustc_span::BytePos,
@@ -160,9 +161,6 @@ pub(super) struct DecodeContext<'a, 'tcx> {
     sess: Option<&'tcx Session>,
     tcx: Option<TyCtxt<'tcx>>,
 
-    // Cache the last used source_file for translating spans as an optimization.
-    last_source_file_index: usize,
-
     lazy_state: LazyState,
 
     // Used for decoding interpret::AllocIds in a cached & thread-safe manner.
@@ -191,7 +189,6 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
             blob: self.blob(),
             sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
             tcx,
-            last_source_file_index: 0,
             lazy_state: LazyState::NoNode,
             alloc_decoding_session: self
                 .cdata()
@@ -527,6 +524,9 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
             bug!("Cannot decode Span without Session.")
         };
 
+        // Index of the file in the corresponding crate's list of encoded files.
+        let metadata_index = u32::decode(decoder);
+
         // There are two possibilities here:
         // 1. This is a 'local span', which is located inside a `SourceFile`
         // that came from this crate. In this case, we use the source map data
@@ -553,10 +553,10 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
         // to be based on the *foreign* crate (e.g. crate C), not the crate
         // we are writing metadata for (e.g. crate B). This allows us to
         // treat the 'local' and 'foreign' cases almost identically during deserialization:
-        // we can call `imported_source_files` for the proper crate, and binary search
+        // we can call `imported_source_file` for the proper crate, and binary search
         // through the returned slice using our span.
-        let imported_source_files = if tag == TAG_VALID_SPAN_LOCAL {
-            decoder.cdata().imported_source_files(sess)
+        let source_file = if tag == TAG_VALID_SPAN_LOCAL {
+            decoder.cdata().imported_source_file(metadata_index, sess)
         } else {
             // When we encode a proc-macro crate, all `Span`s should be encoded
             // with `TAG_VALID_SPAN_LOCAL`
@@ -577,66 +577,65 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
                 cnum
             );
 
-            // Decoding 'foreign' spans should be rare enough that it's
-            // not worth it to maintain a per-CrateNum cache for `last_source_file_index`.
-            // We just set it to 0, to ensure that we don't try to access something out
-            // of bounds for our initial 'guess'
-            decoder.last_source_file_index = 0;
-
             let foreign_data = decoder.cdata().cstore.get_crate_data(cnum);
-            foreign_data.imported_source_files(sess)
+            foreign_data.imported_source_file(metadata_index, sess)
         };
 
-        let source_file = {
-            // Optimize for the case that most spans within a translated item
-            // originate from the same source_file.
-            let last_source_file = &imported_source_files[decoder.last_source_file_index];
-
-            if lo >= last_source_file.original_start_pos && lo <= last_source_file.original_end_pos
-            {
-                last_source_file
-            } else {
-                let index = imported_source_files
-                    .binary_search_by_key(&lo, |source_file| source_file.original_start_pos)
-                    .unwrap_or_else(|index| index - 1);
-
-                // Don't try to cache the index for foreign spans,
-                // as this would require a map from CrateNums to indices
-                if tag == TAG_VALID_SPAN_LOCAL {
-                    decoder.last_source_file_index = index;
-                }
-                &imported_source_files[index]
-            }
-        };
-
-        // Make sure our binary search above is correct.
+        // Make sure our span is well-formed.
         debug_assert!(
-            lo >= source_file.original_start_pos && lo <= source_file.original_end_pos,
-            "Bad binary search: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
+            lo + source_file.original_start_pos <= source_file.original_end_pos,
+            "Malformed encoded span: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
             lo,
             source_file.original_start_pos,
             source_file.original_end_pos
         );
 
-        // Make sure we correctly filtered out invalid spans during encoding
+        // Make sure we correctly filtered out invalid spans during encoding.
         debug_assert!(
-            hi >= source_file.original_start_pos && hi <= source_file.original_end_pos,
-            "Bad binary search: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
+            hi + source_file.original_start_pos <= source_file.original_end_pos,
+            "Malformed encoded span: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
             hi,
             source_file.original_start_pos,
             source_file.original_end_pos
         );
 
-        let lo =
-            (lo + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
-        let hi =
-            (hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
+        let lo = lo + source_file.translated_source_file.start_pos;
+        let hi = hi + source_file.translated_source_file.start_pos;
 
         // Do not try to decode parent for foreign spans.
         Span::new(lo, hi, ctxt, None)
     }
 }
 
+impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Symbol {
+    fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
+        let tag = d.read_u8();
+
+        match tag {
+            SYMBOL_STR => {
+                let s = d.read_str();
+                Symbol::intern(s)
+            }
+            SYMBOL_OFFSET => {
+                // read str offset
+                let pos = d.read_usize();
+                let old_pos = d.opaque.position();
+
+                // move to str ofset and read
+                d.opaque.set_position(pos);
+                let s = d.read_str();
+                let sym = Symbol::intern(s);
+
+                // restore position
+                d.opaque.set_position(old_pos);
+
+                sym
+            }
+            _ => unreachable!(),
+        }
+    }
+}
+
 impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [ty::abstract_const::Node<'tcx>] {
     fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
         ty::codec::RefDecodable::decode(d)
@@ -1453,7 +1452,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     ///
     /// Proc macro crates don't currently export spans, so this function does not have
     /// to work for them.
-    fn imported_source_files(self, sess: &Session) -> &'a [ImportedSourceFile] {
+    fn imported_source_file(self, source_file_index: u32, sess: &Session) -> ImportedSourceFile {
         fn filter<'a>(sess: &Session, path: Option<&'a Path>) -> Option<&'a Path> {
             path.filter(|_| {
                 // Only spend time on further checks if we have what to translate *to*.
@@ -1541,90 +1540,96 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             }
         };
 
-        self.cdata.source_map_import_info.get_or_init(|| {
-            let external_source_map = self.root.source_map.decode(self);
-
-            external_source_map
-                .map(|source_file_to_import| {
-                    // We can't reuse an existing SourceFile, so allocate a new one
-                    // containing the information we need.
-                    let rustc_span::SourceFile {
-                        mut name,
-                        src_hash,
-                        start_pos,
-                        end_pos,
-                        lines,
-                        multibyte_chars,
-                        non_narrow_chars,
-                        normalized_pos,
-                        name_hash,
-                        ..
-                    } = source_file_to_import;
-
-                    // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
-                    // during rust bootstrapping by `remap-debuginfo = true`, and the user
-                    // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
-                    // then we change `name` to a similar state as if the rust was bootstrapped
-                    // with `remap-debuginfo = true`.
-                    // This is useful for testing so that tests about the effects of
-                    // `try_to_translate_virtual_to_real` don't have to worry about how the
-                    // compiler is bootstrapped.
-                    if let Some(virtual_dir) =
-                        &sess.opts.unstable_opts.simulate_remapped_rust_src_base
-                    {
-                        if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
-                            if let rustc_span::FileName::Real(ref mut old_name) = name {
-                                if let rustc_span::RealFileName::LocalPath(local) = old_name {
-                                    if let Ok(rest) = local.strip_prefix(real_dir) {
-                                        *old_name = rustc_span::RealFileName::Remapped {
-                                            local_path: None,
-                                            virtual_name: virtual_dir.join(rest),
-                                        };
-                                    }
+        let mut import_info = self.cdata.source_map_import_info.lock();
+        for _ in import_info.len()..=(source_file_index as usize) {
+            import_info.push(None);
+        }
+        import_info[source_file_index as usize]
+            .get_or_insert_with(|| {
+                let source_file_to_import = self
+                    .root
+                    .source_map
+                    .get(self, source_file_index)
+                    .expect("missing source file")
+                    .decode(self);
+
+                // We can't reuse an existing SourceFile, so allocate a new one
+                // containing the information we need.
+                let rustc_span::SourceFile {
+                    mut name,
+                    src_hash,
+                    start_pos,
+                    end_pos,
+                    lines,
+                    multibyte_chars,
+                    non_narrow_chars,
+                    normalized_pos,
+                    name_hash,
+                    ..
+                } = source_file_to_import;
+
+                // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
+                // during rust bootstrapping by `remap-debuginfo = true`, and the user
+                // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
+                // then we change `name` to a similar state as if the rust was bootstrapped
+                // with `remap-debuginfo = true`.
+                // This is useful for testing so that tests about the effects of
+                // `try_to_translate_virtual_to_real` don't have to worry about how the
+                // compiler is bootstrapped.
+                if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base
+                {
+                    if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
+                        if let rustc_span::FileName::Real(ref mut old_name) = name {
+                            if let rustc_span::RealFileName::LocalPath(local) = old_name {
+                                if let Ok(rest) = local.strip_prefix(real_dir) {
+                                    *old_name = rustc_span::RealFileName::Remapped {
+                                        local_path: None,
+                                        virtual_name: virtual_dir.join(rest),
+                                    };
                                 }
                             }
                         }
                     }
+                }
 
-                    // If this file's path has been remapped to `/rustc/$hash`,
-                    // we might be able to reverse that (also see comments above,
-                    // on `try_to_translate_virtual_to_real`).
-                    try_to_translate_virtual_to_real(&mut name);
-
-                    let source_length = (end_pos - start_pos).to_usize();
-
-                    let local_version = sess.source_map().new_imported_source_file(
-                        name,
-                        src_hash,
-                        name_hash,
-                        source_length,
-                        self.cnum,
-                        lines,
-                        multibyte_chars,
-                        non_narrow_chars,
-                        normalized_pos,
-                        start_pos,
-                        end_pos,
-                    );
-                    debug!(
-                        "CrateMetaData::imported_source_files alloc \
+                // If this file's path has been remapped to `/rustc/$hash`,
+                // we might be able to reverse that (also see comments above,
+                // on `try_to_translate_virtual_to_real`).
+                try_to_translate_virtual_to_real(&mut name);
+
+                let source_length = (end_pos - start_pos).to_usize();
+
+                let local_version = sess.source_map().new_imported_source_file(
+                    name,
+                    src_hash,
+                    name_hash,
+                    source_length,
+                    self.cnum,
+                    lines,
+                    multibyte_chars,
+                    non_narrow_chars,
+                    normalized_pos,
+                    start_pos,
+                    source_file_index,
+                );
+                debug!(
+                    "CrateMetaData::imported_source_files alloc \
                          source_file {:?} original (start_pos {:?} end_pos {:?}) \
                          translated (start_pos {:?} end_pos {:?})",
-                        local_version.name,
-                        start_pos,
-                        end_pos,
-                        local_version.start_pos,
-                        local_version.end_pos
-                    );
+                    local_version.name,
+                    start_pos,
+                    end_pos,
+                    local_version.start_pos,
+                    local_version.end_pos
+                );
 
-                    ImportedSourceFile {
-                        original_start_pos: start_pos,
-                        original_end_pos: end_pos,
-                        translated_source_file: local_version,
-                    }
-                })
-                .collect()
-        })
+                ImportedSourceFile {
+                    original_start_pos: start_pos,
+                    original_end_pos: end_pos,
+                    translated_source_file: local_version,
+                }
+            })
+            .clone()
     }
 
     fn get_generator_diagnostic_data(
@@ -1687,7 +1692,7 @@ impl CrateMetadata {
             trait_impls,
             incoherent_impls: Default::default(),
             raw_proc_macros,
-            source_map_import_info: OnceCell::new(),
+            source_map_import_info: Lock::new(Vec::new()),
             def_path_hash_map,
             expn_hash_map: Default::default(),
             alloc_decoding_state,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 61f16be1d6b..ad2b6846a4b 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -676,6 +676,9 @@ impl CrateStore for CStore {
     }
 
     fn import_source_files(&self, sess: &Session, cnum: CrateNum) {
-        self.get_crate_data(cnum).imported_source_files(sess);
+        let cdata = self.get_crate_data(cnum);
+        for file_index in 0..cdata.root.source_map.size() {
+            cdata.imported_source_file(file_index as u32, sess);
+        }
     }
 }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index f68005c0526..0d3a3efb0d3 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -17,7 +17,6 @@ use rustc_hir::definitions::DefPathData;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::lang_items;
 use rustc_hir::{AnonConst, GenericParamKind};
-use rustc_index::bit_set::GrowableBitSet;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::{
@@ -39,6 +38,7 @@ use rustc_span::{
 };
 use rustc_target::abi::VariantIdx;
 use std::borrow::Borrow;
+use std::collections::hash_map::Entry;
 use std::hash::Hash;
 use std::io::{Read, Seek, Write};
 use std::iter;
@@ -66,15 +66,13 @@ pub(super) struct EncodeContext<'a, 'tcx> {
     // The indices (into the `SourceMap`'s `MonotonicVec`)
     // of all of the `SourceFiles` that we need to serialize.
     // When we serialize a `Span`, we insert the index of its
-    // `SourceFile` into the `GrowableBitSet`.
-    //
-    // This needs to be a `GrowableBitSet` and not a
-    // regular `BitSet` because we may actually import new `SourceFiles`
-    // during metadata encoding, due to executing a query
-    // with a result containing a foreign `Span`.
-    required_source_files: Option<GrowableBitSet<usize>>,
+    // `SourceFile` into the `FxIndexSet`.
+    // The order inside the `FxIndexSet` is used as on-disk
+    // order of `SourceFiles`, and encoded inside `Span`s.
+    required_source_files: Option<FxIndexSet<usize>>,
     is_proc_macro: bool,
     hygiene_ctxt: &'a HygieneEncodeContext,
+    symbol_table: FxHashMap<Symbol, usize>,
 }
 
 /// If the current crate is a proc-macro, returns early with `Lazy:empty()`.
@@ -238,17 +236,15 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
             s.source_file_cache =
                 (source_map.files()[source_file_index].clone(), source_file_index);
         }
+        let (ref source_file, source_file_index) = s.source_file_cache;
+        debug_assert!(source_file.contains(span.lo));
 
-        if !s.source_file_cache.0.contains(span.hi) {
+        if !source_file.contains(span.hi) {
             // Unfortunately, macro expansion still sometimes generates Spans
             // that malformed in this way.
             return TAG_PARTIAL_SPAN.encode(s);
         }
 
-        let source_files = s.required_source_files.as_mut().expect("Already encoded SourceMap!");
-        // Record the fact that we need to encode the data for this `SourceFile`
-        source_files.insert(s.source_file_cache.1);
-
         // There are two possible cases here:
         // 1. This span comes from a 'foreign' crate - e.g. some crate upstream of the
         // crate we are writing metadata for. When the metadata for *this* crate gets
@@ -265,7 +261,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
         // if we're a proc-macro crate.
         // This allows us to avoid loading the dependencies of proc-macro crates: all of
         // the information we need to decode `Span`s is stored in the proc-macro crate.
-        let (tag, lo, hi) = if s.source_file_cache.0.is_imported() && !s.is_proc_macro {
+        let (tag, metadata_index) = if source_file.is_imported() && !s.is_proc_macro {
             // To simplify deserialization, we 'rebase' this span onto the crate it originally came from
             // (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
             // are relative to the source map information for the 'foreign' crate whose CrateNum
@@ -275,29 +271,41 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
             //
             // All of this logic ensures that the final result of deserialization is a 'normal'
             // Span that can be used without any additional trouble.
-            let external_start_pos = {
+            let metadata_index = {
                 // Introduce a new scope so that we drop the 'lock()' temporary
-                match &*s.source_file_cache.0.external_src.lock() {
-                    ExternalSource::Foreign { original_start_pos, .. } => *original_start_pos,
+                match &*source_file.external_src.lock() {
+                    ExternalSource::Foreign { metadata_index, .. } => *metadata_index,
                     src => panic!("Unexpected external source {:?}", src),
                 }
             };
-            let lo = (span.lo - s.source_file_cache.0.start_pos) + external_start_pos;
-            let hi = (span.hi - s.source_file_cache.0.start_pos) + external_start_pos;
 
-            (TAG_VALID_SPAN_FOREIGN, lo, hi)
+            (TAG_VALID_SPAN_FOREIGN, metadata_index)
         } else {
-            (TAG_VALID_SPAN_LOCAL, span.lo, span.hi)
+            // Record the fact that we need to encode the data for this `SourceFile`
+            let source_files =
+                s.required_source_files.as_mut().expect("Already encoded SourceMap!");
+            let (metadata_index, _) = source_files.insert_full(source_file_index);
+            let metadata_index: u32 =
+                metadata_index.try_into().expect("cannot export more than U32_MAX files");
+
+            (TAG_VALID_SPAN_LOCAL, metadata_index)
         };
 
-        tag.encode(s);
-        lo.encode(s);
+        // Encode the start position relative to the file start, so we profit more from the
+        // variable-length integer encoding.
+        let lo = span.lo - source_file.start_pos;
 
         // Encode length which is usually less than span.hi and profits more
         // from the variable-length integer encoding that we use.
-        let len = hi - lo;
+        let len = span.hi - span.lo;
+
+        tag.encode(s);
+        lo.encode(s);
         len.encode(s);
 
+        // Encode the index of the `SourceFile` for the span, in order to make decoding faster.
+        metadata_index.encode(s);
+
         if tag == TAG_VALID_SPAN_FOREIGN {
             // This needs to be two lines to avoid holding the `s.source_file_cache`
             // while calling `cnum.encode(s)`
@@ -307,6 +315,24 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
     }
 }
 
+impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Symbol {
+    fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
+        match s.symbol_table.entry(*self) {
+            Entry::Vacant(o) => {
+                s.opaque.emit_u8(SYMBOL_STR);
+                let pos = s.opaque.position();
+                o.insert(pos);
+                s.emit_str(self.as_str());
+            }
+            Entry::Occupied(o) => {
+                let x = o.get().clone();
+                s.emit_u8(SYMBOL_OFFSET);
+                s.emit_usize(x);
+            }
+        }
+    }
+}
+
 impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
     const CLEAR_CROSS_CRATE: bool = true;
 
@@ -449,7 +475,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.lazy(DefPathHashMapRef::BorrowedFromTcx(self.tcx.def_path_hash_to_def_index_map()))
     }
 
-    fn encode_source_map(&mut self) -> LazyArray<rustc_span::SourceFile> {
+    fn encode_source_map(&mut self) -> LazyTable<u32, LazyValue<rustc_span::SourceFile>> {
         let source_map = self.tcx.sess.source_map();
         let all_source_files = source_map.files();
 
@@ -460,66 +486,64 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let working_directory = &self.tcx.sess.opts.working_dir;
 
-        let adapted = all_source_files
-            .iter()
-            .enumerate()
-            .filter(|(idx, source_file)| {
-                // Only serialize `SourceFile`s that were used
-                // during the encoding of a `Span`
-                required_source_files.contains(*idx) &&
-                // Don't serialize imported `SourceFile`s, unless
-                // we're in a proc-macro crate.
-                (!source_file.is_imported() || self.is_proc_macro)
-            })
-            .map(|(_, source_file)| {
-                // At export time we expand all source file paths to absolute paths because
-                // downstream compilation sessions can have a different compiler working
-                // directory, so relative paths from this or any other upstream crate
-                // won't be valid anymore.
-                //
-                // At this point we also erase the actual on-disk path and only keep
-                // the remapped version -- as is necessary for reproducible builds.
-                match source_file.name {
-                    FileName::Real(ref original_file_name) => {
-                        let adapted_file_name =
-                            source_map.path_mapping().to_embeddable_absolute_path(
-                                original_file_name.clone(),
-                                working_directory,
-                            );
-
-                        if adapted_file_name != *original_file_name {
-                            let mut adapted: SourceFile = (**source_file).clone();
-                            adapted.name = FileName::Real(adapted_file_name);
-                            adapted.name_hash = {
-                                let mut hasher: StableHasher = StableHasher::new();
-                                adapted.name.hash(&mut hasher);
-                                hasher.finish::<u128>()
-                            };
-                            Lrc::new(adapted)
-                        } else {
-                            // Nothing to adapt
-                            source_file.clone()
-                        }
+        let mut adapted = TableBuilder::default();
+
+        // Only serialize `SourceFile`s that were used during the encoding of a `Span`.
+        //
+        // The order in which we encode source files is important here: the on-disk format for
+        // `Span` contains the index of the corresponding `SourceFile`.
+        for (on_disk_index, &source_file_index) in required_source_files.iter().enumerate() {
+            let source_file = &all_source_files[source_file_index];
+            // Don't serialize imported `SourceFile`s, unless we're in a proc-macro crate.
+            assert!(!source_file.is_imported() || self.is_proc_macro);
+
+            // At export time we expand all source file paths to absolute paths because
+            // downstream compilation sessions can have a different compiler working
+            // directory, so relative paths from this or any other upstream crate
+            // won't be valid anymore.
+            //
+            // At this point we also erase the actual on-disk path and only keep
+            // the remapped version -- as is necessary for reproducible builds.
+            let mut source_file = match source_file.name {
+                FileName::Real(ref original_file_name) => {
+                    let adapted_file_name = source_map
+                        .path_mapping()
+                        .to_embeddable_absolute_path(original_file_name.clone(), working_directory);
+
+                    if adapted_file_name != *original_file_name {
+                        let mut adapted: SourceFile = (**source_file).clone();
+                        adapted.name = FileName::Real(adapted_file_name);
+                        adapted.name_hash = {
+                            let mut hasher: StableHasher = StableHasher::new();
+                            adapted.name.hash(&mut hasher);
+                            hasher.finish::<u128>()
+                        };
+                        Lrc::new(adapted)
+                    } else {
+                        // Nothing to adapt
+                        source_file.clone()
                     }
-                    // expanded code, not from a file
-                    _ => source_file.clone(),
-                }
-            })
-            .map(|mut source_file| {
-                // We're serializing this `SourceFile` into our crate metadata,
-                // so mark it as coming from this crate.
-                // This also ensures that we don't try to deserialize the
-                // `CrateNum` for a proc-macro dependency - since proc macro
-                // dependencies aren't loaded when we deserialize a proc-macro,
-                // trying to remap the `CrateNum` would fail.
-                if self.is_proc_macro {
-                    Lrc::make_mut(&mut source_file).cnum = LOCAL_CRATE;
                 }
-                source_file
-            })
-            .collect::<Vec<_>>();
+                // expanded code, not from a file
+                _ => source_file.clone(),
+            };
+
+            // We're serializing this `SourceFile` into our crate metadata,
+            // so mark it as coming from this crate.
+            // This also ensures that we don't try to deserialize the
+            // `CrateNum` for a proc-macro dependency - since proc macro
+            // dependencies aren't loaded when we deserialize a proc-macro,
+            // trying to remap the `CrateNum` would fail.
+            if self.is_proc_macro {
+                Lrc::make_mut(&mut source_file).cnum = LOCAL_CRATE;
+            }
+
+            let on_disk_index: u32 =
+                on_disk_index.try_into().expect("cannot export more than U32_MAX files");
+            adapted.set(on_disk_index, self.lazy(source_file));
+        }
 
-        self.lazy_array(adapted.iter().map(|rc| &**rc))
+        adapted.encode(&mut self.opaque)
     }
 
     fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
@@ -2241,7 +2265,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
 
     let source_map_files = tcx.sess.source_map().files();
     let source_file_cache = (source_map_files[0].clone(), 0);
-    let required_source_files = Some(GrowableBitSet::with_capacity(source_map_files.len()));
+    let required_source_files = Some(FxIndexSet::default());
     drop(source_map_files);
 
     let hygiene_ctxt = HygieneEncodeContext::default();
@@ -2259,6 +2283,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
         required_source_files,
         is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
         hygiene_ctxt: &hygiene_ctxt,
+        symbol_table: Default::default(),
     };
 
     // Encode the rustc version string in a predictable location.
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 8efe5051b01..91d744879fd 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -249,7 +249,7 @@ pub(crate) struct CrateRoot {
 
     def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,
 
-    source_map: LazyArray<rustc_span::SourceFile>,
+    source_map: LazyTable<u32, LazyValue<rustc_span::SourceFile>>,
 
     compiler_builtins: bool,
     needs_allocator: bool,
@@ -445,6 +445,10 @@ const TAG_VALID_SPAN_LOCAL: u8 = 0;
 const TAG_VALID_SPAN_FOREIGN: u8 = 1;
 const TAG_PARTIAL_SPAN: u8 = 2;
 
+// Tags for encoding Symbol's
+const SYMBOL_STR: u8 = 0;
+const SYMBOL_OFFSET: u8 = 1;
+
 pub fn provide(providers: &mut Providers) {
     encoder::provide(providers);
     decoder::provide(providers);
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 834c114ee1c..a1c111ae372 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -79,7 +79,7 @@ impl<'tcx> ConstValue<'tcx> {
     }
 
     pub fn try_to_scalar_int(&self) -> Option<ScalarInt> {
-        Some(self.try_to_scalar()?.assert_int())
+        self.try_to_scalar()?.try_to_int().ok()
     }
 
     pub fn try_to_bits(&self, size: Size) -> Option<u128> {
@@ -368,6 +368,7 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
     }
 
     #[inline(always)]
+    #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
     pub fn assert_int(self) -> ScalarInt {
         self.try_to_int().unwrap()
     }
@@ -389,6 +390,7 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
     }
 
     #[inline(always)]
+    #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980)
     pub fn assert_bits(self, target_size: Size) -> u128 {
         self.to_bits(target_size).unwrap()
     }
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index dd9f8795f94..594c14a642d 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -2,7 +2,7 @@
 
 use crate::mir::{Body, ConstantKind, Promoted};
 use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
@@ -115,21 +115,6 @@ pub enum UnusedUnsafe {
     /// `unsafe` block nested under another (used) `unsafe` block
     /// > ``… because it's nested under this `unsafe` block``
     InUnsafeBlock(hir::HirId),
-    /// `unsafe` block nested under `unsafe fn`
-    /// > ``… because it's nested under this `unsafe fn` ``
-    ///
-    /// the second HirId here indicates the first usage of the `unsafe` block,
-    /// which allows retrieval of the LintLevelSource for why that operation would
-    /// have been permitted without the block
-    InUnsafeFn(hir::HirId, hir::HirId),
-}
-
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UsedUnsafeBlockData {
-    SomeDisallowedInUnsafeFn,
-    // the HirId here indicates the first usage of the `unsafe` block
-    // (i.e. the one that's first encountered in the MIR traversal of the unsafety check)
-    AllAllowedInUnsafeFn(hir::HirId),
 }
 
 #[derive(TyEncodable, TyDecodable, HashStable, Debug)]
@@ -138,10 +123,7 @@ pub struct UnsafetyCheckResult {
     pub violations: Vec<UnsafetyViolation>,
 
     /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
-    ///
-    /// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether
-    /// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`.
-    pub used_unsafe_blocks: FxHashMap<hir::HirId, UsedUnsafeBlockData>,
+    pub used_unsafe_blocks: FxHashSet<hir::HirId>,
 
     /// This is `Some` iff the item is not a closure.
     pub unused_unsafes: Option<Vec<(hir::HirId, UnusedUnsafe)>>,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index cfc75f673c8..8a727d9a182 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -770,6 +770,7 @@ rustc_queries! {
         desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
+        cycle_delay_bug
     }
 
     /// Performs lint checking for the module.
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 8e6af936ded..ac89bec702e 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -74,6 +74,18 @@ pub enum TypeError<'tcx> {
     TargetFeatureCast(DefId),
 }
 
+impl TypeError<'_> {
+    pub fn involves_regions(self) -> bool {
+        match self {
+            TypeError::RegionsDoesNotOutlive(_, _)
+            | TypeError::RegionsInsufficientlyPolymorphic(_, _)
+            | TypeError::RegionsOverlyPolymorphic(_, _)
+            | TypeError::RegionsPlaceholderMismatch => true,
+            _ => false,
+        }
+    }
+}
+
 /// Explains the source of a type err in a short, human readable way. This is meant to be placed
 /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
 /// afterwards to present additional details, particularly when it comes to lifetime-related
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 52c3a38861e..0070575f213 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1617,6 +1617,10 @@ impl<'tcx> Region<'tcx> {
             _ => self.is_free(),
         }
     }
+
+    pub fn is_var(self) -> bool {
+        matches!(self.kind(), ty::ReVar(_))
+    }
 }
 
 /// Type utilities
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 864caf0ba31..f0b0456c4b9 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -75,10 +75,11 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
         match self.safety_context {
             SafetyContext::BuiltinUnsafeBlock => {}
             SafetyContext::UnsafeBlock { ref mut used, .. } => {
-                if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed {
-                    // Mark this block as useful
-                    *used = true;
-                }
+                // Mark this block as useful (even inside `unsafe fn`, where it is technically
+                // redundant -- but we want to eventually enable `unsafe_op_in_unsafe_fn` by
+                // default which will require those blocks:
+                // https://github.com/rust-lang/rust/issues/71668#issuecomment-1203075594).
+                *used = true;
             }
             SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
             SafetyContext::UnsafeFn => {
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index d564f480166..0f5fd77f7ab 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -1,17 +1,16 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::hir_id::HirId;
 use rustc_hir::intravisit;
 use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
+use rustc_middle::mir::*;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, TyCtxt};
-use rustc_middle::{lint, mir::*};
 use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
 use rustc_session::lint::Level;
 
-use std::collections::hash_map;
 use std::ops::Bound;
 
 pub struct UnsafetyChecker<'a, 'tcx> {
@@ -23,10 +22,7 @@ pub struct UnsafetyChecker<'a, 'tcx> {
     param_env: ty::ParamEnv<'tcx>,
 
     /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
-    ///
-    /// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether
-    /// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`.
-    used_unsafe_blocks: FxHashMap<HirId, UsedUnsafeBlockData>,
+    used_unsafe_blocks: FxHashSet<HirId>,
 }
 
 impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
@@ -130,10 +126,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
                 &AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => {
                     let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
                         self.tcx.unsafety_check_result(def_id);
-                    self.register_violations(
-                        violations,
-                        used_unsafe_blocks.iter().map(|(&h, &d)| (h, d)),
-                    );
+                    self.register_violations(violations, used_unsafe_blocks.iter().copied());
                 }
             },
             _ => {}
@@ -257,22 +250,8 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
     fn register_violations<'a>(
         &mut self,
         violations: impl IntoIterator<Item = &'a UnsafetyViolation>,
-        new_used_unsafe_blocks: impl IntoIterator<Item = (HirId, UsedUnsafeBlockData)>,
+        new_used_unsafe_blocks: impl IntoIterator<Item = HirId>,
     ) {
-        use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
-
-        let update_entry = |this: &mut Self, hir_id, new_usage| {
-            match this.used_unsafe_blocks.entry(hir_id) {
-                hash_map::Entry::Occupied(mut entry) => {
-                    if new_usage == SomeDisallowedInUnsafeFn {
-                        *entry.get_mut() = SomeDisallowedInUnsafeFn;
-                    }
-                }
-                hash_map::Entry::Vacant(entry) => {
-                    entry.insert(new_usage);
-                }
-            };
-        };
         let safety = self.body.source_scopes[self.source_info.scope]
             .local_data
             .as_ref()
@@ -299,22 +278,14 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
                 }
             }),
             Safety::BuiltinUnsafe => {}
-            Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|violation| {
-                update_entry(
-                    self,
-                    hir_id,
-                    match self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, violation.lint_root).0
-                    {
-                        Level::Allow => AllAllowedInUnsafeFn(violation.lint_root),
-                        _ => SomeDisallowedInUnsafeFn,
-                    },
-                )
+            Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|_violation| {
+                self.used_unsafe_blocks.insert(hir_id);
             }),
         };
 
-        new_used_unsafe_blocks
-            .into_iter()
-            .for_each(|(hir_id, usage_data)| update_entry(self, hir_id, usage_data));
+        new_used_unsafe_blocks.into_iter().for_each(|hir_id| {
+            self.used_unsafe_blocks.insert(hir_id);
+        });
     }
     fn check_mut_borrowing_layout_constrained_field(
         &mut self,
@@ -411,34 +382,28 @@ enum Context {
 
 struct UnusedUnsafeVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    used_unsafe_blocks: &'a FxHashMap<HirId, UsedUnsafeBlockData>,
+    used_unsafe_blocks: &'a FxHashSet<HirId>,
     context: Context,
     unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>,
 }
 
 impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
     fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
-        use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
-
         if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules {
             let used = match self.tcx.lint_level_at_node(UNUSED_UNSAFE, block.hir_id) {
-                (Level::Allow, _) => Some(SomeDisallowedInUnsafeFn),
-                _ => self.used_unsafe_blocks.get(&block.hir_id).copied(),
+                (Level::Allow, _) => true,
+                _ => self.used_unsafe_blocks.contains(&block.hir_id),
             };
             let unused_unsafe = match (self.context, used) {
-                (_, None) => UnusedUnsafe::Unused,
-                (Context::Safe, Some(_))
-                | (Context::UnsafeFn(_), Some(SomeDisallowedInUnsafeFn)) => {
+                (_, false) => UnusedUnsafe::Unused,
+                (Context::Safe, true) | (Context::UnsafeFn(_), true) => {
                     let previous_context = self.context;
                     self.context = Context::UnsafeBlock(block.hir_id);
                     intravisit::walk_block(self, block);
                     self.context = previous_context;
                     return;
                 }
-                (Context::UnsafeFn(hir_id), Some(AllAllowedInUnsafeFn(lint_root))) => {
-                    UnusedUnsafe::InUnsafeFn(hir_id, lint_root)
-                }
-                (Context::UnsafeBlock(hir_id), Some(_)) => UnusedUnsafe::InUnsafeBlock(hir_id),
+                (Context::UnsafeBlock(hir_id), true) => UnusedUnsafe::InUnsafeBlock(hir_id),
             };
             self.unused_unsafes.push((block.hir_id, unused_unsafe));
         }
@@ -462,7 +427,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
 fn check_unused_unsafe(
     tcx: TyCtxt<'_>,
     def_id: LocalDefId,
-    used_unsafe_blocks: &FxHashMap<HirId, UsedUnsafeBlockData>,
+    used_unsafe_blocks: &FxHashSet<HirId>,
 ) -> Vec<(HirId, UnusedUnsafe)> {
     let body_id = tcx.hir().maybe_body_owned_by(def_id);
 
@@ -535,25 +500,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
                     "because it's nested under this `unsafe` block",
                 );
             }
-            UnusedUnsafe::InUnsafeFn(id, usage_lint_root) => {
-                db.span_label(
-                    tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
-                    "because it's nested under this `unsafe` fn",
-                )
-                .note(
-                    "this `unsafe` block does contain unsafe operations, \
-                    but those are already allowed in an `unsafe fn`",
-                );
-                let (level, source) =
-                    tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, usage_lint_root);
-                assert_eq!(level, Level::Allow);
-                lint::explain_lint_level_source(
-                    UNSAFE_OP_IN_UNSAFE_FN,
-                    Level::Allow,
-                    source,
-                    &mut db,
-                );
-            }
         }
 
         db.emit();
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 1e46b0a0e81..6704d3462f4 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -10,6 +10,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
 use rustc_session::config::OptLevel;
+use rustc_span::def_id::DefId;
 use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
 use rustc_target::spec::abi::Abi;
 
@@ -103,8 +104,12 @@ struct Inliner<'tcx> {
     param_env: ParamEnv<'tcx>,
     /// Caller codegen attributes.
     codegen_fn_attrs: &'tcx CodegenFnAttrs,
-    /// Stack of inlined Instances.
-    history: Vec<ty::Instance<'tcx>>,
+    /// Stack of inlined instances.
+    /// We only check the `DefId` and not the substs because we want to
+    /// avoid inlining cases of polymorphic recursion.
+    /// The number of `DefId`s is finite, so checking history is enough
+    /// to ensure that we do not loop endlessly while inlining.
+    history: Vec<DefId>,
     /// Indicates that the caller body has been modified.
     changed: bool,
 }
@@ -132,7 +137,7 @@ impl<'tcx> Inliner<'tcx> {
                 Ok(new_blocks) => {
                     debug!("inlined {}", callsite.callee);
                     self.changed = true;
-                    self.history.push(callsite.callee);
+                    self.history.push(callsite.callee.def_id());
                     self.process_blocks(caller_body, new_blocks);
                     self.history.pop();
                 }
@@ -308,7 +313,7 @@ impl<'tcx> Inliner<'tcx> {
                     return None;
                 }
 
-                if self.history.contains(&callee) {
+                if self.history.contains(&callee.def_id()) {
                     return None;
                 }
 
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 93e70e9abda..7beec270e3b 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -244,7 +244,7 @@ impl MultiSugg {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(parser::maybe_report_ambiguous_plus)]
+#[diag(parser::maybe_report_ambiguous_plus)]
 struct AmbiguousPlus {
     pub sum_ty: String,
     #[primary_span]
@@ -253,7 +253,7 @@ struct AmbiguousPlus {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
+#[diag(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
 struct BadTypePlus {
     pub ty: String,
     #[primary_span]
@@ -287,7 +287,7 @@ pub enum BadTypePlusSub {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(parser::maybe_recover_from_bad_qpath_stage_2)]
+#[diag(parser::maybe_recover_from_bad_qpath_stage_2)]
 struct BadQPathStage2 {
     #[primary_span]
     #[suggestion(applicability = "maybe-incorrect")]
@@ -296,7 +296,7 @@ struct BadQPathStage2 {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(parser::incorrect_semicolon)]
+#[diag(parser::incorrect_semicolon)]
 struct IncorrectSemicolon<'a> {
     #[primary_span]
     #[suggestion_short(applicability = "machine-applicable")]
@@ -307,7 +307,7 @@ struct IncorrectSemicolon<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(parser::incorrect_use_of_await)]
+#[diag(parser::incorrect_use_of_await)]
 struct IncorrectUseOfAwait {
     #[primary_span]
     #[suggestion(parser::parentheses_suggestion, applicability = "machine-applicable")]
@@ -315,7 +315,7 @@ struct IncorrectUseOfAwait {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(parser::incorrect_use_of_await)]
+#[diag(parser::incorrect_use_of_await)]
 struct IncorrectAwait {
     #[primary_span]
     span: Span,
@@ -326,7 +326,7 @@ struct IncorrectAwait {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(parser::in_in_typo)]
+#[diag(parser::in_in_typo)]
 struct InInTypo {
     #[primary_span]
     span: Span,
@@ -334,6 +334,35 @@ struct InInTypo {
     sugg_span: Span,
 }
 
+#[derive(SessionDiagnostic)]
+#[diag(parser::invalid_variable_declaration)]
+pub struct InvalidVariableDeclaration {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sub: InvalidVariableDeclarationSub,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub enum InvalidVariableDeclarationSub {
+    #[suggestion(
+        parser::switch_mut_let_order,
+        applicability = "maybe-incorrect",
+        code = "let mut"
+    )]
+    SwitchMutLetOrder(#[primary_span] Span),
+    #[suggestion(
+        parser::missing_let_before_mut,
+        applicability = "machine-applicable",
+        code = "let mut"
+    )]
+    MissingLet(#[primary_span] Span),
+    #[suggestion(parser::use_let_not_auto, applicability = "machine-applicable", code = "let")]
+    UseLetNotAuto(#[primary_span] Span),
+    #[suggestion(parser::use_let_not_var, applicability = "machine-applicable", code = "let")]
+    UseLetNotVar(#[primary_span] Span),
+}
+
 // SnapshotParser is used to create a snapshot of the parser
 // without causing duplicate errors being emitted when the `Parser`
 // is dropped.
@@ -611,6 +640,15 @@ impl<'a> Parser<'a> {
                     appl,
                 );
             }
+
+            if ["def", "fun", "func", "function"].contains(&symbol.as_str()) {
+                err.span_suggestion_short(
+                    self.prev_token.span,
+                    &format!("write `fn` instead of `{symbol}` to declare a function"),
+                    "fn",
+                    appl,
+                );
+            }
         }
 
         // Add suggestion for a missing closing angle bracket if '>' is included in expected_tokens
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 9d6d632c2e8..df092f55bfa 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1492,11 +1492,11 @@ impl<'a> Parser<'a> {
                 self.struct_span_err(path.span, "macros cannot use qualified paths").emit();
             }
             let lo = path.span;
-            let mac = MacCall {
+            let mac = P(MacCall {
                 path,
                 args: self.parse_mac_args()?,
                 prior_type_ascription: self.last_type_ascription,
-            };
+            });
             (lo.to(self.prev_token.span), ExprKind::MacCall(mac))
         } else if self.check(&token::OpenDelim(Delimiter::Brace)) &&
             let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path) {
@@ -1750,8 +1750,8 @@ impl<'a> Parser<'a> {
             Some(lit) => match lit.kind {
                 ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
                     style,
-                    symbol: lit.token.symbol,
-                    suffix: lit.token.suffix,
+                    symbol: lit.token_lit.symbol,
+                    suffix: lit.token_lit.suffix,
                     span: lit.span,
                     symbol_unescaped,
                 }),
@@ -1828,7 +1828,7 @@ impl<'a> Parser<'a> {
                 let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
                 let symbol = Symbol::intern(&suffixless_lit.to_string());
                 let lit = token::Lit::new(token::Err, symbol, lit.suffix);
-                Some(Lit::from_lit_token(lit, span).unwrap_or_else(|_| unreachable!()))
+                Some(Lit::from_token_lit(lit, span).unwrap_or_else(|_| unreachable!()))
             }
         }
     }
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 1acfd93d86f..5e5f2fd7d9f 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -314,7 +314,6 @@ impl<'a> Parser<'a> {
                 span: lo.to(self.prev_token.span),
                 lhs_ty: ty,
                 rhs_ty,
-                id: ast::DUMMY_NODE_ID,
             }))
         } else {
             self.maybe_recover_bounds_doubled_colon(&ty)?;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index f3f070e6eb0..cd3c982ce81 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -287,7 +287,7 @@ impl<'a> Parser<'a> {
             return Ok(None);
         } else if macros_allowed && self.check_path() {
             // MACRO INVOCATION ITEM
-            (Ident::empty(), ItemKind::MacCall(self.parse_item_macro(vis)?))
+            (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?)))
         } else {
             return Ok(None);
         };
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 98c974420eb..42bf8898447 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -665,7 +665,7 @@ impl<'a> Parser<'a> {
     fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> {
         self.bump();
         let args = self.parse_mac_args()?;
-        let mac = MacCall { path, args, prior_type_ascription: self.last_type_ascription };
+        let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
         Ok(PatKind::MacCall(mac))
     }
 
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 8332c171a9c..fc7fb866f11 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -527,7 +527,7 @@ impl<'a> Parser<'a> {
                         Ok(ident_gen_args) => ident_gen_args,
                         Err(()) => return Ok(Some(AngleBracketedArg::Arg(arg))),
                     };
-                    if binder.is_some() {
+                    if binder {
                         // FIXME(compiler-errors): this could be improved by suggesting lifting
                         // this up to the trait, at least before this becomes real syntax.
                         // e.g. `Trait<for<'a> Assoc = Ty>` -> `for<'a> Trait<Assoc = Ty>`
@@ -720,28 +720,24 @@ impl<'a> Parser<'a> {
 
     /// Given a arg inside of generics, we try to destructure it as if it were the LHS in
     /// `LHS = ...`, i.e. an associated type binding.
-    /// This returns (optionally, if they are present) any `for<'a, 'b>` binder args, the
+    /// This returns a bool indicating if there are any `for<'a, 'b>` binder args, the
     /// identifier, and any GAT arguments.
     fn get_ident_from_generic_arg(
         &self,
         gen_arg: &GenericArg,
-    ) -> Result<(Option<Vec<ast::GenericParam>>, Ident, Option<GenericArgs>), ()> {
+    ) -> Result<(bool, Ident, Option<GenericArgs>), ()> {
         if let GenericArg::Type(ty) = gen_arg {
             if let ast::TyKind::Path(qself, path) = &ty.kind
                 && qself.is_none()
                 && let [seg] = path.segments.as_slice()
             {
-                return Ok((None, seg.ident, seg.args.as_deref().cloned()));
+                return Ok((false, seg.ident, seg.args.as_deref().cloned()));
             } else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
                 && let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None)] =
                     bounds.as_slice()
                 && let [seg] = trait_ref.trait_ref.path.segments.as_slice()
             {
-                return Ok((
-                    Some(trait_ref.bound_generic_params.clone()),
-                    seg.ident,
-                    seg.args.as_deref().cloned(),
-                ));
+                return Ok((true, seg.ident, seg.args.as_deref().cloned()));
             }
         }
         Err(())
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ade0f4fbc86..12b1a37e022 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -1,5 +1,7 @@
 use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
-use super::diagnostics::{AttemptLocalParseRecovery, Error};
+use super::diagnostics::{
+    AttemptLocalParseRecovery, Error, InvalidVariableDeclaration, InvalidVariableDeclarationSub,
+};
 use super::expr::LhsExpr;
 use super::pat::RecoverComma;
 use super::path::PathStyle;
@@ -34,7 +36,7 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    /// If `force_capture` is true, forces collection of tokens regardless of whether
+    /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of whether
     /// or not we have attributes
     pub(crate) fn parse_stmt_without_recovery(
         &mut self,
@@ -58,28 +60,22 @@ impl<'a> Parser<'a> {
         if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) {
             self.bump();
             let mut_let_span = lo.to(self.token.span);
-            self.struct_span_err(mut_let_span, "invalid variable declaration")
-                .span_suggestion(
-                    mut_let_span,
-                    "switch the order of `mut` and `let`",
-                    "let mut",
-                    Applicability::MaybeIncorrect,
-                )
-                .emit();
+            self.sess.emit_err(InvalidVariableDeclaration {
+                span: mut_let_span,
+                sub: InvalidVariableDeclarationSub::SwitchMutLetOrder(mut_let_span),
+            });
         }
 
         Ok(Some(if self.token.is_keyword(kw::Let) {
             self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
         } else if self.is_kw_followed_by_ident(kw::Mut) {
-            self.recover_stmt_local(lo, attrs, "missing keyword", "let mut")?
+            self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)?
         } else if self.is_kw_followed_by_ident(kw::Auto) {
             self.bump(); // `auto`
-            let msg = "write `let` instead of `auto` to introduce a new variable";
-            self.recover_stmt_local(lo, attrs, msg, "let")?
+            self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)?
         } else if self.is_kw_followed_by_ident(sym::var) {
             self.bump(); // `var`
-            let msg = "write `let` instead of `var` to introduce a new variable";
-            self.recover_stmt_local(lo, attrs, msg, "let")?
+            self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)?
         } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
             // We have avoided contextual keywords like `union`, items with `crate` visibility,
             // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
@@ -181,7 +177,7 @@ impl<'a> Parser<'a> {
             None => unreachable!(),
         };
 
-        let mac = MacCall { path, args, prior_type_ascription: self.last_type_ascription };
+        let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription });
 
         let kind = if (style == MacStmtStyle::Braces
             && self.token != token::Dot
@@ -217,13 +213,10 @@ impl<'a> Parser<'a> {
         &mut self,
         lo: Span,
         attrs: AttrWrapper,
-        msg: &str,
-        sugg: &str,
+        subdiagnostic: fn(Span) -> InvalidVariableDeclarationSub,
     ) -> PResult<'a, Stmt> {
         let stmt = self.recover_local_after_let(lo, attrs)?;
-        self.struct_span_err(lo, "invalid variable declaration")
-            .span_suggestion(lo, msg, sugg, Applicability::MachineApplicable)
-            .emit();
+        self.sess.emit_err(InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) });
         Ok(stmt)
     }
 
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 31b40a83e60..76b710095d7 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -598,11 +598,11 @@ impl<'a> Parser<'a> {
         let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
         if self.eat(&token::Not) {
             // Macro invocation in type position
-            Ok(TyKind::MacCall(MacCall {
+            Ok(TyKind::MacCall(P(MacCall {
                 path,
                 args: self.parse_mac_args()?,
                 prior_type_ascription: self.last_type_ascription,
-            }))
+            })))
         } else if allow_plus == AllowPlus::Yes && self.check_plus() {
             // `Trait1 + Trait2 + 'a`
             self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 4890fade50f..e4842d2afb7 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -9,6 +9,8 @@
     html_playground_url = "https://play.rust-lang.org/",
     test(attr(deny(warnings)))
 )]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 // We want to be able to build this crate with a stable compiler, so no
 // `#![feature]` attributes should be added.
 
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index cd465380867..383982013d9 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -3,37 +3,37 @@ use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
 use rustc_span::{Span, Symbol};
 
 #[derive(LintDiagnostic)]
-#[lint(passes::outer_crate_level_attr)]
+#[diag(passes::outer_crate_level_attr)]
 pub struct OuterCrateLevelAttr;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::inner_crate_level_attr)]
+#[diag(passes::inner_crate_level_attr)]
 pub struct InnerCrateLevelAttr;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::ignored_attr_with_macro)]
+#[diag(passes::ignored_attr_with_macro)]
 pub struct IgnoredAttrWithMacro<'a> {
     pub sym: &'a str,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::ignored_attr)]
+#[diag(passes::ignored_attr)]
 pub struct IgnoredAttr<'a> {
     pub sym: &'a str,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::inline_ignored_function_prototype)]
+#[diag(passes::inline_ignored_function_prototype)]
 pub struct IgnoredInlineAttrFnProto;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::inline_ignored_constants)]
+#[diag(passes::inline_ignored_constants)]
 #[warn_]
 #[note]
 pub struct IgnoredInlineAttrConstants;
 
 #[derive(SessionDiagnostic)]
-#[error(passes::inline_not_fn_or_closure, code = "E0518")]
+#[diag(passes::inline_not_fn_or_closure, code = "E0518")]
 pub struct InlineNotFnOrClosure {
     #[primary_span]
     pub attr_span: Span,
@@ -42,19 +42,19 @@ pub struct InlineNotFnOrClosure {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::no_coverage_ignored_function_prototype)]
+#[diag(passes::no_coverage_ignored_function_prototype)]
 pub struct IgnoredNoCoverageFnProto;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::no_coverage_propagate)]
+#[diag(passes::no_coverage_propagate)]
 pub struct IgnoredNoCoveragePropagate;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::no_coverage_fn_defn)]
+#[diag(passes::no_coverage_fn_defn)]
 pub struct IgnoredNoCoverageFnDefn;
 
 #[derive(SessionDiagnostic)]
-#[error(passes::no_coverage_not_coverable, code = "E0788")]
+#[diag(passes::no_coverage_not_coverable, code = "E0788")]
 pub struct IgnoredNoCoverageNotCoverable {
     #[primary_span]
     pub attr_span: Span,
@@ -63,7 +63,7 @@ pub struct IgnoredNoCoverageNotCoverable {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_fn)]
+#[diag(passes::should_be_applied_to_fn)]
 pub struct AttrShouldBeAppliedToFn {
     #[primary_span]
     pub attr_span: Span,
@@ -72,14 +72,14 @@ pub struct AttrShouldBeAppliedToFn {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::naked_tracked_caller, code = "E0736")]
+#[diag(passes::naked_tracked_caller, code = "E0736")]
 pub struct NakedTrackedCaller {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_fn, code = "E0739")]
+#[diag(passes::should_be_applied_to_fn, code = "E0739")]
 pub struct TrackedCallerWrongLocation {
     #[primary_span]
     pub attr_span: Span,
@@ -88,7 +88,7 @@ pub struct TrackedCallerWrongLocation {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_struct_enum, code = "E0701")]
+#[diag(passes::should_be_applied_to_struct_enum, code = "E0701")]
 pub struct NonExhaustiveWrongLocation {
     #[primary_span]
     pub attr_span: Span,
@@ -97,7 +97,7 @@ pub struct NonExhaustiveWrongLocation {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_trait)]
+#[diag(passes::should_be_applied_to_trait)]
 pub struct AttrShouldBeAppliedToTrait {
     #[primary_span]
     pub attr_span: Span,
@@ -106,11 +106,11 @@ pub struct AttrShouldBeAppliedToTrait {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::target_feature_on_statement)]
+#[diag(passes::target_feature_on_statement)]
 pub struct TargetFeatureOnStatement;
 
 #[derive(SessionDiagnostic)]
-#[error(passes::should_be_applied_to_static)]
+#[diag(passes::should_be_applied_to_static)]
 pub struct AttrShouldBeAppliedToStatic {
     #[primary_span]
     pub attr_span: Span,
@@ -119,7 +119,7 @@ pub struct AttrShouldBeAppliedToStatic {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_expect_str)]
+#[diag(passes::doc_expect_str)]
 pub struct DocExpectStr<'a> {
     #[primary_span]
     pub attr_span: Span,
@@ -127,7 +127,7 @@ pub struct DocExpectStr<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_empty)]
+#[diag(passes::doc_alias_empty)]
 pub struct DocAliasEmpty<'a> {
     #[primary_span]
     pub span: Span,
@@ -135,7 +135,7 @@ pub struct DocAliasEmpty<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_bad_char)]
+#[diag(passes::doc_alias_bad_char)]
 pub struct DocAliasBadChar<'a> {
     #[primary_span]
     pub span: Span,
@@ -144,7 +144,7 @@ pub struct DocAliasBadChar<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_start_end)]
+#[diag(passes::doc_alias_start_end)]
 pub struct DocAliasStartEnd<'a> {
     #[primary_span]
     pub span: Span,
@@ -152,7 +152,7 @@ pub struct DocAliasStartEnd<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_bad_location)]
+#[diag(passes::doc_alias_bad_location)]
 pub struct DocAliasBadLocation<'a> {
     #[primary_span]
     pub span: Span,
@@ -161,7 +161,7 @@ pub struct DocAliasBadLocation<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_not_an_alias)]
+#[diag(passes::doc_alias_not_an_alias)]
 pub struct DocAliasNotAnAlias<'a> {
     #[primary_span]
     pub span: Span,
@@ -169,42 +169,42 @@ pub struct DocAliasNotAnAlias<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_alias_duplicated)]
+#[diag(passes::doc_alias_duplicated)]
 pub struct DocAliasDuplicated {
     #[label]
     pub first_defn: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_not_string_literal)]
+#[diag(passes::doc_alias_not_string_literal)]
 pub struct DocAliasNotStringLiteral {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_alias_malformed)]
+#[diag(passes::doc_alias_malformed)]
 pub struct DocAliasMalformed {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_empty_mod)]
+#[diag(passes::doc_keyword_empty_mod)]
 pub struct DocKeywordEmptyMod {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_not_mod)]
+#[diag(passes::doc_keyword_not_mod)]
 pub struct DocKeywordNotMod {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_invalid_ident)]
+#[diag(passes::doc_keyword_invalid_ident)]
 pub struct DocKeywordInvalidIdent {
     #[primary_span]
     pub span: Span,
@@ -212,21 +212,21 @@ pub struct DocKeywordInvalidIdent {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_fake_variadic_not_valid)]
+#[diag(passes::doc_fake_variadic_not_valid)]
 pub struct DocFakeVariadicNotValid {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_keyword_only_impl)]
+#[diag(passes::doc_keyword_only_impl)]
 pub struct DocKeywordOnlyImpl {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_inline_conflict)]
+#[diag(passes::doc_inline_conflict)]
 #[help]
 pub struct DocKeywordConflict {
     #[primary_span]
@@ -234,7 +234,7 @@ pub struct DocKeywordConflict {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_inline_only_use)]
+#[diag(passes::doc_inline_only_use)]
 #[note]
 pub struct DocInlineOnlyUse {
     #[label]
@@ -244,7 +244,7 @@ pub struct DocInlineOnlyUse {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::doc_attr_not_crate_level)]
+#[diag(passes::doc_attr_not_crate_level)]
 pub struct DocAttrNotCrateLevel<'a> {
     #[primary_span]
     pub span: Span,
@@ -252,27 +252,27 @@ pub struct DocAttrNotCrateLevel<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown)]
+#[diag(passes::doc_test_unknown)]
 pub struct DocTestUnknown {
     pub path: String,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_test_takes_list)]
+#[diag(passes::doc_test_takes_list)]
 pub struct DocTestTakesList;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_primitive)]
+#[diag(passes::doc_primitive)]
 pub struct DocPrimitive;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown_any)]
+#[diag(passes::doc_test_unknown_any)]
 pub struct DocTestUnknownAny {
     pub path: String,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown_spotlight)]
+#[diag(passes::doc_test_unknown_spotlight)]
 #[note]
 #[note(passes::no_op_note)]
 pub struct DocTestUnknownSpotlight {
@@ -282,7 +282,7 @@ pub struct DocTestUnknownSpotlight {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_test_unknown_include)]
+#[diag(passes::doc_test_unknown_include)]
 pub struct DocTestUnknownInclude {
     pub path: String,
     pub value: String,
@@ -292,11 +292,11 @@ pub struct DocTestUnknownInclude {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::doc_invalid)]
+#[diag(passes::doc_invalid)]
 pub struct DocInvalid;
 
 #[derive(SessionDiagnostic)]
-#[error(passes::pass_by_value)]
+#[diag(passes::pass_by_value)]
 pub struct PassByValue {
     #[primary_span]
     pub attr_span: Span,
@@ -305,7 +305,7 @@ pub struct PassByValue {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::allow_incoherent_impl)]
+#[diag(passes::allow_incoherent_impl)]
 pub struct AllowIncoherentImpl {
     #[primary_span]
     pub attr_span: Span,
@@ -314,7 +314,7 @@ pub struct AllowIncoherentImpl {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::has_incoherent_inherent_impl)]
+#[diag(passes::has_incoherent_inherent_impl)]
 pub struct HasIncoherentInherentImpl {
     #[primary_span]
     pub attr_span: Span,
@@ -323,21 +323,21 @@ pub struct HasIncoherentInherentImpl {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::must_use_async)]
+#[diag(passes::must_use_async)]
 pub struct MustUseAsync {
     #[label]
     pub span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::must_use_no_effect)]
+#[diag(passes::must_use_no_effect)]
 pub struct MustUseNoEffect {
     pub article: &'static str,
     pub target: rustc_hir::Target,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::must_not_suspend)]
+#[diag(passes::must_not_suspend)]
 pub struct MustNotSuspend {
     #[primary_span]
     pub attr_span: Span,
@@ -346,7 +346,7 @@ pub struct MustNotSuspend {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::cold)]
+#[diag(passes::cold)]
 #[warn_]
 pub struct Cold {
     #[label]
@@ -354,7 +354,7 @@ pub struct Cold {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::link)]
+#[diag(passes::link)]
 #[warn_]
 pub struct Link {
     #[label]
@@ -362,7 +362,7 @@ pub struct Link {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::link_name)]
+#[diag(passes::link_name)]
 #[warn_]
 pub struct LinkName<'a> {
     #[help]
@@ -373,7 +373,7 @@ pub struct LinkName<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::no_link)]
+#[diag(passes::no_link)]
 pub struct NoLink {
     #[primary_span]
     pub attr_span: Span,
@@ -382,7 +382,7 @@ pub struct NoLink {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::export_name)]
+#[diag(passes::export_name)]
 pub struct ExportName {
     #[primary_span]
     pub attr_span: Span,
@@ -391,7 +391,7 @@ pub struct ExportName {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_layout_scalar_valid_range_not_struct)]
+#[diag(passes::rustc_layout_scalar_valid_range_not_struct)]
 pub struct RustcLayoutScalarValidRangeNotStruct {
     #[primary_span]
     pub attr_span: Span,
@@ -400,14 +400,14 @@ pub struct RustcLayoutScalarValidRangeNotStruct {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_layout_scalar_valid_range_arg)]
+#[diag(passes::rustc_layout_scalar_valid_range_arg)]
 pub struct RustcLayoutScalarValidRangeArg {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_only)]
+#[diag(passes::rustc_legacy_const_generics_only)]
 pub struct RustcLegacyConstGenericsOnly {
     #[primary_span]
     pub attr_span: Span,
@@ -416,7 +416,7 @@ pub struct RustcLegacyConstGenericsOnly {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_index)]
+#[diag(passes::rustc_legacy_const_generics_index)]
 pub struct RustcLegacyConstGenericsIndex {
     #[primary_span]
     pub attr_span: Span,
@@ -425,7 +425,7 @@ pub struct RustcLegacyConstGenericsIndex {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_index_exceed)]
+#[diag(passes::rustc_legacy_const_generics_index_exceed)]
 pub struct RustcLegacyConstGenericsIndexExceed {
     #[primary_span]
     #[label]
@@ -434,21 +434,21 @@ pub struct RustcLegacyConstGenericsIndexExceed {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_legacy_const_generics_index_negative)]
+#[diag(passes::rustc_legacy_const_generics_index_negative)]
 pub struct RustcLegacyConstGenericsIndexNegative {
     #[primary_span]
     pub invalid_args: Vec<Span>,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_dirty_clean)]
+#[diag(passes::rustc_dirty_clean)]
 pub struct RustcDirtyClean {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::link_section)]
+#[diag(passes::link_section)]
 #[warn_]
 pub struct LinkSection {
     #[label]
@@ -456,7 +456,7 @@ pub struct LinkSection {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::no_mangle_foreign)]
+#[diag(passes::no_mangle_foreign)]
 #[warn_]
 #[note]
 pub struct NoMangleForeign {
@@ -468,7 +468,7 @@ pub struct NoMangleForeign {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::no_mangle)]
+#[diag(passes::no_mangle)]
 #[warn_]
 pub struct NoMangle {
     #[label]
@@ -476,32 +476,32 @@ pub struct NoMangle {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::repr_ident, code = "E0565")]
+#[diag(passes::repr_ident, code = "E0565")]
 pub struct ReprIdent {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::repr_conflicting, code = "E0566")]
+#[diag(passes::repr_conflicting, code = "E0566")]
 pub struct ReprConflicting;
 
 #[derive(SessionDiagnostic)]
-#[error(passes::used_static)]
+#[diag(passes::used_static)]
 pub struct UsedStatic {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::used_compiler_linker)]
+#[diag(passes::used_compiler_linker)]
 pub struct UsedCompilerLinker {
     #[primary_span]
     pub spans: Vec<Span>,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::allow_internal_unstable)]
+#[diag(passes::allow_internal_unstable)]
 pub struct AllowInternalUnstable {
     #[primary_span]
     pub attr_span: Span,
@@ -510,14 +510,14 @@ pub struct AllowInternalUnstable {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::debug_visualizer_placement)]
+#[diag(passes::debug_visualizer_placement)]
 pub struct DebugVisualizerPlacement {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::debug_visualizer_invalid)]
+#[diag(passes::debug_visualizer_invalid)]
 #[note(passes::note_1)]
 #[note(passes::note_2)]
 #[note(passes::note_3)]
@@ -527,7 +527,7 @@ pub struct DebugVisualizerInvalid {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_allow_const_fn_unstable)]
+#[diag(passes::rustc_allow_const_fn_unstable)]
 pub struct RustcAllowConstFnUnstable {
     #[primary_span]
     pub attr_span: Span,
@@ -536,7 +536,7 @@ pub struct RustcAllowConstFnUnstable {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_std_internal_symbol)]
+#[diag(passes::rustc_std_internal_symbol)]
 pub struct RustcStdInternalSymbol {
     #[primary_span]
     pub attr_span: Span,
@@ -545,42 +545,42 @@ pub struct RustcStdInternalSymbol {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::const_trait)]
+#[diag(passes::const_trait)]
 pub struct ConstTrait {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::link_ordinal)]
+#[diag(passes::link_ordinal)]
 pub struct LinkOrdinal {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::stability_promotable)]
+#[diag(passes::stability_promotable)]
 pub struct StabilityPromotable {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::deprecated)]
+#[diag(passes::deprecated)]
 pub struct Deprecated;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::macro_use)]
+#[diag(passes::macro_use)]
 pub struct MacroUse {
     pub name: Symbol,
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::macro_export)]
+#[diag(passes::macro_export)]
 pub struct MacroExport;
 
 #[derive(LintDiagnostic)]
-#[lint(passes::plugin_registrar)]
+#[diag(passes::plugin_registrar)]
 pub struct PluginRegistrar;
 
 #[derive(SessionSubdiagnostic)]
@@ -594,7 +594,7 @@ pub enum UnusedNote {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::unused)]
+#[diag(passes::unused)]
 pub struct Unused {
     #[suggestion(applicability = "machine-applicable")]
     pub attr_span: Span,
@@ -603,7 +603,7 @@ pub struct Unused {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::non_exported_macro_invalid_attrs, code = "E0518")]
+#[diag(passes::non_exported_macro_invalid_attrs, code = "E0518")]
 pub struct NonExportedMacroInvalidAttrs {
     #[primary_span]
     #[label]
@@ -611,9 +611,8 @@ pub struct NonExportedMacroInvalidAttrs {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(passes::unused_duplicate)]
+#[diag(passes::unused_duplicate)]
 pub struct UnusedDuplicate {
-    #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
     pub this: Span,
     #[note]
@@ -623,7 +622,7 @@ pub struct UnusedDuplicate {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::unused_multiple)]
+#[diag(passes::unused_multiple)]
 pub struct UnusedMultiple {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
@@ -634,7 +633,7 @@ pub struct UnusedMultiple {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_lint_opt_ty)]
+#[diag(passes::rustc_lint_opt_ty)]
 pub struct RustcLintOptTy {
     #[primary_span]
     pub attr_span: Span,
@@ -643,7 +642,7 @@ pub struct RustcLintOptTy {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(passes::rustc_lint_opt_deny_field_access)]
+#[diag(passes::rustc_lint_opt_deny_field_access)]
 pub struct RustcLintOptDenyFieldAccess {
     #[primary_span]
     pub attr_span: Span,
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index aca7d770f34..1e423ddb710 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -3,7 +3,7 @@ use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
 use rustc_span::{Span, Symbol};
 
 #[derive(SessionDiagnostic)]
-#[error(privacy::field_is_private, code = "E0451")]
+#[diag(privacy::field_is_private, code = "E0451")]
 pub struct FieldIsPrivate {
     #[primary_span]
     pub span: Span,
@@ -30,7 +30,7 @@ pub enum FieldIsPrivateLabel {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(privacy::item_is_private)]
+#[diag(privacy::item_is_private)]
 pub struct ItemIsPrivate<'a> {
     #[primary_span]
     #[label]
@@ -40,7 +40,7 @@ pub struct ItemIsPrivate<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(privacy::unnamed_item_is_private)]
+#[diag(privacy::unnamed_item_is_private)]
 pub struct UnnamedItemIsPrivate {
     #[primary_span]
     pub span: Span,
@@ -49,7 +49,7 @@ pub struct UnnamedItemIsPrivate {
 
 // Duplicate of `InPublicInterface` but with a different error code, shares the same slug.
 #[derive(SessionDiagnostic)]
-#[error(privacy::in_public_interface, code = "E0445")]
+#[diag(privacy::in_public_interface, code = "E0445")]
 pub struct InPublicInterfaceTraits<'a> {
     #[primary_span]
     #[label]
@@ -63,7 +63,7 @@ pub struct InPublicInterfaceTraits<'a> {
 
 // Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug.
 #[derive(SessionDiagnostic)]
-#[error(privacy::in_public_interface, code = "E0446")]
+#[diag(privacy::in_public_interface, code = "E0446")]
 pub struct InPublicInterface<'a> {
     #[primary_span]
     #[label]
@@ -76,7 +76,7 @@ pub struct InPublicInterface<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(privacy::from_private_dep_in_public_interface)]
+#[diag(privacy::from_private_dep_in_public_interface)]
 pub struct FromPrivateDependencyInPublicInterface<'a> {
     pub kind: &'a str,
     pub descr: DiagnosticArgFromDisplay<'a>,
@@ -84,7 +84,7 @@ pub struct FromPrivateDependencyInPublicInterface<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[lint(privacy::private_in_public_lint)]
+#[diag(privacy::private_in_public_lint)]
 pub struct PrivateInPublicLint<'a> {
     pub vis_descr: &'static str,
     pub kind: &'a str,
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index 5673bb83b15..c37ae4f3253 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -20,6 +20,7 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
 tracing = "0.1"
 
 [features]
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index eda61df7700..df187ea0c94 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -7,6 +7,8 @@
 #![feature(rustc_attrs)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 56fd90c9855..6711dd3d5c5 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -22,8 +22,9 @@ use rustc_span::hygiene::{
     ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
 };
 use rustc_span::source_map::{SourceMap, StableSourceFileId};
-use rustc_span::CachingSourceMapView;
 use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
+use rustc_span::{CachingSourceMapView, Symbol};
+use std::collections::hash_map::Entry;
 use std::io;
 use std::mem;
 
@@ -38,6 +39,10 @@ const TAG_RELATIVE_SPAN: u8 = 2;
 const TAG_SYNTAX_CONTEXT: u8 = 0;
 const TAG_EXPN_DATA: u8 = 1;
 
+// Tags for encoding Symbol's
+const SYMBOL_STR: u8 = 0;
+const SYMBOL_OFFSET: u8 = 1;
+
 /// Provides an interface to incremental compilation data cached from the
 /// previous compilation session. This data will eventually include the results
 /// of a few selected queries (like `typeck` and `mir_optimized`) and
@@ -254,6 +259,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
                 source_map: CachingSourceMapView::new(tcx.sess.source_map()),
                 file_to_file_index,
                 hygiene_context: &hygiene_encode_context,
+                symbol_table: Default::default(),
             };
 
             // Encode query results.
@@ -714,6 +720,36 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
     }
 }
 
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Symbol {
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+        let tag = d.read_u8();
+
+        match tag {
+            SYMBOL_STR => {
+                let s = d.read_str();
+                Symbol::intern(s)
+            }
+            SYMBOL_OFFSET => {
+                // read str offset
+                let pos = d.read_usize();
+                let old_pos = d.opaque.position();
+
+                // move to str ofset and read
+                d.opaque.set_position(pos);
+                let s = d.read_str();
+                let sym = Symbol::intern(s);
+
+                // restore position
+                d.opaque.set_position(old_pos);
+
+                sym
+            }
+            _ => unreachable!(),
+        }
+    }
+}
+
 impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
     fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
         let stable_id = StableCrateId::decode(d);
@@ -815,6 +851,7 @@ pub struct CacheEncoder<'a, 'tcx> {
     source_map: CachingSourceMapView<'tcx>,
     file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>,
     hygiene_context: &'a HygieneEncodeContext,
+    symbol_table: FxHashMap<Symbol, usize>,
 }
 
 impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
@@ -899,6 +936,25 @@ impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Span {
     }
 }
 
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Symbol {
+    fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
+        match s.symbol_table.entry(*self) {
+            Entry::Vacant(o) => {
+                s.encoder.emit_u8(SYMBOL_STR);
+                let pos = s.encoder.position();
+                o.insert(pos);
+                s.emit_str(self.as_str());
+            }
+            Entry::Occupied(o) => {
+                let x = o.get().clone();
+                s.emit_u8(SYMBOL_OFFSET);
+                s.emit_usize(x);
+            }
+        }
+    }
+}
+
 impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
     type I = TyCtxt<'tcx>;
     const CLEAR_CROSS_CRATE: bool = false;
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index eda4401c81d..339683cf689 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -233,21 +233,10 @@ macro_rules! get_provider {
     };
 }
 
-macro_rules! opt_remap_env_constness {
-    ([][$name:ident]) => {};
-    ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
-        let $name = $name.without_const();
-    };
-    ([$other:tt $($modifiers:tt)*][$name:ident]) => {
-        opt_remap_env_constness!([$($modifiers)*][$name])
-    };
-}
-
 macro_rules! define_queries {
     (<$tcx:tt>
      $($(#[$attr:meta])*
         [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
-
         define_queries_struct! {
             tcx: $tcx,
             input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
@@ -259,7 +248,6 @@ macro_rules! define_queries {
             // Create an eponymous constructor for each query.
             $(#[allow(nonstandard_style)] $(#[$attr])*
             pub fn $name<$tcx>(tcx: QueryCtxt<$tcx>, key: query_keys::$name<$tcx>) -> QueryStackFrame {
-                opt_remap_env_constness!([$($modifiers)*][key]);
                 let kind = dep_graph::DepKind::$name;
                 let name = stringify!($name);
                 // Disable visible paths printing for performance reasons.
@@ -549,7 +537,6 @@ macro_rules! define_queries_struct {
                 key: query_keys::$name<$tcx>,
                 mode: QueryMode,
             ) -> Option<query_stored::$name<$tcx>> {
-                opt_remap_env_constness!([$($modifiers)*][key]);
                 let qcx = QueryCtxt { tcx, queries: self };
                 get_query::<queries::$name<$tcx>, _>(qcx, span, key, mode)
             })*
diff --git a/compiler/rustc_query_impl/src/values.rs b/compiler/rustc_query_impl/src/values.rs
index 718a2971c40..0ed48f8d4a0 100644
--- a/compiler/rustc_query_impl/src/values.rs
+++ b/compiler/rustc_query_impl/src/values.rs
@@ -43,3 +43,23 @@ impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
         }
     }
 }
+
+impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> {
+    fn from_cycle_error(tcx: QueryCtxt<'tcx>) -> Self {
+        let err = tcx.ty_error();
+        // FIXME(compiler-errors): It would be nice if we could get the
+        // query key, so we could at least generate a fn signature that
+        // has the right arity.
+        let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
+            [].into_iter(),
+            err,
+            false,
+            rustc_hir::Unsafety::Normal,
+            rustc_target::spec::abi::Abi::Rust,
+        ));
+
+        // SAFETY: This is never called when `Self` is not `ty::Binder<'tcx, ty::FnSig<'tcx>>`.
+        // FIXME: Represent the above fact in the trait system somehow.
+        unsafe { std::mem::transmute::<ty::PolyFnSig<'tcx>, ty::Binder<'_, ty::FnSig<'_>>>(fn_sig) }
+    }
+}
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index b89273990d8..e0d57ded5bf 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -31,7 +31,7 @@ use std::{mem, ptr};
 type Res = def::Res<NodeId>;
 
 /// Contains data for specific kinds of imports.
-#[derive(Clone, Debug)]
+#[derive(Clone)]
 pub enum ImportKind<'a> {
     Single {
         /// `source` in `use prefix::source as target`.
@@ -62,6 +62,44 @@ pub enum ImportKind<'a> {
     MacroUse,
 }
 
+/// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
+/// contain `Cell`s which can introduce infinite loops while printing.
+impl<'a> std::fmt::Debug for ImportKind<'a> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        use ImportKind::*;
+        match self {
+            Single {
+                ref source,
+                ref target,
+                ref type_ns_only,
+                ref nested,
+                ref additional_ids,
+                // Ignore the following to avoid an infinite loop while printing.
+                source_bindings: _,
+                target_bindings: _,
+            } => f
+                .debug_struct("Single")
+                .field("source", source)
+                .field("target", target)
+                .field("type_ns_only", type_ns_only)
+                .field("nested", nested)
+                .field("additional_ids", additional_ids)
+                .finish_non_exhaustive(),
+            Glob { ref is_prelude, ref max_vis } => f
+                .debug_struct("Glob")
+                .field("is_prelude", is_prelude)
+                .field("max_vis", max_vis)
+                .finish(),
+            ExternCrate { ref source, ref target } => f
+                .debug_struct("ExternCrate")
+                .field("source", source)
+                .field("target", target)
+                .finish(),
+            MacroUse => f.debug_struct("MacroUse").finish(),
+        }
+    }
+}
+
 /// One import.
 #[derive(Debug, Clone)]
 pub(crate) struct Import<'a> {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 09c1f44826f..4175527da47 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -161,6 +161,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
             msg: String,
             fallback_label: String,
             span: Span,
+            span_label: Option<(Span, &'a str)>,
             could_be_expr: bool,
             suggestion: Option<(Span, &'a str, String)>,
         }
@@ -172,6 +173,12 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 msg: format!("expected {}, found {} `{}`", expected, res.descr(), path_str),
                 fallback_label: format!("not a {expected}"),
                 span,
+                span_label: match res {
+                    Res::Def(kind, def_id) if kind == DefKind::TyParam => {
+                        self.def_span(def_id).map(|span| (span, "found this type pararmeter"))
+                    }
+                    _ => None,
+                },
                 could_be_expr: match res {
                     Res::Def(DefKind::Fn, _) => {
                         // Verify whether this is a fn call or an Fn used as a type.
@@ -251,6 +258,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     format!("not found in {mod_str}")
                 },
                 span: item_span,
+                span_label: None,
                 could_be_expr: false,
                 suggestion,
             }
@@ -262,6 +270,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 
         self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
 
+        if let Some((span, label)) = base_error.span_label {
+            err.span_label(span, label);
+        }
+
         if let Some(sugg) = base_error.suggestion {
             err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect);
         }
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index e606f427335..079d44bac68 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -18,6 +18,8 @@ Core encoding and decoding interfaces.
 #![feature(new_uninit)]
 #![cfg_attr(test, feature(test))]
 #![allow(rustc::internal)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 pub use self::serialize::{Decodable, Decoder, Encodable, Encoder};
 
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index f31d52147b4..b9b2356130a 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -2,15 +2,17 @@
 //! It also serves as an input to the parser itself.
 
 use crate::config::CheckCfg;
-use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
+use crate::lint::{
+    builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
+};
 use crate::SessionDiagnostic;
 use rustc_ast::node_id::NodeId;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
 use rustc_errors::{
-    error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder,
-    DiagnosticMessage, ErrorGuaranteed, MultiSpan,
+    error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
+    DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, MultiSpan, StashKey,
 };
 use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
 use rustc_span::edition::Edition;
@@ -101,11 +103,58 @@ pub fn feature_err_issue<'a>(
     issue: GateIssue,
     explain: &str,
 ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
+    let span = span.into();
+
+    // Cancel an earlier warning for this same error, if it exists.
+    if let Some(span) = span.primary_span() {
+        sess.span_diagnostic
+            .steal_diagnostic(span, StashKey::EarlySyntaxWarning)
+            .map(|err| err.cancel());
+    }
+
     let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658));
     add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
     err
 }
 
+/// Construct a future incompatibility diagnostic for a feature gate.
+///
+/// This diagnostic is only a warning and *does not cause compilation to fail*.
+pub fn feature_warn<'a>(sess: &'a ParseSess, feature: Symbol, span: Span, explain: &str) {
+    feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
+}
+
+/// Construct a future incompatibility diagnostic for a feature gate.
+///
+/// This diagnostic is only a warning and *does not cause compilation to fail*.
+///
+/// This variant allows you to control whether it is a library or language feature.
+/// Almost always, you want to use this for a language feature. If so, prefer `feature_warn`.
+pub fn feature_warn_issue<'a>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: Span,
+    issue: GateIssue,
+    explain: &str,
+) {
+    let mut err = sess.span_diagnostic.struct_span_warn(span, explain);
+    add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
+
+    // Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
+    let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
+    let future_incompatible = lint.future_incompatible.as_ref().unwrap();
+    err.code(DiagnosticId::Lint {
+        name: lint.name_lower(),
+        has_future_breakage: false,
+        is_force_warn: false,
+    });
+    err.warn(lint.desc);
+    err.note(format!("for more information, see {}", future_incompatible.reference));
+
+    // A later feature_err call can steal and cancel this warning.
+    err.stash(span, StashKey::EarlySyntaxWarning);
+}
+
 /// Adds the diagnostics for a feature to an existing error.
 pub fn add_feature_diagnostics<'a>(err: &mut Diagnostic, sess: &'a ParseSess, feature: Symbol) {
     add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language);
@@ -323,4 +372,12 @@ impl ParseSess {
     pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
         self.span_diagnostic.struct_warn(msg)
     }
+
+    #[rustc_lint_diagnostics]
+    pub fn struct_diagnostic<G: EmissionGuarantee>(
+        &self,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, G> {
+        self.span_diagnostic.struct_diagnostic(msg)
+    }
 }
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 5c7aaf35b90..3e93c6bba97 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -11,6 +11,8 @@
     test(attr(allow(unused_variables), deny(warnings)))
 )]
 #![cfg_attr(not(feature = "default"), feature(rustc_private))]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 pub mod mir;
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index cf306928151..d14e28e85be 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -20,6 +20,8 @@
 #![feature(negative_impls)]
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
@@ -1094,10 +1096,8 @@ pub enum ExternalSource {
     Unneeded,
     Foreign {
         kind: ExternalSourceKind,
-        /// This SourceFile's byte-offset within the source_map of its original crate.
-        original_start_pos: BytePos,
-        /// The end of this SourceFile within the source_map of its original crate.
-        original_end_pos: BytePos,
+        /// Index of the file inside metadata.
+        metadata_index: u32,
     },
 }
 
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index ad9f5ba85a1..bc76ccc1d59 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -336,7 +336,7 @@ impl SourceMap {
         mut file_local_non_narrow_chars: Vec<NonNarrowChar>,
         mut file_local_normalized_pos: Vec<NormalizedPos>,
         original_start_pos: BytePos,
-        original_end_pos: BytePos,
+        metadata_index: u32,
     ) -> Lrc<SourceFile> {
         let start_pos = self
             .allocate_address_space(source_len)
@@ -381,8 +381,7 @@ impl SourceMap {
             src_hash,
             external_src: Lock::new(ExternalSource::Foreign {
                 kind: ExternalSourceKind::AbsentOk,
-                original_start_pos,
-                original_end_pos,
+                metadata_index,
             }),
             start_pos,
             end_pos,
diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index be827cea874..3058ec45a64 100644
--- a/compiler/rustc_span/src/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
@@ -251,7 +251,7 @@ fn t10() {
         non_narrow_chars,
         normalized_pos,
         start_pos,
-        end_pos,
+        0,
     );
 
     assert!(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2f3519e3edd..156f53ac486 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1852,14 +1852,14 @@ impl fmt::Display for Symbol {
 }
 
 impl<S: Encoder> Encodable<S> for Symbol {
-    fn encode(&self, s: &mut S) {
+    default fn encode(&self, s: &mut S) {
         s.emit_str(self.as_str());
     }
 }
 
 impl<D: Decoder> Decodable<D> for Symbol {
     #[inline]
-    fn decode(d: &mut D) -> Symbol {
+    default fn decode(d: &mut D) -> Symbol {
         Symbol::intern(&d.read_str())
     }
 }
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 59dbea70534..9c9e297849e 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -16,6 +16,8 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(step_trait)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 use std::iter::FromIterator;
 use std::path::{Path, PathBuf};
diff --git a/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
index 59c6a95c2c5..98d3e79c8e9 100644
--- a/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
@@ -2,7 +2,7 @@ use crate::spec::Target;
 
 pub fn target() -> Target {
     let mut base = super::windows_gnullvm_base::opts();
-    base.max_atomic_width = Some(64);
+    base.max_atomic_width = Some(128);
     base.features = "+neon,+fp-armv8".into();
     base.linker = Some("aarch64-w64-mingw32-clang".into());
 
diff --git a/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
index 856ec4fb0b4..7c4544b3f33 100644
--- a/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/aarch64_pc_windows_msvc.rs
@@ -2,7 +2,7 @@ use crate::spec::Target;
 
 pub fn target() -> Target {
     let mut base = super::windows_msvc_base::opts();
-    base.max_atomic_width = Some(64);
+    base.max_atomic_width = Some(128);
     base.features = "+neon,+fp-armv8".into();
 
     Target {
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
index 162b091b269..3ef04c67668 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
@@ -7,7 +7,7 @@ use crate::spec::{LinkerFlavor, Target};
 pub fn target() -> Target {
     let mut base = uefi_msvc_base::opts();
 
-    base.max_atomic_width = Some(64);
+    base.max_atomic_width = Some(128);
     base.add_pre_link_args(LinkerFlavor::Msvc, &["/machine:arm64"]);
 
     Target {
diff --git a/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
index 54247fd93f2..db4dbf817b8 100644
--- a/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/aarch64_uwp_windows_msvc.rs
@@ -2,7 +2,7 @@ use crate::spec::Target;
 
 pub fn target() -> Target {
     let mut base = super::windows_uwp_msvc_base::opts();
-    base.max_atomic_width = Some(64);
+    base.max_atomic_width = Some(128);
 
     Target {
         llvm_target: "aarch64-pc-windows-msvc".into(),
diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index bf3ebaa2840..49e302676a7 100644
--- a/compiler/rustc_target/src/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
@@ -65,7 +65,6 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
     TargetOptions {
         abi: target_abi(arch).into(),
         cpu: target_cpu(arch).into(),
-        dynamic_linking: false,
         link_env_remove: link_env_remove(arch),
         has_thread_local: false,
         ..super::apple_base::opts(os, target_arch_name(arch), target_abi(arch))
diff --git a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
index 7b23fe1c482..cb7f5f2a583 100644
--- a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
         arch: "aarch64".into(),
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
-            max_atomic_width: Some(64),
+            max_atomic_width: Some(128),
             forces_embed_bitcode: true,
             // These arguments are not actually invoked - they just have
             // to look right to pass App Store validation.
diff --git a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
index a76ffe808c3..797dfe52bd1 100644
--- a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs
@@ -38,7 +38,9 @@ pub fn target() -> Target {
             linker_flavor: LinkerFlavor::Ld,
             linker: Some("arm-none-eabi-ld".into()),
             asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",],
-            features: "+soft-float,+strict-align".into(),
+            // Force-enable 32-bit atomics, which allows the use of atomic load/store only.
+            // The resulting atomics are ABI incompatible with atomics backed by libatomic.
+            features: "+soft-float,+strict-align,+atomics-32".into(),
             main_needs_argc_argv: false,
             atomic_cas: false,
             has_thumb_interworking: true,
diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
index 7125d141af7..bdaaed8b5d0 100644
--- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
@@ -47,7 +47,9 @@ pub fn target() -> Target {
             asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",],
 
             // minimum extra features, these cannot be disabled via -C
-            features: "+soft-float,+strict-align".into(),
+            // Also force-enable 32-bit atomics, which allows the use of atomic load/store only.
+            // The resulting atomics are ABI incompatible with atomics backed by libatomic.
+            features: "+soft-float,+strict-align,+atomics-32".into(),
 
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 9bb41b900b8..985600d9ebc 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -404,12 +404,12 @@ fn resolve_negative_obligation<'cx, 'tcx>(
 pub fn trait_ref_is_knowable<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
-) -> Option<Conflict> {
+) -> Result<(), Conflict> {
     debug!("trait_ref_is_knowable(trait_ref={:?})", trait_ref);
     if orphan_check_trait_ref(tcx, trait_ref, InCrate::Remote).is_ok() {
         // A downstream or cousin crate is allowed to implement some
         // substitution of this trait-ref.
-        return Some(Conflict::Downstream);
+        return Err(Conflict::Downstream);
     }
 
     if trait_ref_is_local_or_fundamental(tcx, trait_ref) {
@@ -418,7 +418,7 @@ pub fn trait_ref_is_knowable<'tcx>(
         // allowed to implement a substitution of this trait ref, which
         // means impls could only come from dependencies of this crate,
         // which we already know about.
-        return None;
+        return Ok(());
     }
 
     // This is a remote non-fundamental trait, so if another crate
@@ -431,10 +431,10 @@ pub fn trait_ref_is_knowable<'tcx>(
     // we are an owner.
     if orphan_check_trait_ref(tcx, trait_ref, InCrate::Local).is_ok() {
         debug!("trait_ref_is_knowable: orphan check passed");
-        None
+        Ok(())
     } else {
         debug!("trait_ref_is_knowable: nonlocal, nonfundamental, unowned");
-        Some(Conflict::Upstream)
+        Err(Conflict::Upstream)
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 4260cb53adc..1a39a168038 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -22,6 +22,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_hir::GenericParam;
 use rustc_hir::Item;
 use rustc_hir::Node;
+use rustc_infer::infer::TypeTrace;
 use rustc_infer::traits::TraitEngine;
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
@@ -941,9 +942,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
 
                 self.reported_closure_mismatch.borrow_mut().insert((span, found_span));
 
+                let mut not_tupled = false;
+
                 let found = match found_trait_ref.skip_binder().substs.type_at(1).kind() {
                     ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
-                    _ => vec![ArgKind::empty()],
+                    _ => {
+                        not_tupled = true;
+                        vec![ArgKind::empty()]
+                    }
                 };
 
                 let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1);
@@ -951,10 +957,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     ty::Tuple(ref tys) => {
                         tys.iter().map(|t| ArgKind::from_expected_ty(t, Some(span))).collect()
                     }
-                    _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())],
+                    _ => {
+                        not_tupled = true;
+                        vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())]
+                    }
                 };
 
-                if found.len() == expected.len() {
+                // If this is a `Fn` family trait and either the expected or found
+                // is not tupled, then fall back to just a regular mismatch error.
+                // This shouldn't be common unless manually implementing one of the
+                // traits manually, but don't make it more confusing when it does
+                // happen.
+                if Some(expected_trait_ref.def_id()) != tcx.lang_items().gen_trait() && not_tupled {
+                    self.report_and_explain_type_error(
+                        TypeTrace::poly_trait_refs(
+                            &obligation.cause,
+                            true,
+                            expected_trait_ref,
+                            found_trait_ref,
+                        ),
+                        ty::error::TypeError::Mismatch,
+                    )
+                } else if found.len() == expected.len() {
                     self.report_closure_arg_mismatch(
                         span,
                         found_span,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 219413121d8..0d279069694 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -671,7 +671,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
         // It only make sense when suggesting dereferences for arguments
-        let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
+        let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else {
             return false;
         };
         let param_env = obligation.param_env;
@@ -702,19 +702,22 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     Some(steps).filter(|_| self.predicate_may_hold(&obligation))
                 }) {
                     if steps > 0 {
-                        if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
-                            // Don't care about `&mut` because `DerefMut` is used less
-                            // often and user will not expect autoderef happens.
-                            if src.starts_with('&') && !src.starts_with("&mut ") {
-                                let derefs = "*".repeat(steps);
-                                err.span_suggestion(
-                                    span,
-                                    "consider dereferencing here",
-                                    format!("&{}{}", derefs, &src[1..]),
-                                    Applicability::MachineApplicable,
-                                );
-                                return true;
-                            }
+                        // Don't care about `&mut` because `DerefMut` is used less
+                        // often and user will not expect autoderef happens.
+                        if let Some(hir::Node::Expr(hir::Expr {
+                            kind:
+                                hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, expr),
+                            ..
+                        })) = self.tcx.hir().find(*arg_hir_id)
+                        {
+                            let derefs = "*".repeat(steps);
+                            err.span_suggestion_verbose(
+                                expr.span.shrink_to_lo(),
+                                "consider dereferencing here",
+                                derefs,
+                                Applicability::MachineApplicable,
+                            );
+                            return true;
                         }
                     }
                 } else if real_trait_pred != trait_pred {
@@ -882,6 +885,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             obligation.cause.code()
         {
             &parent_code
+        } else if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code() {
+            obligation.cause.code()
         } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) =
             span.ctxt().outer_expn_data().kind
         {
@@ -930,10 +935,25 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         self.mk_trait_obligation_with_new_self_ty(param_env, trait_pred_and_new_ty);
                     self.predicate_must_hold_modulo_regions(&obligation)
                 };
-                let imm_result = mk_result(trait_pred_and_imm_ref);
-                let mut_result = mk_result(trait_pred_and_mut_ref);
+                let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref);
+                let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
+
+                let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
+                if let ObligationCauseCode::ItemObligation(_) = obligation.cause.code()
+                    && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind()
+                {
+                    (
+                        mk_result(old_pred.map_bound(|trait_pred| (trait_pred, *ty))),
+                        matches!(mutability, hir::Mutability::Mut),
+                    )
+                } else {
+                    (false, false)
+                };
 
-                if imm_result || mut_result {
+                if imm_ref_self_ty_satisfies_pred
+                    || mut_ref_self_ty_satisfies_pred
+                    || ref_inner_ty_satisfies_pred
+                {
                     if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
                         // We have a very specific type of error, where just borrowing this argument
                         // might solve the problem. In cases like this, the important part is the
@@ -973,7 +993,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             // }
                             // ```
 
-                            if imm_result && mut_result {
+                            if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
                                 err.span_suggestions(
                                     span.shrink_to_lo(),
                                     "consider borrowing here",
@@ -981,13 +1001,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                                     Applicability::MaybeIncorrect,
                                 );
                             } else {
+                                let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
                                 err.span_suggestion_verbose(
                                     span.shrink_to_lo(),
                                     &format!(
                                         "consider{} borrowing here",
-                                        if mut_result { " mutably" } else { "" }
+                                        if is_mut { " mutably" } else { "" }
                                     ),
-                                    format!("&{}", if mut_result { "mut " } else { "" }),
+                                    format!("&{}", if is_mut { "mut " } else { "" }),
                                     Applicability::MaybeIncorrect,
                                 );
                             }
@@ -1001,7 +1022,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code {
             try_borrowing(cause.derived.parent_trait_pred, &[])
         } else if let ObligationCauseCode::BindingObligation(_, _)
-        | ObligationCauseCode::ItemObligation(_) = code
+        | ObligationCauseCode::ItemObligation(..) = code
         {
             try_borrowing(poly_trait_pred, &never_suggest_borrow)
         } else {
@@ -2537,9 +2558,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 parent_trait_pred.remap_constness_diag(param_env);
                 let parent_def_id = parent_trait_pred.def_id();
                 let msg = format!(
-                    "required because of the requirements on the impl of `{}` for `{}`",
-                    parent_trait_pred.print_modifiers_and_trait_path(),
-                    parent_trait_pred.skip_binder().self_ty()
+                    "required for `{}` to implement `{}`",
+                    parent_trait_pred.skip_binder().self_ty(),
+                    parent_trait_pred.print_modifiers_and_trait_path()
                 );
                 let mut is_auto_trait = false;
                 match self.tcx.hir().get_if_local(data.impl_def_id) {
@@ -2608,9 +2629,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         pluralize!(count)
                     ));
                     err.note(&format!(
-                        "required because of the requirements on the impl of `{}` for `{}`",
-                        parent_trait_pred.print_modifiers_and_trait_path(),
-                        parent_trait_pred.skip_binder().self_ty()
+                        "required for `{}` to implement `{}`",
+                        parent_trait_pred.skip_binder().self_ty(),
+                        parent_trait_pred.print_modifiers_and_trait_path()
                     ));
                 }
                 // #74711: avoid a stack overflow
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 74625cc7bb7..715b9749268 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -252,10 +252,20 @@ fn project_and_unify_type<'cx, 'tcx>(
         Err(InProgress) => return ProjectAndUnifyResult::Recursive,
     };
     debug!(?normalized, ?obligations, "project_and_unify_type result");
-    match infcx
-        .at(&obligation.cause, obligation.param_env)
-        .eq(normalized, obligation.predicate.term)
-    {
+    let actual = obligation.predicate.term;
+    // For an example where this is neccessary see src/test/ui/impl-trait/nested-return-type2.rs
+    // This allows users to omit re-mentioning all bounds on an associated type and just use an
+    // `impl Trait` for the assoc type to add more bounds.
+    let InferOk { value: actual, obligations: new } =
+        selcx.infcx().replace_opaque_types_with_inference_vars(
+            actual,
+            obligation.cause.body_id,
+            obligation.cause.span,
+            obligation.param_env,
+        );
+    obligations.extend(new);
+
+    match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) {
         Ok(InferOk { obligations: inferred_obligations, value: () }) => {
             obligations.extend(inferred_obligations);
             ProjectAndUnifyResult::Holds(obligations)
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 50e9b95a445..d67bd6292b4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -75,7 +75,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         stack: &TraitObligationStack<'o, 'tcx>,
     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
-        if let Some(conflict) = self.is_knowable(stack) {
+        if let Err(conflict) = self.is_knowable(stack) {
             debug!("coherence stage: not knowable");
             if self.intercrate_ambiguity_causes.is_some() {
                 debug!("evaluate_stack: intercrate_ambiguity_causes is some");
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index c01ac197991..46b50dd92f1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1265,11 +1265,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         Ok(Some(candidate))
     }
 
-    fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Option<Conflict> {
+    fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
         debug!("is_knowable(intercrate={:?})", self.intercrate);
 
         if !self.intercrate || stack.obligation.polarity() == ty::ImplPolarity::Negative {
-            return None;
+            return Ok(());
         }
 
         let obligation = &stack.obligation;
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index 2bea164c051..318e76c79f1 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -1,6 +1,8 @@
 //! New recursive solver modeled on Chalk's recursive solver. Most of
 //! the guts are broken up into modules; see the comments in those modules.
 
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(let_else)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 791e9e0f5a3..5488bca8f47 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -1,6 +1,8 @@
 #![feature(fmt_helpers_for_derive)]
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate bitflags;
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 1e6cb53f3ee..5bb02bc246c 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -35,7 +35,7 @@ use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECT
 use rustc_span::edition::Edition;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::symbol::{kw, Ident, Symbol};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 use rustc_target::spec::abi;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::astconv_object_safety_violations;
@@ -1453,21 +1453,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     .enumerate()
                     .skip(1) // Remove `Self` for `ExistentialPredicate`.
                     .map(|(index, arg)| {
-                        if let ty::GenericArgKind::Type(ty) = arg.unpack() {
-                            debug!(?ty);
-                            if ty == dummy_self {
-                                let param = &generics.params[index];
-                                missing_type_params.push(param.name);
-                                tcx.ty_error().into()
-                            } else if ty.walk().any(|arg| arg == dummy_self.into()) {
-                                references_self = true;
-                                tcx.ty_error().into()
-                            } else {
-                                arg
-                            }
-                        } else {
-                            arg
+                        if arg == dummy_self.into() {
+                            let param = &generics.params[index];
+                            missing_type_params.push(param.name);
+                            return tcx.ty_error().into();
+                        } else if arg.walk().any(|arg| arg == dummy_self.into()) {
+                            references_self = true;
+                            return tcx.ty_error().into();
                         }
+                        arg
                     })
                     .collect();
                 let substs = tcx.intern_substs(&substs[..]);
@@ -1506,13 +1500,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         });
 
         let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
-            bound.map_bound(|b| {
-                if b.projection_ty.self_ty() != dummy_self {
-                    tcx.sess.delay_span_bug(
-                        DUMMY_SP,
-                        &format!("trait_ref_to_existential called on {:?} with non-dummy Self", b),
-                    );
+            bound.map_bound(|mut b| {
+                assert_eq!(b.projection_ty.self_ty(), dummy_self);
+
+                // Like for trait refs, verify that `dummy_self` did not leak inside default type
+                // parameters.
+                let references_self = b.projection_ty.substs.iter().skip(1).any(|arg| {
+                    if arg.walk().any(|arg| arg == dummy_self.into()) {
+                        return true;
+                    }
+                    false
+                });
+                if references_self {
+                    tcx.sess
+                        .delay_span_bug(span, "trait object projection bounds reference `Self`");
+                    let substs: Vec<_> = b
+                        .projection_ty
+                        .substs
+                        .iter()
+                        .map(|arg| {
+                            if arg.walk().any(|arg| arg == dummy_self.into()) {
+                                return tcx.ty_error().into();
+                            }
+                            arg
+                        })
+                        .collect();
+                    b.projection_ty.substs = tcx.intern_substs(&substs[..]);
                 }
+
                 ty::ExistentialProjection::erase_self_ty(tcx, b)
             })
         });
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index da575cb1367..def592c46c2 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -1488,14 +1488,14 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                     // `break`, we want to call the `()` "expected"
                     // since it is implied by the syntax.
                     // (Note: not all force-units work this way.)"
-                    (expression_ty, self.final_ty.unwrap_or(self.expected_ty))
+                    (expression_ty, self.merged_ty())
                 } else {
                     // Otherwise, the "expected" type for error
                     // reporting is the current unification type,
                     // which is basically the LUB of the expressions
                     // we've seen so far (combined with the expected
                     // type)
-                    (self.final_ty.unwrap_or(self.expected_ty), expression_ty)
+                    (self.merged_ty(), expression_ty)
                 };
                 let (expected, found) = fcx.resolve_vars_if_possible((expected, found));
 
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 9c2fdd87516..5ff62f36b45 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -561,16 +561,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We just want to check sizedness, so instead of introducing
                     // placeholder lifetimes with probing, we just replace higher lifetimes
                     // with fresh vars.
-                    let span = args.get(i).map(|a| a.span).unwrap_or(expr.span);
+                    let arg_span = args.get(i).map(|a| a.span);
+                    let span = arg_span.unwrap_or(expr.span);
                     let input = self.replace_bound_vars_with_fresh_vars(
                         span,
                         infer::LateBoundRegionConversionTime::FnCall,
                         fn_sig.input(i),
                     );
-                    self.require_type_is_sized_deferred(
-                        input,
+                    self.require_type_is_sized(
+                        self.normalize_associated_types_in(span, input),
                         span,
-                        traits::SizedArgumentType(None),
+                        traits::SizedArgumentType(arg_span),
                     );
                 }
             }
@@ -585,7 +586,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 infer::LateBoundRegionConversionTime::FnCall,
                 fn_sig.output(),
             );
-            self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
+            self.require_type_is_sized(
+                self.normalize_associated_types_in(expr.span, output),
+                expr.span,
+                traits::SizedReturnType,
+            );
         }
 
         // We always require that the type provided as the value for
@@ -2193,7 +2198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 E0610,
                 "`{expr_t}` is a primitive type and therefore doesn't have fields",
             );
-            let is_valid_suffix = |field: String| {
+            let is_valid_suffix = |field: &str| {
                 if field == "f32" || field == "f64" {
                     return true;
                 }
@@ -2218,20 +2223,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let suffix = chars.collect::<String>();
                 suffix.is_empty() || suffix == "f32" || suffix == "f64"
             };
+            let maybe_partial_suffix = |field: &str| -> Option<&str> {
+                let first_chars = ['f', 'l'];
+                if field.len() >= 1
+                    && field.to_lowercase().starts_with(first_chars)
+                    && field[1..].chars().all(|c| c.is_ascii_digit())
+                {
+                    if field.to_lowercase().starts_with(['f']) { Some("f32") } else { Some("f64") }
+                } else {
+                    None
+                }
+            };
             if let ty::Infer(ty::IntVar(_)) = expr_t.kind()
                 && let ExprKind::Lit(Spanned {
                     node: ast::LitKind::Int(_, ast::LitIntType::Unsuffixed),
                     ..
                 }) = base.kind
                 && !base.span.from_expansion()
-                && is_valid_suffix(field_name)
             {
-                err.span_suggestion_verbose(
-                    field.span.shrink_to_lo(),
-                    "If the number is meant to be a floating point number, consider adding a `0` after the period",
-                    '0',
-                    Applicability::MaybeIncorrect,
-                );
+                if is_valid_suffix(&field_name) {
+                    err.span_suggestion_verbose(
+                        field.span.shrink_to_lo(),
+                        "if intended to be a floating point literal, consider adding a `0` after the period",
+                        '0',
+                        Applicability::MaybeIncorrect,
+                    );
+                } else if let Some(correct_suffix) = maybe_partial_suffix(&field_name) {
+                    err.span_suggestion_verbose(
+                        field.span,
+                        format!("if intended to be a floating point literal, consider adding a `0` after the period and a `{correct_suffix}` suffix"),
+                        format!("0{correct_suffix}"),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
             }
             err.emit();
         }
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 3a809334511..1d9d04ceec0 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -442,17 +442,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn require_type_is_sized_deferred(
-        &self,
-        ty: Ty<'tcx>,
-        span: Span,
-        code: traits::ObligationCauseCode<'tcx>,
-    ) {
-        if !ty.references_error() {
-            self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
-        }
-    }
-
     pub fn register_bound(
         &self,
         ty: Ty<'tcx>,
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index d4f8001493c..85a0d4e4499 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -457,7 +457,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
 }
 
 #[derive(Default)]
-pub struct SuspendCheckData<'a, 'tcx> {
+struct SuspendCheckData<'a, 'tcx> {
     expr: Option<&'tcx Expr<'tcx>>,
     source_span: Span,
     yield_span: Span,
@@ -472,7 +472,7 @@ pub struct SuspendCheckData<'a, 'tcx> {
 //
 // Note that this technique was chosen over things like a `Suspend` marker trait
 // as it is simpler and has precedent in the compiler
-pub fn check_must_not_suspend_ty<'tcx>(
+fn check_must_not_suspend_ty<'tcx>(
     fcx: &FnCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
     hir_id: HirId,
@@ -489,6 +489,8 @@ pub fn check_must_not_suspend_ty<'tcx>(
 
     let plural_suffix = pluralize!(data.plural_len);
 
+    debug!("Checking must_not_suspend for {}", ty);
+
     match *ty.kind() {
         ty::Adt(..) if ty.is_box() => {
             let boxed_ty = ty.boxed_ty();
@@ -580,6 +582,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
                 },
             )
         }
+        // If drop tracking is enabled, we want to look through references, since the referrent
+        // may not be considered live across the await point.
+        ty::Ref(_region, ty, _mutability) if fcx.sess().opts.unstable_opts.drop_tracking => {
+            let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix);
+            check_must_not_suspend_ty(fcx, ty, hir_id, SuspendCheckData { descr_pre, ..data })
+        }
         _ => false,
     }
 }
diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs
index cd152eb97f1..f3115fc5c02 100644
--- a/compiler/rustc_typeck/src/check/inherited.rs
+++ b/compiler/rustc_typeck/src/check/inherited.rs
@@ -35,11 +35,6 @@ pub struct Inherited<'a, 'tcx> {
 
     pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
 
-    // Some additional `Sized` obligations badly affect type inference.
-    // These obligations are added in a later stage of typeck.
-    pub(super) deferred_sized_obligations:
-        RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
-
     // When we process a call like `c()` where `c` is a closure type,
     // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
     // `FnOnce` closure. In that case, we defer full resolution of the
@@ -117,7 +112,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
             infcx,
             fulfillment_cx: RefCell::new(<dyn TraitEngine<'_>>::new(tcx)),
             locals: RefCell::new(Default::default()),
-            deferred_sized_obligations: RefCell::new(Vec::new()),
             deferred_call_resolutions: RefCell::new(Default::default()),
             deferred_cast_checks: RefCell::new(Vec::new()),
             deferred_transmute_checks: RefCell::new(Vec::new()),
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 1b50209ee64..dfbef544b1d 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -467,11 +467,6 @@ fn typeck_with_fallback<'tcx>(
         fcx.resolve_rvalue_scopes(def_id.to_def_id());
         fcx.resolve_generator_interiors(def_id.to_def_id());
 
-        for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
-            let ty = fcx.normalize_ty(span, ty);
-            fcx.require_type_is_sized(ty, span, code);
-        }
-
         fcx.select_all_obligations_or_error();
 
         if !fcx.infcx.is_tainted_by_errors() {
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index ebf1f506183..ba687bc4da4 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -3,7 +3,6 @@
 // substitutions.
 
 use crate::check::FnCtxt;
-
 use hir::def_id::LocalDefId;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::ErrorGuaranteed;
@@ -16,6 +15,7 @@ use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable};
+use rustc_middle::ty::TypeckResults;
 use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
@@ -192,6 +192,27 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
+    // (ouz-a 1005988): Normally `[T] : std::ops::Index<usize>` should be normalized
+    // into [T] but currently `Where` clause stops the normalization process for it,
+    // here we compare types of expr and base in a code without `Where` clause they would be equal
+    // if they are not we don't modify the expr, hence we bypass the ICE
+    fn is_builtin_index(
+        &mut self,
+        typeck_results: &TypeckResults<'tcx>,
+        e: &hir::Expr<'_>,
+        base_ty: Ty<'tcx>,
+        index_ty: Ty<'tcx>,
+    ) -> bool {
+        if let Some(elem_ty) = base_ty.builtin_index() {
+            let Some(exp_ty) = typeck_results.expr_ty_opt(e) else {return false;};
+            let resolved_exp_ty = self.resolve(exp_ty, &e.span);
+
+            elem_ty == resolved_exp_ty && index_ty == self.fcx.tcx.types.usize
+        } else {
+            false
+        }
+    }
+
     // Similar to operators, indexing is always assumed to be overloaded
     // Here, correct cases where an indexing expression can be simplified
     // to use builtin indexing because the index type is known to be
@@ -222,8 +243,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                     )
                 });
                 let index_ty = self.fcx.resolve_vars_if_possible(index_ty);
+                let resolved_base_ty = self.resolve(*base_ty, &base.span);
 
-                if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {
+                if self.is_builtin_index(&typeck_results, e, resolved_base_ty, index_ty) {
                     // Remove the method call record
                     typeck_results.type_dependent_defs_mut().remove(e.hir_id);
                     typeck_results.node_substs_mut().remove(e.hir_id);
diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs
index 4a3cfa1ca37..1d23ed92921 100644
--- a/compiler/rustc_typeck/src/check_unused.rs
+++ b/compiler/rustc_typeck/src/check_unused.rs
@@ -1,5 +1,5 @@
+use crate::errors::{ExternCrateNotIdiomatic, UnusedExternCrate};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -108,25 +108,16 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
         // We do this in any edition.
         if extern_crate.warn_if_unused {
             if let Some(&span) = unused_extern_crates.get(&def_id) {
+                // Removal suggestion span needs to include attributes (Issue #54400)
                 let id = tcx.hir().local_def_id_to_hir_id(def_id);
-                tcx.struct_span_lint_hir(lint, id, span, |lint| {
-                    // Removal suggestion span needs to include attributes (Issue #54400)
-                    let span_with_attrs = tcx
-                        .hir()
-                        .attrs(id)
-                        .iter()
-                        .map(|attr| attr.span)
-                        .fold(span, |acc, attr_span| acc.to(attr_span));
-
-                    lint.build("unused extern crate")
-                        .span_suggestion_short(
-                            span_with_attrs,
-                            "remove it",
-                            "",
-                            Applicability::MachineApplicable,
-                        )
-                        .emit();
-                });
+                let span_with_attrs = tcx
+                    .hir()
+                    .attrs(id)
+                    .iter()
+                    .map(|attr| attr.span)
+                    .fold(span, |acc, attr_span| acc.to(attr_span));
+
+                tcx.emit_spanned_lint(lint, id, span, UnusedExternCrate { span: span_with_attrs });
                 continue;
             }
         }
@@ -158,23 +149,23 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
         if !tcx.hir().attrs(id).is_empty() {
             continue;
         }
-        tcx.struct_span_lint_hir(lint, id, extern_crate.span, |lint| {
-            // Otherwise, we can convert it into a `use` of some kind.
-            let base_replacement = match extern_crate.orig_name {
-                Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name),
-                None => format!("use {};", item.ident.name),
-            };
-            let vis = tcx.sess.source_map().span_to_snippet(item.vis_span).unwrap_or_default();
-            let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) };
-            lint.build("`extern crate` is not idiomatic in the new edition")
-                .span_suggestion_short(
-                    extern_crate.span,
-                    &format!("convert it to a `{}`", add_vis("use".to_string())),
-                    add_vis(base_replacement),
-                    Applicability::MachineApplicable,
-                )
-                .emit();
-        })
+
+        let base_replacement = match extern_crate.orig_name {
+            Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name),
+            None => format!("use {};", item.ident.name),
+        };
+        let vis = tcx.sess.source_map().span_to_snippet(item.vis_span).unwrap_or_default();
+        let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) };
+        tcx.emit_spanned_lint(
+            lint,
+            id,
+            extern_crate.span,
+            ExternCrateNotIdiomatic {
+                span: extern_crate.span,
+                msg_code: add_vis("use".to_string()),
+                suggestion_code: add_vis(base_replacement),
+            },
+        );
     }
 }
 
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index 043e21fc1e3..2467a81638f 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -47,9 +47,11 @@ impl<'tcx> Checker<'tcx> {
 }
 
 fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
-    // Destructors only work on nominal types.
-    if let ty::Adt(..) | ty::Error(_) = tcx.type_of(impl_did).kind() {
-        return;
+    // Destructors only work on local ADT types.
+    match tcx.type_of(impl_did).kind() {
+        ty::Adt(def, _) if def.did().is_local() => return,
+        ty::Error(_) => return,
+        _ => {}
     }
 
     let sp = match tcx.hir().expect_item(impl_did).kind {
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index e7c5ecc60ec..970b39dc845 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2836,12 +2836,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
                     codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
                 }
                 Some(_) => {
-                    tcx.sess
-                        .struct_span_err(
-                            attr.span,
-                            "expected `used`, `used(compiler)` or `used(linker)`",
-                        )
-                        .emit();
+                    tcx.sess.emit_err(errors::ExpectedUsedSymbol { span: attr.span });
                 }
                 None => {
                     // Unfortunately, unconditionally using `llvm.used` causes
diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs
index 0438ac02ea9..2214fc2ced8 100644
--- a/compiler/rustc_typeck/src/errors.rs
+++ b/compiler/rustc_typeck/src/errors.rs
@@ -1,12 +1,12 @@
 //! Errors emitted by typeck.
 use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed};
-use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
 use rustc_middle::ty::Ty;
 use rustc_session::{parse::ParseSess, SessionDiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::field_multiply_specified_in_initializer, code = "E0062")]
+#[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")]
 pub struct FieldMultiplySpecifiedInInitializer {
     #[primary_span]
     #[label]
@@ -17,7 +17,7 @@ pub struct FieldMultiplySpecifiedInInitializer {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::unrecognized_atomic_operation, code = "E0092")]
+#[diag(typeck::unrecognized_atomic_operation, code = "E0092")]
 pub struct UnrecognizedAtomicOperation<'a> {
     #[primary_span]
     #[label]
@@ -26,7 +26,7 @@ pub struct UnrecognizedAtomicOperation<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
+#[diag(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
 pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
     #[primary_span]
     #[label]
@@ -37,7 +37,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::unrecognized_intrinsic_function, code = "E0093")]
+#[diag(typeck::unrecognized_intrinsic_function, code = "E0093")]
 pub struct UnrecognizedIntrinsicFunction {
     #[primary_span]
     #[label]
@@ -46,7 +46,7 @@ pub struct UnrecognizedIntrinsicFunction {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
+#[diag(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
 pub struct LifetimesOrBoundsMismatchOnTrait {
     #[primary_span]
     #[label]
@@ -58,7 +58,7 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::drop_impl_on_wrong_item, code = "E0120")]
+#[diag(typeck::drop_impl_on_wrong_item, code = "E0120")]
 pub struct DropImplOnWrongItem {
     #[primary_span]
     #[label]
@@ -66,7 +66,7 @@ pub struct DropImplOnWrongItem {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::field_already_declared, code = "E0124")]
+#[diag(typeck::field_already_declared, code = "E0124")]
 pub struct FieldAlreadyDeclared {
     pub field_name: Ident,
     #[primary_span]
@@ -77,7 +77,7 @@ pub struct FieldAlreadyDeclared {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::copy_impl_on_type_with_dtor, code = "E0184")]
+#[diag(typeck::copy_impl_on_type_with_dtor, code = "E0184")]
 pub struct CopyImplOnTypeWithDtor {
     #[primary_span]
     #[label]
@@ -85,14 +85,14 @@ pub struct CopyImplOnTypeWithDtor {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::multiple_relaxed_default_bounds, code = "E0203")]
+#[diag(typeck::multiple_relaxed_default_bounds, code = "E0203")]
 pub struct MultipleRelaxedDefaultBounds {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::copy_impl_on_non_adt, code = "E0206")]
+#[diag(typeck::copy_impl_on_non_adt, code = "E0206")]
 pub struct CopyImplOnNonAdt {
     #[primary_span]
     #[label]
@@ -100,7 +100,7 @@ pub struct CopyImplOnNonAdt {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::trait_object_declared_with_no_traits, code = "E0224")]
+#[diag(typeck::trait_object_declared_with_no_traits, code = "E0224")]
 pub struct TraitObjectDeclaredWithNoTraits {
     #[primary_span]
     pub span: Span,
@@ -109,14 +109,14 @@ pub struct TraitObjectDeclaredWithNoTraits {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0227")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0227")]
 pub struct AmbiguousLifetimeBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::assoc_type_binding_not_allowed, code = "E0229")]
+#[diag(typeck::assoc_type_binding_not_allowed, code = "E0229")]
 pub struct AssocTypeBindingNotAllowed {
     #[primary_span]
     #[label]
@@ -124,14 +124,14 @@ pub struct AssocTypeBindingNotAllowed {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::functional_record_update_on_non_struct, code = "E0436")]
+#[diag(typeck::functional_record_update_on_non_struct, code = "E0436")]
 pub struct FunctionalRecordUpdateOnNonStruct {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::typeof_reserved_keyword_used, code = "E0516")]
+#[diag(typeck::typeof_reserved_keyword_used, code = "E0516")]
 pub struct TypeofReservedKeywordUsed<'tcx> {
     pub ty: Ty<'tcx>,
     #[primary_span]
@@ -142,7 +142,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::return_stmt_outside_of_fn_body, code = "E0572")]
+#[diag(typeck::return_stmt_outside_of_fn_body, code = "E0572")]
 pub struct ReturnStmtOutsideOfFnBody {
     #[primary_span]
     pub span: Span,
@@ -153,14 +153,14 @@ pub struct ReturnStmtOutsideOfFnBody {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::yield_expr_outside_of_generator, code = "E0627")]
+#[diag(typeck::yield_expr_outside_of_generator, code = "E0627")]
 pub struct YieldExprOutsideOfGenerator {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::struct_expr_non_exhaustive, code = "E0639")]
+#[diag(typeck::struct_expr_non_exhaustive, code = "E0639")]
 pub struct StructExprNonExhaustive {
     #[primary_span]
     pub span: Span,
@@ -168,14 +168,14 @@ pub struct StructExprNonExhaustive {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::method_call_on_unknown_type, code = "E0699")]
+#[diag(typeck::method_call_on_unknown_type, code = "E0699")]
 pub struct MethodCallOnUnknownType {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::value_of_associated_struct_already_specified, code = "E0719")]
+#[diag(typeck::value_of_associated_struct_already_specified, code = "E0719")]
 pub struct ValueOfAssociatedStructAlreadySpecified {
     #[primary_span]
     #[label]
@@ -187,7 +187,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::address_of_temporary_taken, code = "E0745")]
+#[diag(typeck::address_of_temporary_taken, code = "E0745")]
 pub struct AddressOfTemporaryTaken {
     #[primary_span]
     #[label]
@@ -233,7 +233,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::unconstrained_opaque_type)]
+#[diag(typeck::unconstrained_opaque_type)]
 #[note]
 pub struct UnconstrainedOpaqueType {
     #[primary_span]
@@ -309,7 +309,7 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::manual_implementation, code = "E0183")]
+#[diag(typeck::manual_implementation, code = "E0183")]
 #[help]
 pub struct ManualImplementation {
     #[primary_span]
@@ -319,8 +319,31 @@ pub struct ManualImplementation {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::substs_on_overridden_impl)]
+#[diag(typeck::substs_on_overridden_impl)]
 pub struct SubstsOnOverriddenImpl {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(typeck::unused_extern_crate)]
+pub struct UnusedExternCrate {
+    #[suggestion(applicability = "machine-applicable", code = "")]
+    pub span: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(typeck::extern_crate_not_idiomatic)]
+pub struct ExternCrateNotIdiomatic {
+    #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")]
+    pub span: Span,
+    pub msg_code: String,
+    pub suggestion_code: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(typeck::expected_used_symbol)]
+pub struct ExpectedUsedSymbol {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 8b6f4054851..62fd5955726 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -56,10 +56,6 @@
 //! [`Rc`]: rc
 //! [`RefCell`]: core::cell
 
-// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
-// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
-// rustc itself never sets the feature, so this line has no affect there.
-#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
 #![allow(unused_attributes)]
 #![stable(feature = "alloc", since = "1.36.0")]
 #![doc(
@@ -77,6 +73,10 @@
 ))]
 #![no_std]
 #![needs_allocator]
+// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
 //
 // Lints:
 #![deny(unsafe_op_in_unsafe_fn)]
@@ -145,6 +145,7 @@
 #![feature(unchecked_math)]
 #![feature(unicode_internals)]
 #![feature(unsize)]
+#![feature(utf8_chunks)]
 #![feature(std_internals)]
 //
 // Language features:
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index d5ed2c4adf4..b94b1b1ce21 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -71,6 +71,8 @@ pub use core::str::{RSplit, Split};
 pub use core::str::{RSplitN, SplitN};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::{RSplitTerminator, SplitTerminator};
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+pub use core::str::{Utf8Chunk, Utf8Chunks};
 
 /// Note: `str` in `Concat<str>` is not meaningful here.
 /// This type parameter of the trait only exists to enable another impl.
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index a5118e5333b..7bee894d3e4 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -58,9 +58,9 @@ use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{self, Index, IndexMut, Range, RangeBounds};
 use core::ptr;
 use core::slice;
-#[cfg(not(no_global_oom_handling))]
-use core::str::lossy;
 use core::str::pattern::Pattern;
+#[cfg(not(no_global_oom_handling))]
+use core::str::Utf8Chunks;
 
 #[cfg(not(no_global_oom_handling))]
 use crate::borrow::{Cow, ToOwned};
@@ -628,11 +628,11 @@ impl String {
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
-        let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();
+        let mut iter = Utf8Chunks::new(v);
 
         let first_valid = if let Some(chunk) = iter.next() {
-            let lossy::Utf8LossyChunk { valid, broken } = chunk;
-            if broken.is_empty() {
+            let valid = chunk.valid();
+            if chunk.invalid().is_empty() {
                 debug_assert_eq!(valid.len(), v.len());
                 return Cow::Borrowed(valid);
             }
@@ -647,9 +647,9 @@ impl String {
         res.push_str(first_valid);
         res.push_str(REPLACEMENT);
 
-        for lossy::Utf8LossyChunk { valid, broken } in iter {
-            res.push_str(valid);
-            if !broken.is_empty() {
+        for chunk in iter {
+            res.push_str(chunk.valid());
+            if !chunk.invalid().is_empty() {
                 res.push_str(REPLACEMENT);
             }
         }
diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs
index 202d0e7f020..0fae8953aa2 100644
--- a/library/alloc/src/sync/tests.rs
+++ b/library/alloc/src/sync/tests.rs
@@ -618,3 +618,22 @@ fn test_arc_cyclic_two_refs() {
     assert_eq!(Arc::strong_count(&two_refs), 3);
     assert_eq!(Arc::weak_count(&two_refs), 2);
 }
+
+/// Test for Arc::drop bug (https://github.com/rust-lang/rust/issues/55005)
+#[test]
+#[cfg(miri)] // relies on Stacked Borrows in Miri
+fn arc_drop_dereferenceable_race() {
+    // The bug seems to take up to 700 iterations to reproduce with most seeds (tested 0-9).
+    for _ in 0..750 {
+        let arc_1 = Arc::new(());
+        let arc_2 = arc_1.clone();
+        let thread = thread::spawn(|| drop(arc_2));
+        // Spin a bit; makes the race more likely to appear
+        let mut i = 0;
+        while i < 256 {
+            i += 1;
+        }
+        drop(arc_1);
+        thread.join().unwrap();
+    }
+}
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 171f4902236..5ca5b5fde16 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -38,8 +38,10 @@ use self::Ordering::*;
 ///
 /// Implementations must ensure that `eq` and `ne` are consistent with each other:
 ///
-/// - `a != b` if and only if `!(a == b)`
-///   (ensured by the default implementation).
+/// - `a != b` if and only if `!(a == b)`.
+///
+/// The default implementation of `ne` provides this consistency and is almost
+/// always sufficient. It should not be overridden without very good reason.
 ///
 /// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also
 /// be consistent with `PartialEq` (see the documentation of those traits for the exact
@@ -225,7 +227,8 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn eq(&self, other: &Rhs) -> bool;
 
-    /// This method tests for `!=`.
+    /// This method tests for `!=`. The default implementation is almost always
+    /// sufficient, and should not be overridden without very good reason.
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 15a120e35a2..307016c2690 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -1,6 +1,6 @@
 use crate::fmt;
 use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
-use crate::ops::Try;
+use crate::ops::{ControlFlow, Try};
 
 /// An iterator that maps each element to an iterator, and yields the elements
 /// of the produced iterators.
@@ -73,6 +73,21 @@ where
     {
         self.inner.fold(init, fold)
     }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+        self.inner.advance_by(n)
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.inner.count()
+    }
+
+    #[inline]
+    fn last(self) -> Option<Self::Item> {
+        self.inner.last()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -103,6 +118,11 @@ where
     {
         self.inner.rfold(init, fold)
     }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+        self.inner.advance_back_by(n)
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
@@ -214,6 +234,21 @@ where
     {
         self.inner.fold(init, fold)
     }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+        self.inner.advance_by(n)
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.inner.count()
+    }
+
+    #[inline]
+    fn last(self) -> Option<Self::Item> {
+        self.inner.last()
+    }
 }
 
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
@@ -244,6 +279,11 @@ where
     {
         self.inner.rfold(init, fold)
     }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+        self.inner.advance_back_by(n)
+    }
 }
 
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
@@ -280,6 +320,144 @@ where
     }
 }
 
+impl<I, U> FlattenCompat<I, U>
+where
+    I: Iterator<Item: IntoIterator<IntoIter = U>>,
+{
+    /// Folds the inner iterators into an accumulator by applying an operation.
+    ///
+    /// Folds over the inner iterators, not over their elements. Is used by the `fold`, `count`,
+    /// and `last` methods.
+    #[inline]
+    fn iter_fold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, U) -> Acc,
+    {
+        #[inline]
+        fn flatten<T: IntoIterator, Acc>(
+            fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
+        ) -> impl FnMut(Acc, T) -> Acc + '_ {
+            move |acc, iter| fold(acc, iter.into_iter())
+        }
+
+        if let Some(iter) = self.frontiter {
+            acc = fold(acc, iter);
+        }
+
+        acc = self.iter.fold(acc, flatten(&mut fold));
+
+        if let Some(iter) = self.backiter {
+            acc = fold(acc, iter);
+        }
+
+        acc
+    }
+
+    /// Folds over the inner iterators as long as the given function returns successfully,
+    /// always storing the most recent inner iterator in `self.frontiter`.
+    ///
+    /// Folds over the inner iterators, not over their elements. Is used by the `try_fold` and
+    /// `advance_by` methods.
+    #[inline]
+    fn iter_try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
+    where
+        Fold: FnMut(Acc, &mut U) -> R,
+        R: Try<Output = Acc>,
+    {
+        #[inline]
+        fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
+            frontiter: &'a mut Option<T::IntoIter>,
+            fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
+        ) -> impl FnMut(Acc, T) -> R + 'a {
+            move |acc, iter| fold(acc, frontiter.insert(iter.into_iter()))
+        }
+
+        if let Some(iter) = &mut self.frontiter {
+            acc = fold(acc, iter)?;
+        }
+        self.frontiter = None;
+
+        acc = self.iter.try_fold(acc, flatten(&mut self.frontiter, &mut fold))?;
+        self.frontiter = None;
+
+        if let Some(iter) = &mut self.backiter {
+            acc = fold(acc, iter)?;
+        }
+        self.backiter = None;
+
+        try { acc }
+    }
+}
+
+impl<I, U> FlattenCompat<I, U>
+where
+    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U>>,
+{
+    /// Folds the inner iterators into an accumulator by applying an operation, starting form the
+    /// back.
+    ///
+    /// Folds over the inner iterators, not over their elements. Is used by the `rfold` method.
+    #[inline]
+    fn iter_rfold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, U) -> Acc,
+    {
+        #[inline]
+        fn flatten<T: IntoIterator, Acc>(
+            fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
+        ) -> impl FnMut(Acc, T) -> Acc + '_ {
+            move |acc, iter| fold(acc, iter.into_iter())
+        }
+
+        if let Some(iter) = self.backiter {
+            acc = fold(acc, iter);
+        }
+
+        acc = self.iter.rfold(acc, flatten(&mut fold));
+
+        if let Some(iter) = self.frontiter {
+            acc = fold(acc, iter);
+        }
+
+        acc
+    }
+
+    /// Folds over the inner iterators in reverse order as long as the given function returns
+    /// successfully, always storing the most recent inner iterator in `self.backiter`.
+    ///
+    /// Folds over the inner iterators, not over their elements. Is used by the `try_rfold` and
+    /// `advance_back_by` methods.
+    #[inline]
+    fn iter_try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
+    where
+        Fold: FnMut(Acc, &mut U) -> R,
+        R: Try<Output = Acc>,
+    {
+        #[inline]
+        fn flatten<'a, T: IntoIterator, Acc, R: Try>(
+            backiter: &'a mut Option<T::IntoIter>,
+            fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
+        ) -> impl FnMut(Acc, T) -> R + 'a {
+            move |acc, iter| fold(acc, backiter.insert(iter.into_iter()))
+        }
+
+        if let Some(iter) = &mut self.backiter {
+            acc = fold(acc, iter)?;
+        }
+        self.backiter = None;
+
+        acc = self.iter.try_rfold(acc, flatten(&mut self.backiter, &mut fold))?;
+        self.backiter = None;
+
+        if let Some(iter) = &mut self.frontiter {
+            acc = fold(acc, iter)?;
+        }
+        self.frontiter = None;
+
+        try { acc }
+    }
+}
+
 impl<I, U> Iterator for FlattenCompat<I, U>
 where
     I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
@@ -323,99 +501,74 @@ where
     }
 
     #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
     {
         #[inline]
-        fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
-            frontiter: &'a mut Option<T::IntoIter>,
-            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
-        ) -> impl FnMut(Acc, T) -> R + 'a {
-            move |acc, x| {
-                let mut mid = x.into_iter();
-                let r = mid.try_fold(acc, &mut *fold);
-                *frontiter = Some(mid);
-                r
-            }
-        }
-
-        if let Some(ref mut front) = self.frontiter {
-            init = front.try_fold(init, &mut fold)?;
+        fn flatten<U: Iterator, Acc, R: Try<Output = Acc>>(
+            mut fold: impl FnMut(Acc, U::Item) -> R,
+        ) -> impl FnMut(Acc, &mut U) -> R {
+            move |acc, iter| iter.try_fold(acc, &mut fold)
         }
-        self.frontiter = None;
 
-        init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
-        self.frontiter = None;
-
-        if let Some(ref mut back) = self.backiter {
-            init = back.try_fold(init, &mut fold)?;
-        }
-        self.backiter = None;
-
-        try { init }
+        self.iter_try_fold(init, flatten(fold))
     }
 
     #[inline]
-    fn fold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
         #[inline]
-        fn flatten<T: IntoIterator, Acc>(
-            fold: &mut impl FnMut(Acc, T::Item) -> Acc,
-        ) -> impl FnMut(Acc, T) -> Acc + '_ {
-            move |acc, x| x.into_iter().fold(acc, &mut *fold)
-        }
-
-        if let Some(front) = self.frontiter {
-            init = front.fold(init, &mut fold);
-        }
-
-        init = self.iter.fold(init, flatten(&mut fold));
-
-        if let Some(back) = self.backiter {
-            init = back.fold(init, &mut fold);
+        fn flatten<U: Iterator, Acc>(
+            mut fold: impl FnMut(Acc, U::Item) -> Acc,
+        ) -> impl FnMut(Acc, U) -> Acc {
+            move |acc, iter| iter.fold(acc, &mut fold)
         }
 
-        init
+        self.iter_fold(init, flatten(fold))
     }
 
     #[inline]
     #[rustc_inherit_overflow_checks]
     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
-        let mut rem = n;
-        loop {
-            if let Some(ref mut front) = self.frontiter {
-                match front.advance_by(rem) {
-                    ret @ Ok(_) => return ret,
-                    Err(advanced) => rem -= advanced,
-                }
-            }
-            self.frontiter = match self.iter.next() {
-                Some(iterable) => Some(iterable.into_iter()),
-                _ => break,
+        #[inline]
+        #[rustc_inherit_overflow_checks]
+        fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
+            match iter.advance_by(n) {
+                Ok(()) => ControlFlow::BREAK,
+                Err(advanced) => ControlFlow::Continue(n - advanced),
             }
         }
 
-        self.frontiter = None;
-
-        if let Some(ref mut back) = self.backiter {
-            match back.advance_by(rem) {
-                ret @ Ok(_) => return ret,
-                Err(advanced) => rem -= advanced,
-            }
+        match self.iter_try_fold(n, advance) {
+            ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining),
+            _ => Ok(()),
         }
+    }
 
-        if rem > 0 {
-            return Err(n - rem);
+    #[inline]
+    fn count(self) -> usize {
+        #[inline]
+        #[rustc_inherit_overflow_checks]
+        fn count<U: Iterator>(acc: usize, iter: U) -> usize {
+            acc + iter.count()
         }
 
-        self.backiter = None;
+        self.iter_fold(0, count)
+    }
+
+    #[inline]
+    fn last(self) -> Option<Self::Item> {
+        #[inline]
+        fn last<U: Iterator>(last: Option<U::Item>, iter: U) -> Option<U::Item> {
+            iter.last().or(last)
+        }
 
-        Ok(())
+        self.iter_fold(None, last)
     }
 }
 
@@ -438,105 +591,53 @@ where
     }
 
     #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
     {
         #[inline]
-        fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
-            backiter: &'a mut Option<T::IntoIter>,
-            fold: &'a mut impl FnMut(Acc, T::Item) -> R,
-        ) -> impl FnMut(Acc, T) -> R + 'a
-        where
-            T::IntoIter: DoubleEndedIterator,
-        {
-            move |acc, x| {
-                let mut mid = x.into_iter();
-                let r = mid.try_rfold(acc, &mut *fold);
-                *backiter = Some(mid);
-                r
-            }
+        fn flatten<U: DoubleEndedIterator, Acc, R: Try<Output = Acc>>(
+            mut fold: impl FnMut(Acc, U::Item) -> R,
+        ) -> impl FnMut(Acc, &mut U) -> R {
+            move |acc, iter| iter.try_rfold(acc, &mut fold)
         }
 
-        if let Some(ref mut back) = self.backiter {
-            init = back.try_rfold(init, &mut fold)?;
-        }
-        self.backiter = None;
-
-        init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
-        self.backiter = None;
-
-        if let Some(ref mut front) = self.frontiter {
-            init = front.try_rfold(init, &mut fold)?;
-        }
-        self.frontiter = None;
-
-        try { init }
+        self.iter_try_rfold(init, flatten(fold))
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
         #[inline]
-        fn flatten<T: IntoIterator, Acc>(
-            fold: &mut impl FnMut(Acc, T::Item) -> Acc,
-        ) -> impl FnMut(Acc, T) -> Acc + '_
-        where
-            T::IntoIter: DoubleEndedIterator,
-        {
-            move |acc, x| x.into_iter().rfold(acc, &mut *fold)
-        }
-
-        if let Some(back) = self.backiter {
-            init = back.rfold(init, &mut fold);
+        fn flatten<U: DoubleEndedIterator, Acc>(
+            mut fold: impl FnMut(Acc, U::Item) -> Acc,
+        ) -> impl FnMut(Acc, U) -> Acc {
+            move |acc, iter| iter.rfold(acc, &mut fold)
         }
 
-        init = self.iter.rfold(init, flatten(&mut fold));
-
-        if let Some(front) = self.frontiter {
-            init = front.rfold(init, &mut fold);
-        }
-
-        init
+        self.iter_rfold(init, flatten(fold))
     }
 
     #[inline]
     #[rustc_inherit_overflow_checks]
     fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
-        let mut rem = n;
-        loop {
-            if let Some(ref mut back) = self.backiter {
-                match back.advance_back_by(rem) {
-                    ret @ Ok(_) => return ret,
-                    Err(advanced) => rem -= advanced,
-                }
-            }
-            match self.iter.next_back() {
-                Some(iterable) => self.backiter = Some(iterable.into_iter()),
-                _ => break,
-            }
-        }
-
-        self.backiter = None;
-
-        if let Some(ref mut front) = self.frontiter {
-            match front.advance_back_by(rem) {
-                ret @ Ok(_) => return ret,
-                Err(advanced) => rem -= advanced,
+        #[inline]
+        #[rustc_inherit_overflow_checks]
+        fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
+            match iter.advance_back_by(n) {
+                Ok(()) => ControlFlow::BREAK,
+                Err(advanced) => ControlFlow::Continue(n - advanced),
             }
         }
 
-        if rem > 0 {
-            return Err(n - rem);
+        match self.iter_try_rfold(n, advance) {
+            ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining),
+            _ => Ok(()),
         }
-
-        self.frontiter = None;
-
-        Ok(())
     }
 }
 
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 6548ad2e514..23c46f1a74a 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -394,7 +394,7 @@ impl f32 {
 
     /// Not a Number (NaN).
     ///
-    /// Note that IEEE-745 doesn't define just a single NaN value;
+    /// Note that IEEE-754 doesn't define just a single NaN value;
     /// a plethora of bit patterns are considered to be NaN.
     /// Furthermore, the standard makes a difference
     /// between a "signaling" and a "quiet" NaN,
@@ -632,7 +632,7 @@ impl f32 {
     }
 
     /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
-    /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any
+    /// positive sign bit and positive infinity. Note that IEEE-754 doesn't assign any
     /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
     /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
     /// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
@@ -654,7 +654,7 @@ impl f32 {
     }
 
     /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
-    /// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any
+    /// negative sign bit and negative infinity. Note that IEEE-754 doesn't assign any
     /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
     /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
     /// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 75c92c2f883..b5c8241d294 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -393,7 +393,7 @@ impl f64 {
 
     /// Not a Number (NaN).
     ///
-    /// Note that IEEE-745 doesn't define just a single NaN value;
+    /// Note that IEEE-754 doesn't define just a single NaN value;
     /// a plethora of bit patterns are considered to be NaN.
     /// Furthermore, the standard makes a difference
     /// between a "signaling" and a "quiet" NaN,
@@ -624,7 +624,7 @@ impl f64 {
     }
 
     /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
-    /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any
+    /// positive sign bit and positive infinity. Note that IEEE-754 doesn't assign any
     /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
     /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
     /// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
@@ -655,7 +655,7 @@ impl f64 {
     }
 
     /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
-    /// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any
+    /// negative sign bit and negative infinity. Note that IEEE-754 doesn't assign any
     /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
     /// the bit pattern of NaNs are conserved over arithmetic operations, the result of
     /// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index f481399fdcf..72b6dc28185 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -623,7 +623,7 @@ impl u8 {
     ///
     /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
     /// - U+003A ..= U+0040 `: ; < = > ? @`, or
-    /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
+    /// - U+005B ..= U+0060 `` [ \ ] ^ _ ` ``, or
     /// - U+007B ..= U+007E `{ | } ~`
     ///
     /// # Examples
diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs
index 6ec1c93908f..59f873d1268 100644
--- a/library/core/src/str/lossy.rs
+++ b/library/core/src/str/lossy.rs
@@ -1,51 +1,170 @@
-use crate::char;
-use crate::fmt::{self, Write};
-use crate::mem;
+use crate::fmt;
+use crate::fmt::Formatter;
+use crate::fmt::Write;
+use crate::iter::FusedIterator;
 
 use super::from_utf8_unchecked;
 use super::validations::utf8_char_width;
 
-/// Lossy UTF-8 string.
-#[unstable(feature = "str_internals", issue = "none")]
-pub struct Utf8Lossy {
-    bytes: [u8],
+/// An item returned by the [`Utf8Chunks`] iterator.
+///
+/// A `Utf8Chunk` stores a sequence of [`u8`] up to the first broken character
+/// when decoding a UTF-8 string.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(utf8_chunks)]
+///
+/// use std::str::Utf8Chunks;
+///
+/// // An invalid UTF-8 string
+/// let bytes = b"foo\xF1\x80bar";
+///
+/// // Decode the first `Utf8Chunk`
+/// let chunk = Utf8Chunks::new(bytes).next().unwrap();
+///
+/// // The first three characters are valid UTF-8
+/// assert_eq!("foo", chunk.valid());
+///
+/// // The fourth character is broken
+/// assert_eq!(b"\xF1\x80", chunk.invalid());
+/// ```
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Utf8Chunk<'a> {
+    valid: &'a str,
+    invalid: &'a [u8],
 }
 
-impl Utf8Lossy {
+impl<'a> Utf8Chunk<'a> {
+    /// Returns the next validated UTF-8 substring.
+    ///
+    /// This substring can be empty at the start of the string or between
+    /// broken UTF-8 characters.
     #[must_use]
-    pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy {
-        // SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required.
-        unsafe { mem::transmute(bytes) }
+    #[unstable(feature = "utf8_chunks", issue = "99543")]
+    pub fn valid(&self) -> &'a str {
+        self.valid
     }
 
-    pub fn chunks(&self) -> Utf8LossyChunksIter<'_> {
-        Utf8LossyChunksIter { source: &self.bytes }
+    /// Returns the invalid sequence that caused a failure.
+    ///
+    /// The returned slice will have a maximum length of 3 and starts after the
+    /// substring given by [`valid`]. Decoding will resume after this sequence.
+    ///
+    /// If empty, this is the last chunk in the string. If non-empty, an
+    /// unexpected byte was encountered or the end of the input was reached
+    /// unexpectedly.
+    ///
+    /// Lossy decoding would replace this sequence with [`U+FFFD REPLACEMENT
+    /// CHARACTER`].
+    ///
+    /// [`valid`]: Self::valid
+    /// [`U+FFFD REPLACEMENT CHARACTER`]: crate::char::REPLACEMENT_CHARACTER
+    #[must_use]
+    #[unstable(feature = "utf8_chunks", issue = "99543")]
+    pub fn invalid(&self) -> &'a [u8] {
+        self.invalid
     }
 }
 
-/// Iterator over lossy UTF-8 string
-#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[must_use]
+#[unstable(feature = "str_internals", issue = "none")]
+pub struct Debug<'a>(&'a [u8]);
+
 #[unstable(feature = "str_internals", issue = "none")]
-#[allow(missing_debug_implementations)]
-pub struct Utf8LossyChunksIter<'a> {
+impl fmt::Debug for Debug<'_> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        f.write_char('"')?;
+
+        for chunk in Utf8Chunks::new(self.0) {
+            // Valid part.
+            // Here we partially parse UTF-8 again which is suboptimal.
+            {
+                let valid = chunk.valid();
+                let mut from = 0;
+                for (i, c) in valid.char_indices() {
+                    let esc = c.escape_debug();
+                    // If char needs escaping, flush backlog so far and write, else skip
+                    if esc.len() != 1 {
+                        f.write_str(&valid[from..i])?;
+                        for c in esc {
+                            f.write_char(c)?;
+                        }
+                        from = i + c.len_utf8();
+                    }
+                }
+                f.write_str(&valid[from..])?;
+            }
+
+            // Broken parts of string as hex escape.
+            for &b in chunk.invalid() {
+                write!(f, "\\x{:02X}", b)?;
+            }
+        }
+
+        f.write_char('"')
+    }
+}
+
+/// An iterator used to decode a slice of mostly UTF-8 bytes to string slices
+/// ([`&str`]) and byte slices ([`&[u8]`][byteslice]).
+///
+/// If you want a simple conversion from UTF-8 byte slices to string slices,
+/// [`from_utf8`] is easier to use.
+///
+/// [byteslice]: slice
+/// [`from_utf8`]: super::from_utf8
+///
+/// # Examples
+///
+/// This can be used to create functionality similar to
+/// [`String::from_utf8_lossy`] without allocating heap memory:
+///
+/// ```
+/// #![feature(utf8_chunks)]
+///
+/// use std::str::Utf8Chunks;
+///
+/// fn from_utf8_lossy<F>(input: &[u8], mut push: F) where F: FnMut(&str) {
+///     for chunk in Utf8Chunks::new(input) {
+///         push(chunk.valid());
+///
+///         if !chunk.invalid().is_empty() {
+///             push("\u{FFFD}");
+///         }
+///     }
+/// }
+/// ```
+///
+/// [`String::from_utf8_lossy`]: ../../std/string/struct.String.html#method.from_utf8_lossy
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+#[derive(Clone)]
+pub struct Utf8Chunks<'a> {
     source: &'a [u8],
 }
 
-#[unstable(feature = "str_internals", issue = "none")]
-#[derive(PartialEq, Eq, Debug)]
-pub struct Utf8LossyChunk<'a> {
-    /// Sequence of valid chars.
-    /// Can be empty between broken UTF-8 chars.
-    pub valid: &'a str,
-    /// Single broken char, empty if none.
-    /// Empty iff iterator item is last.
-    pub broken: &'a [u8],
+impl<'a> Utf8Chunks<'a> {
+    /// Creates a new iterator to decode the bytes.
+    #[unstable(feature = "utf8_chunks", issue = "99543")]
+    pub fn new(bytes: &'a [u8]) -> Self {
+        Self { source: bytes }
+    }
+
+    #[doc(hidden)]
+    #[unstable(feature = "str_internals", issue = "none")]
+    pub fn debug(&self) -> Debug<'_> {
+        Debug(self.source)
+    }
 }
 
-impl<'a> Iterator for Utf8LossyChunksIter<'a> {
-    type Item = Utf8LossyChunk<'a>;
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+impl<'a> Iterator for Utf8Chunks<'a> {
+    type Item = Utf8Chunk<'a>;
 
-    fn next(&mut self) -> Option<Utf8LossyChunk<'a>> {
+    fn next(&mut self) -> Option<Utf8Chunk<'a>> {
         if self.source.is_empty() {
             return None;
         }
@@ -130,71 +249,22 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
 
         // SAFETY: `valid_up_to <= i` because it is only ever assigned via
         // `valid_up_to = i` and `i` only increases.
-        let (valid, broken) = unsafe { inspected.split_at_unchecked(valid_up_to) };
+        let (valid, invalid) = unsafe { inspected.split_at_unchecked(valid_up_to) };
 
-        Some(Utf8LossyChunk {
+        Some(Utf8Chunk {
             // SAFETY: All bytes up to `valid_up_to` are valid UTF-8.
             valid: unsafe { from_utf8_unchecked(valid) },
-            broken,
+            invalid,
         })
     }
 }
 
-impl fmt::Display for Utf8Lossy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // If we're the empty string then our iterator won't actually yield
-        // anything, so perform the formatting manually
-        if self.bytes.is_empty() {
-            return "".fmt(f);
-        }
-
-        for Utf8LossyChunk { valid, broken } in self.chunks() {
-            // If we successfully decoded the whole chunk as a valid string then
-            // we can return a direct formatting of the string which will also
-            // respect various formatting flags if possible.
-            if valid.len() == self.bytes.len() {
-                assert!(broken.is_empty());
-                return valid.fmt(f);
-            }
-
-            f.write_str(valid)?;
-            if !broken.is_empty() {
-                f.write_char(char::REPLACEMENT_CHARACTER)?;
-            }
-        }
-        Ok(())
-    }
-}
-
-impl fmt::Debug for Utf8Lossy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_char('"')?;
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+impl FusedIterator for Utf8Chunks<'_> {}
 
-        for Utf8LossyChunk { valid, broken } in self.chunks() {
-            // Valid part.
-            // Here we partially parse UTF-8 again which is suboptimal.
-            {
-                let mut from = 0;
-                for (i, c) in valid.char_indices() {
-                    let esc = c.escape_debug();
-                    // If char needs escaping, flush backlog so far and write, else skip
-                    if esc.len() != 1 {
-                        f.write_str(&valid[from..i])?;
-                        for c in esc {
-                            f.write_char(c)?;
-                        }
-                        from = i + c.len_utf8();
-                    }
-                }
-                f.write_str(&valid[from..])?;
-            }
-
-            // Broken parts of string as hex escape.
-            for &b in broken {
-                write!(f, "\\x{:02x}", b)?;
-            }
-        }
-
-        f.write_char('"')
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+impl fmt::Debug for Utf8Chunks<'_> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Utf8Chunks").field("source", &self.debug()).finish()
     }
 }
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index ee66895a7ed..e44e025aaf1 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -22,9 +22,9 @@ use crate::slice::{self, SliceIndex};
 
 pub mod pattern;
 
-#[unstable(feature = "str_internals", issue = "none")]
-#[allow(missing_docs)]
-pub mod lossy;
+mod lossy;
+#[unstable(feature = "utf8_chunks", issue = "99543")]
+pub use lossy::{Utf8Chunk, Utf8Chunks};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use converts::{from_utf8, from_utf8_unchecked};
diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs
index f8ab8c9d444..690fd0c2197 100644
--- a/library/core/tests/iter/adapters/flatten.rs
+++ b/library/core/tests/iter/adapters/flatten.rs
@@ -168,3 +168,45 @@ fn test_trusted_len_flatten() {
     assert_trusted_len(&iter);
     assert_eq!(iter.size_hint(), (20, Some(20)));
 }
+
+#[test]
+fn test_flatten_count() {
+    let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten();
+
+    assert_eq!(it.clone().count(), 40);
+    it.advance_by(5).unwrap();
+    assert_eq!(it.clone().count(), 35);
+    it.advance_back_by(5).unwrap();
+    assert_eq!(it.clone().count(), 30);
+    it.advance_by(10).unwrap();
+    assert_eq!(it.clone().count(), 20);
+    it.advance_back_by(8).unwrap();
+    assert_eq!(it.clone().count(), 12);
+    it.advance_by(4).unwrap();
+    assert_eq!(it.clone().count(), 8);
+    it.advance_back_by(5).unwrap();
+    assert_eq!(it.clone().count(), 3);
+    it.advance_by(3).unwrap();
+    assert_eq!(it.clone().count(), 0);
+}
+
+#[test]
+fn test_flatten_last() {
+    let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten();
+
+    assert_eq!(it.clone().last(), Some(39));
+    it.advance_by(5).unwrap(); // 5..40
+    assert_eq!(it.clone().last(), Some(39));
+    it.advance_back_by(5).unwrap(); // 5..35
+    assert_eq!(it.clone().last(), Some(34));
+    it.advance_by(10).unwrap(); // 15..35
+    assert_eq!(it.clone().last(), Some(34));
+    it.advance_back_by(8).unwrap(); // 15..27
+    assert_eq!(it.clone().last(), Some(26));
+    it.advance_by(4).unwrap(); // 19..27
+    assert_eq!(it.clone().last(), Some(26));
+    it.advance_back_by(5).unwrap(); // 19..22
+    assert_eq!(it.clone().last(), Some(21));
+    it.advance_by(3).unwrap(); // 22..22
+    assert_eq!(it.clone().last(), None);
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 09f1500f564..59510d3cc2a 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -99,6 +99,7 @@
 #![feature(waker_getters)]
 #![feature(slice_flatten)]
 #![feature(provide_any)]
+#![feature(utf8_chunks)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 extern crate test;
diff --git a/library/core/tests/str_lossy.rs b/library/core/tests/str_lossy.rs
index d4b47a4708e..9d3f0b65fdb 100644
--- a/library/core/tests/str_lossy.rs
+++ b/library/core/tests/str_lossy.rs
@@ -1,85 +1,85 @@
-use core::str::lossy::*;
+use core::str::Utf8Chunks;
 
 #[test]
 fn chunks() {
-    let mut iter = Utf8Lossy::from_bytes(b"hello").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "hello", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
+    macro_rules! assert_chunks {
+        ( $string:expr, $(($valid:expr, $invalid:expr)),* $(,)? ) => {{
+            let mut iter = Utf8Chunks::new($string);
+            $(
+                let chunk = iter.next().expect("missing chunk");
+                assert_eq!($valid, chunk.valid());
+                assert_eq!($invalid, chunk.invalid());
+            )*
+            assert_eq!(None, iter.next());
+        }};
+    }
 
-    let mut iter = Utf8Lossy::from_bytes("ศไทย中华Việt Nam".as_bytes()).chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "ศไทย中华Việt Nam", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
-
-    let mut iter = Utf8Lossy::from_bytes(b"Hello\xC2 There\xFF Goodbye").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC2" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xFF" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
-
-    let mut iter = Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC0" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xE6\x83" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
-
-    let mut iter = Utf8Lossy::from_bytes(b"\xF5foo\xF5\x80bar").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF5" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF5" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
-
-    let mut iter = Utf8Lossy::from_bytes(b"\xF1foo\xF1\x80bar\xF1\x80\x80baz").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF1" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF1\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF1\x80\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
-
-    let mut iter = Utf8Lossy::from_bytes(b"\xF4foo\xF4\x80bar\xF4\xBFbaz").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF4" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF4\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF4" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
-
-    let mut iter = Utf8Lossy::from_bytes(b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF0" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "foo\u{10000}bar", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
+    assert_chunks!(b"hello", ("hello", b""));
+    assert_chunks!("ศไทย中华Việt Nam".as_bytes(), ("ศไทย中华Việt Nam", b""));
+    assert_chunks!(
+        b"Hello\xC2 There\xFF Goodbye",
+        ("Hello", b"\xC2"),
+        (" There", b"\xFF"),
+        (" Goodbye", b""),
+    );
+    assert_chunks!(
+        b"Hello\xC0\x80 There\xE6\x83 Goodbye",
+        ("Hello", b"\xC0"),
+        ("", b"\x80"),
+        (" There", b"\xE6\x83"),
+        (" Goodbye", b""),
+    );
+    assert_chunks!(
+        b"\xF5foo\xF5\x80bar",
+        ("", b"\xF5"),
+        ("foo", b"\xF5"),
+        ("", b"\x80"),
+        ("bar", b""),
+    );
+    assert_chunks!(
+        b"\xF1foo\xF1\x80bar\xF1\x80\x80baz",
+        ("", b"\xF1"),
+        ("foo", b"\xF1\x80"),
+        ("bar", b"\xF1\x80\x80"),
+        ("baz", b""),
+    );
+    assert_chunks!(
+        b"\xF4foo\xF4\x80bar\xF4\xBFbaz",
+        ("", b"\xF4"),
+        ("foo", b"\xF4\x80"),
+        ("bar", b"\xF4"),
+        ("", b"\xBF"),
+        ("baz", b""),
+    );
+    assert_chunks!(
+        b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar",
+        ("", b"\xF0"),
+        ("", b"\x80"),
+        ("", b"\x80"),
+        ("", b"\x80"),
+        ("foo\u{10000}bar", b""),
+    );
 
     // surrogates
-    let mut iter = Utf8Lossy::from_bytes(b"\xED\xA0\x80foo\xED\xBF\xBFbar").chunks();
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xED" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xA0" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xED" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
-    assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next());
-    assert_eq!(None, iter.next());
-}
-
-#[test]
-fn display() {
-    assert_eq!(
-        "Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye",
-        &Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
+    assert_chunks!(
+        b"\xED\xA0\x80foo\xED\xBF\xBFbar",
+        ("", b"\xED"),
+        ("", b"\xA0"),
+        ("", b"\x80"),
+        ("foo", b"\xED"),
+        ("", b"\xBF"),
+        ("", b"\xBF"),
+        ("bar", b""),
     );
 }
 
 #[test]
 fn debug() {
     assert_eq!(
-        "\"Hello\\xc0\\x80 There\\xe6\\x83 Goodbye\\u{10d4ea}\"",
+        "\"Hello\\xC0\\x80 There\\xE6\\x83 Goodbye\\u{10d4ea}\"",
         &format!(
             "{:?}",
-            Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa")
-        )
+            Utf8Chunks::new(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa").debug(),
+        ),
     );
 }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 229e546e085..3da9565a86d 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -39,7 +39,7 @@ rand = "0.7"
 dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
 
 [target.x86_64-fortanix-unknown-sgx.dependencies]
-fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
+fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(target_os = "hermit")'.dependencies]
 hermit-abi = { version = "0.2.0", features = ['rustc-dep-of-std'] }
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index 7ebc41588b3..cb3032719fa 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -268,10 +268,13 @@ fn test_lots_of_insertions() {
 
     // Try this a few times to make sure we never screw up the hashmap's
     // internal state.
-    for _ in 0..10 {
+    let loops = if cfg!(miri) { 2 } else { 10 };
+    for _ in 0..loops {
         assert!(m.is_empty());
 
-        for i in 1..1001 {
+        let count = if cfg!(miri) { 101 } else { 1001 };
+
+        for i in 1..count {
             assert!(m.insert(i, i).is_none());
 
             for j in 1..=i {
@@ -279,42 +282,42 @@ fn test_lots_of_insertions() {
                 assert_eq!(r, Some(&j));
             }
 
-            for j in i + 1..1001 {
+            for j in i + 1..count {
                 let r = m.get(&j);
                 assert_eq!(r, None);
             }
         }
 
-        for i in 1001..2001 {
+        for i in count..(2 * count) {
             assert!(!m.contains_key(&i));
         }
 
         // remove forwards
-        for i in 1..1001 {
+        for i in 1..count {
             assert!(m.remove(&i).is_some());
 
             for j in 1..=i {
                 assert!(!m.contains_key(&j));
             }
 
-            for j in i + 1..1001 {
+            for j in i + 1..count {
                 assert!(m.contains_key(&j));
             }
         }
 
-        for i in 1..1001 {
+        for i in 1..count {
             assert!(!m.contains_key(&i));
         }
 
-        for i in 1..1001 {
+        for i in 1..count {
             assert!(m.insert(i, i).is_none());
         }
 
         // remove backwards
-        for i in (1..1001).rev() {
+        for i in (1..count).rev() {
             assert!(m.remove(&i).is_some());
 
-            for j in i..1001 {
+            for j in i..count {
                 assert!(!m.contains_key(&j));
             }
 
@@ -817,6 +820,7 @@ fn test_retain() {
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
 fn test_try_reserve() {
     let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index f357f33ec52..68a19eccc0e 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -94,7 +94,7 @@ fn read_to_end() {
     assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
     assert_eq!(v, b"1");
 
-    let cap = 1024 * 1024;
+    let cap = if cfg!(miri) { 1024 } else { 1024 * 1024 };
     let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>();
     let mut v = Vec::new();
     let (a, b) = data.split_at(data.len() / 2);
@@ -309,6 +309,7 @@ fn chain_zero_length_read_is_not_eof() {
 
 #[bench]
 #[cfg_attr(target_os = "emscripten", ignore)]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
 fn bench_read_to_end(b: &mut test::Bencher) {
     b.iter(|| {
         let mut lr = repeat(1).take(10000000);
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 475a1d9fd99..5029023121f 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -187,6 +187,7 @@
 //! [rust-discord]: https://discord.gg/rust-lang
 //! [array]: prim@array
 //! [slice]: prim@slice
+
 #![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
 #![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
 #![doc(
@@ -201,25 +202,35 @@
     no_global_oom_handling,
     not(no_global_oom_handling)
 ))]
+// To run libstd tests without x.py without ending up with two copies of libstd, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
+// miri-test-libstd also prefers to make std use the sysroot versions of the dependencies.
+#![cfg_attr(feature = "miri-test-libstd", feature(rustc_private))]
 // Don't link to std. We are std.
 #![no_std]
+// Tell the compiler to link to either panic_abort or panic_unwind
+#![needs_panic_runtime]
+//
+// Lints:
 #![warn(deprecated_in_future)]
 #![warn(missing_docs)]
 #![warn(missing_debug_implementations)]
 #![allow(explicit_outlives_requirements)]
 #![allow(unused_lifetimes)]
-// Tell the compiler to link to either panic_abort or panic_unwind
-#![needs_panic_runtime]
+#![deny(rustc::existing_doc_keyword)]
 // Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
 #![deny(ffi_unwind_calls)]
 // std may use features in a platform-specific way
 #![allow(unused_features)]
+//
+// Features:
 #![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
 #![cfg_attr(
     all(target_vendor = "fortanix", target_env = "sgx"),
     feature(slice_index_methods, coerce_unsized, sgx_platform)
 )]
-#![deny(rustc::existing_doc_keyword)]
 //
 // Language features:
 #![feature(alloc_error_handler)]
@@ -258,6 +269,7 @@
 #![feature(staged_api)]
 #![feature(thread_local)]
 #![feature(try_blocks)]
+#![feature(utf8_chunks)]
 //
 // Library features (core):
 #![feature(array_error_internals)]
@@ -294,6 +306,8 @@
 #![feature(std_internals)]
 #![feature(str_internals)]
 #![feature(strict_provenance)]
+#![feature(maybe_uninit_uninit_array)]
+#![feature(const_maybe_uninit_uninit_array)]
 //
 // Library features (alloc):
 #![feature(alloc_layout_extra)]
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 41ca9ba8425..189754a161e 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -3,12 +3,14 @@
 mod tests;
 
 use crate::cmp::Ordering;
-use crate::fmt::{self, Write as FmtWrite};
-use crate::io::Write as IoWrite;
+use crate::fmt::{self, Write};
 use crate::mem::transmute;
 use crate::sys::net::netc as c;
 use crate::sys_common::{FromInner, IntoInner};
 
+mod display_buffer;
+use display_buffer::IpDisplayBuffer;
+
 /// An IP address, either IPv4 or IPv6.
 ///
 /// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their
@@ -991,21 +993,19 @@ impl From<Ipv6Addr> for IpAddr {
 impl fmt::Display for Ipv4Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         let octets = self.octets();
-        // Fast Path: if there's no alignment stuff, write directly to the buffer
+
+        // If there are no alignment requirements, write the IP address directly to `f`.
+        // Otherwise, write it to a local buffer and then use `f.pad`.
         if fmt.precision().is_none() && fmt.width().is_none() {
             write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
         } else {
-            const IPV4_BUF_LEN: usize = 15; // Long enough for the longest possible IPv4 address
-            let mut buf = [0u8; IPV4_BUF_LEN];
-            let mut buf_slice = &mut buf[..];
+            const LONGEST_IPV4_ADDR: &str = "255.255.255.255";
 
-            // Note: The call to write should never fail, hence the unwrap
-            write!(buf_slice, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]).unwrap();
-            let len = IPV4_BUF_LEN - buf_slice.len();
+            let mut buf = IpDisplayBuffer::<{ LONGEST_IPV4_ADDR.len() }>::new();
+            // Buffer is long enough for the longest possible IPv4 address, so this should never fail.
+            write!(buf, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]).unwrap();
 
-            // This unsafe is OK because we know what is being written to the buffer
-            let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
-            fmt.pad(buf)
+            fmt.pad(buf.as_str())
         }
     }
 }
@@ -1708,8 +1708,8 @@ impl Ipv6Addr {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Ipv6Addr {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // If there are no alignment requirements, write out the IP address to
-        // f. Otherwise, write it to a local buffer, then use f.pad.
+        // If there are no alignment requirements, write the IP address directly to `f`.
+        // Otherwise, write it to a local buffer and then use `f.pad`.
         if f.precision().is_none() && f.width().is_none() {
             let segments = self.segments();
 
@@ -1780,22 +1780,13 @@ impl fmt::Display for Ipv6Addr {
                 }
             }
         } else {
-            // Slow path: write the address to a local buffer, then use f.pad.
-            // Defined recursively by using the fast path to write to the
-            // buffer.
-
-            // This is the largest possible size of an IPv6 address
-            const IPV6_BUF_LEN: usize = (4 * 8) + 7;
-            let mut buf = [0u8; IPV6_BUF_LEN];
-            let mut buf_slice = &mut buf[..];
-
-            // Note: This call to write should never fail, so unwrap is okay.
-            write!(buf_slice, "{}", self).unwrap();
-            let len = IPV6_BUF_LEN - buf_slice.len();
-
-            // This is safe because we know exactly what can be in this buffer
-            let buf = unsafe { crate::str::from_utf8_unchecked(&buf[..len]) };
-            f.pad(buf)
+            const LONGEST_IPV6_ADDR: &str = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
+
+            let mut buf = IpDisplayBuffer::<{ LONGEST_IPV6_ADDR.len() }>::new();
+            // Buffer is long enough for the longest possible IPv6 address, so this should never fail.
+            write!(buf, "{}", self).unwrap();
+
+            f.pad(buf.as_str())
         }
     }
 }
diff --git a/library/std/src/net/ip/display_buffer.rs b/library/std/src/net/ip/display_buffer.rs
new file mode 100644
index 00000000000..bd852d5da8e
--- /dev/null
+++ b/library/std/src/net/ip/display_buffer.rs
@@ -0,0 +1,40 @@
+use crate::fmt;
+use crate::mem::MaybeUninit;
+use crate::str;
+
+/// Used for slow path in `Display` implementations when alignment is required.
+pub struct IpDisplayBuffer<const SIZE: usize> {
+    buf: [MaybeUninit<u8>; SIZE],
+    len: usize,
+}
+
+impl<const SIZE: usize> IpDisplayBuffer<SIZE> {
+    #[inline]
+    pub const fn new() -> Self {
+        Self { buf: MaybeUninit::uninit_array(), len: 0 }
+    }
+
+    #[inline]
+    pub fn as_str(&self) -> &str {
+        // SAFETY: `buf` is only written to by the `fmt::Write::write_str` implementation
+        // which writes a valid UTF-8 string to `buf` and correctly sets `len`.
+        unsafe {
+            let s = MaybeUninit::slice_assume_init_ref(&self.buf[..self.len]);
+            str::from_utf8_unchecked(s)
+        }
+    }
+}
+
+impl<const SIZE: usize> fmt::Write for IpDisplayBuffer<SIZE> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        let bytes = s.as_bytes();
+
+        if let Some(buf) = self.buf.get_mut(self.len..(self.len + bytes.len())) {
+            MaybeUninit::write_slice(buf, bytes);
+            self.len += bytes.len();
+            Ok(())
+        } else {
+            Err(fmt::Error)
+        }
+    }
+}
diff --git a/library/std/src/os/fortanix_sgx/mod.rs b/library/std/src/os/fortanix_sgx/mod.rs
index a40dabe190a..da100b689db 100644
--- a/library/std/src/os/fortanix_sgx/mod.rs
+++ b/library/std/src/os/fortanix_sgx/mod.rs
@@ -26,6 +26,7 @@ pub mod usercalls {
             free, insecure_time, launch_thread, read, read_alloc, send, wait, write,
         };
         pub use crate::sys::abi::usercalls::raw::{do_usercall, Usercalls as UsercallNrs};
+        pub use crate::sys::abi::usercalls::raw::{Register, RegisterArgument, ReturnValue};
 
         // fortanix-sgx-abi re-exports
         pub use crate::sys::abi::usercalls::raw::Error;
diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs
index 7c0d539504d..3b2601e755a 100644
--- a/library/std/src/os/unix/net/listener.rs
+++ b/library/std/src/os/unix/net/listener.rs
@@ -73,9 +73,13 @@ impl UnixListener {
         unsafe {
             let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
             let (addr, len) = sockaddr_un(path.as_ref())?;
+            #[cfg(target_os = "linux")]
+            const backlog: libc::c_int = -1;
+            #[cfg(not(target_os = "linux"))]
+            const backlog: libc::c_int = 128;
 
             cvt(libc::bind(inner.as_inner().as_raw_fd(), &addr as *const _ as *const _, len as _))?;
-            cvt(libc::listen(inner.as_inner().as_raw_fd(), 128))?;
+            cvt(libc::listen(inner.as_inner().as_raw_fd(), backlog))?;
 
             Ok(UnixListener(inner))
         }
@@ -109,12 +113,16 @@ impl UnixListener {
     pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixListener> {
         unsafe {
             let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+            #[cfg(target_os = "linux")]
+            const backlog: libc::c_int = -1;
+            #[cfg(not(target_os = "linux"))]
+            const backlog: libc::c_int = 128;
             cvt(libc::bind(
                 inner.as_raw_fd(),
                 &socket_addr.addr as *const _ as *const _,
                 socket_addr.len as _,
             ))?;
-            cvt(libc::listen(inner.as_raw_fd(), 128))?;
+            cvt(libc::listen(inner.as_raw_fd(), backlog))?;
             Ok(UnixListener(inner))
         }
     }
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
index 351cf698810..dd307022c6d 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/src/path/tests.rs
@@ -1768,6 +1768,7 @@ fn test_windows_absolute() {
 }
 
 #[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
 fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
     let prefix = "my/home";
     let mut paths: Vec<_> =
@@ -1781,6 +1782,7 @@ fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
 }
 
 #[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
 fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
     let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
     let paths: Vec<_> =
@@ -1799,6 +1801,7 @@ fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
 }
 
 #[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
 fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
     let prefix = "my/home";
     let paths: Vec<_> =
@@ -1817,6 +1820,7 @@ fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
 }
 
 #[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
 fn bench_path_hashset(b: &mut test::Bencher) {
     let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
     let paths: Vec<_> =
@@ -1835,6 +1839,7 @@ fn bench_path_hashset(b: &mut test::Bencher) {
 }
 
 #[bench]
+#[cfg_attr(miri, ignore)] // Miri isn't fast...
 fn bench_path_hashset_miss(b: &mut test::Bencher) {
     let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
     let paths: Vec<_> =
diff --git a/library/std/src/sync/mpsc/mpsc_queue/tests.rs b/library/std/src/sync/mpsc/mpsc_queue/tests.rs
index 9f4f31ed051..34b2a9a98ac 100644
--- a/library/std/src/sync/mpsc/mpsc_queue/tests.rs
+++ b/library/std/src/sync/mpsc/mpsc_queue/tests.rs
@@ -13,7 +13,7 @@ fn test_full() {
 #[test]
 fn test() {
     let nthreads = 8;
-    let nmsgs = 1000;
+    let nmsgs = if cfg!(miri) { 100 } else { 1000 };
     let q = Queue::new();
     match q.pop() {
         Empty => {}
diff --git a/library/std/src/sync/mpsc/spsc_queue/tests.rs b/library/std/src/sync/mpsc/spsc_queue/tests.rs
index 467ef3dbdcb..eb6d5c2cf66 100644
--- a/library/std/src/sync/mpsc/spsc_queue/tests.rs
+++ b/library/std/src/sync/mpsc/spsc_queue/tests.rs
@@ -77,12 +77,13 @@ fn stress() {
     }
 
     unsafe fn stress_bound(bound: usize) {
+        let count = if cfg!(miri) { 1000 } else { 100000 };
         let q = Arc::new(Queue::with_additions(bound, (), ()));
 
         let (tx, rx) = channel();
         let q2 = q.clone();
         let _t = thread::spawn(move || {
-            for _ in 0..100000 {
+            for _ in 0..count {
                 loop {
                     match q2.pop() {
                         Some(1) => break,
@@ -93,7 +94,7 @@ fn stress() {
             }
             tx.send(()).unwrap();
         });
-        for _ in 0..100000 {
+        for _ in 0..count {
             q.push(1);
         }
         rx.recv().unwrap();
diff --git a/library/std/src/sync/mpsc/sync_tests.rs b/library/std/src/sync/mpsc/sync_tests.rs
index e58649bab6e..63c79436974 100644
--- a/library/std/src/sync/mpsc/sync_tests.rs
+++ b/library/std/src/sync/mpsc/sync_tests.rs
@@ -113,23 +113,25 @@ fn chan_gone_concurrent() {
 
 #[test]
 fn stress() {
+    let count = if cfg!(miri) { 100 } else { 10000 };
     let (tx, rx) = sync_channel::<i32>(0);
     thread::spawn(move || {
-        for _ in 0..10000 {
+        for _ in 0..count {
             tx.send(1).unwrap();
         }
     });
-    for _ in 0..10000 {
+    for _ in 0..count {
         assert_eq!(rx.recv().unwrap(), 1);
     }
 }
 
 #[test]
 fn stress_recv_timeout_two_threads() {
+    let count = if cfg!(miri) { 100 } else { 10000 };
     let (tx, rx) = sync_channel::<i32>(0);
 
     thread::spawn(move || {
-        for _ in 0..10000 {
+        for _ in 0..count {
             tx.send(1).unwrap();
         }
     });
@@ -146,12 +148,12 @@ fn stress_recv_timeout_two_threads() {
         }
     }
 
-    assert_eq!(recv_count, 10000);
+    assert_eq!(recv_count, count);
 }
 
 #[test]
 fn stress_recv_timeout_shared() {
-    const AMT: u32 = 1000;
+    const AMT: u32 = if cfg!(miri) { 100 } else { 1000 };
     const NTHREADS: u32 = 8;
     let (tx, rx) = sync_channel::<i32>(0);
     let (dtx, drx) = sync_channel::<()>(0);
@@ -191,7 +193,7 @@ fn stress_recv_timeout_shared() {
 
 #[test]
 fn stress_shared() {
-    const AMT: u32 = 1000;
+    const AMT: u32 = if cfg!(miri) { 100 } else { 1000 };
     const NTHREADS: u32 = 8;
     let (tx, rx) = sync_channel::<i32>(0);
     let (dtx, drx) = sync_channel::<()>(0);
@@ -438,12 +440,13 @@ fn stream_send_recv_stress() {
 
 #[test]
 fn recv_a_lot() {
+    let count = if cfg!(miri) { 1000 } else { 10000 };
     // Regression test that we don't run out of stack in scheduler context
-    let (tx, rx) = sync_channel(10000);
-    for _ in 0..10000 {
+    let (tx, rx) = sync_channel(count);
+    for _ in 0..count {
         tx.send(()).unwrap();
     }
-    for _ in 0..10000 {
+    for _ in 0..count {
         rx.recv().unwrap();
     }
 }
diff --git a/library/std/src/sync/mpsc/tests.rs b/library/std/src/sync/mpsc/tests.rs
index 4deb3e59615..f6d0796f604 100644
--- a/library/std/src/sync/mpsc/tests.rs
+++ b/library/std/src/sync/mpsc/tests.rs
@@ -120,13 +120,14 @@ fn chan_gone_concurrent() {
 
 #[test]
 fn stress() {
+    let count = if cfg!(miri) { 100 } else { 10000 };
     let (tx, rx) = channel::<i32>();
     let t = thread::spawn(move || {
-        for _ in 0..10000 {
+        for _ in 0..count {
             tx.send(1).unwrap();
         }
     });
-    for _ in 0..10000 {
+    for _ in 0..count {
         assert_eq!(rx.recv().unwrap(), 1);
     }
     t.join().ok().expect("thread panicked");
@@ -134,7 +135,7 @@ fn stress() {
 
 #[test]
 fn stress_shared() {
-    const AMT: u32 = 10000;
+    const AMT: u32 = if cfg!(miri) { 100 } else { 10000 };
     const NTHREADS: u32 = 8;
     let (tx, rx) = channel::<i32>();
 
@@ -504,12 +505,13 @@ fn very_long_recv_timeout_wont_panic() {
 
 #[test]
 fn recv_a_lot() {
+    let count = if cfg!(miri) { 1000 } else { 10000 };
     // Regression test that we don't run out of stack in scheduler context
     let (tx, rx) = channel();
-    for _ in 0..10000 {
+    for _ in 0..count {
         tx.send(()).unwrap();
     }
-    for _ in 0..10000 {
+    for _ in 0..count {
         rx.recv().unwrap();
     }
 }
diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs
index 08255c985f5..b5b3ad9898e 100644
--- a/library/std/src/sync/rwlock/tests.rs
+++ b/library/std/src/sync/rwlock/tests.rs
@@ -19,7 +19,7 @@ fn smoke() {
 #[test]
 fn frob() {
     const N: u32 = 10;
-    const M: usize = 1000;
+    const M: usize = if cfg!(miri) { 100 } else { 1000 };
 
     let r = Arc::new(RwLock::new(()));
 
diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
index 66fa1efbf10..fe8392f78cd 100644
--- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs
@@ -56,6 +56,8 @@ unsafe impl UserSafeSized for Usercall {}
 #[unstable(feature = "sgx_platform", issue = "56975")]
 unsafe impl UserSafeSized for Return {}
 #[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl UserSafeSized for Cancel {}
+#[unstable(feature = "sgx_platform", issue = "56975")]
 unsafe impl<T: UserSafeSized> UserSafeSized for [T; 2] {}
 
 /// A type that can be represented in memory as one or more `UserSafeSized`s.
@@ -305,6 +307,34 @@ where
     }
 }
 
+// Split a memory region ptr..ptr + len into three parts:
+//   +--------+
+//   | small0 | Chunk smaller than 8 bytes
+//   +--------+
+//   |   big  | Chunk 8-byte aligned, and size a multiple of 8 bytes
+//   +--------+
+//   | small1 | Chunk smaller than 8 bytes
+//   +--------+
+fn region_as_aligned_chunks(ptr: *const u8, len: usize) -> (usize, usize, usize) {
+    let small0_size = if ptr as usize % 8 == 0 { 0 } else { 8 - ptr as usize % 8 };
+    let small1_size = (len - small0_size as usize) % 8;
+    let big_size = len - small0_size as usize - small1_size as usize;
+
+    (small0_size, big_size, small1_size)
+}
+
+unsafe fn copy_quadwords(src: *const u8, dst: *mut u8, len: usize) {
+    unsafe {
+        asm!(
+            "rep movsq (%rsi), (%rdi)",
+            inout("rcx") len / 8 => _,
+            inout("rdi") dst => _,
+            inout("rsi") src => _,
+            options(att_syntax, nostack, preserves_flags)
+        );
+    }
+}
+
 /// Copies `len` bytes of data from enclave pointer `src` to userspace `dst`
 ///
 /// This function mitigates stale data vulnerabilities by ensuring all writes to untrusted memory are either:
@@ -343,17 +373,6 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
         }
     }
 
-    unsafe fn copy_aligned_quadwords_to_userspace(src: *const u8, dst: *mut u8, len: usize) {
-        unsafe {
-            asm!(
-                "rep movsq (%rsi), (%rdi)",
-                inout("rcx") len / 8 => _,
-                inout("rdi") dst => _,
-                inout("rsi") src => _,
-                options(att_syntax, nostack, preserves_flags)
-            );
-        }
-    }
     assert!(!src.is_null());
     assert!(!dst.is_null());
     assert!(is_enclave_range(src, len));
@@ -370,7 +389,7 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
     } else if len % 8 == 0 && dst as usize % 8 == 0 {
         // Copying 8-byte aligned quadwords: copy quad word per quad word
         unsafe {
-            copy_aligned_quadwords_to_userspace(src, dst, len);
+            copy_quadwords(src, dst, len);
         }
     } else {
         // Split copies into three parts:
@@ -381,20 +400,16 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
         //   +--------+
         //   | small1 | Chunk smaller than 8 bytes
         //   +--------+
+        let (small0_size, big_size, small1_size) = region_as_aligned_chunks(dst, len);
 
         unsafe {
             // Copy small0
-            let small0_size = (8 - dst as usize % 8) as u8;
-            let small0_src = src;
-            let small0_dst = dst;
-            copy_bytewise_to_userspace(small0_src as _, small0_dst, small0_size as _);
+            copy_bytewise_to_userspace(src, dst, small0_size as _);
 
             // Copy big
-            let small1_size = ((len - small0_size as usize) % 8) as u8;
-            let big_size = len - small0_size as usize - small1_size as usize;
             let big_src = src.offset(small0_size as _);
             let big_dst = dst.offset(small0_size as _);
-            copy_aligned_quadwords_to_userspace(big_src as _, big_dst, big_size);
+            copy_quadwords(big_src as _, big_dst, big_size);
 
             // Copy small1
             let small1_src = src.offset(big_size as isize + small0_size as isize);
@@ -404,6 +419,106 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize)
     }
 }
 
+/// Copies `len` bytes of data from userspace pointer `src` to enclave pointer `dst`
+///
+/// This function mitigates AEPIC leak vulnerabilities by ensuring all reads from untrusted memory are 8-byte aligned
+///
+/// # Panics
+/// This function panics if:
+///
+/// * The `src` pointer is null
+/// * The `dst` pointer is null
+/// * The `src` memory range is not in user memory
+/// * The `dst` memory range is not in enclave memory
+///
+/// # References
+///  - https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00657.html
+///  - https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/stale-data-read-from-xapic.html
+pub(crate) unsafe fn copy_from_userspace(src: *const u8, dst: *mut u8, len: usize) {
+    // Copies memory region `src..src + len` to the enclave at `dst`. The source memory region
+    // is:
+    //  - strictly less than 8 bytes in size and may be
+    //  - located at a misaligned memory location
+    fn copy_misaligned_chunk_to_enclave(src: *const u8, dst: *mut u8, len: usize) {
+        let mut tmp_buff = [0u8; 16];
+
+        unsafe {
+            // Compute an aligned memory region to read from
+            // +--------+ <-- aligned_src + aligned_len (8B-aligned)
+            // |  pad1  |
+            // +--------+ <-- src + len (misaligned)
+            // |        |
+            // |        |
+            // |        |
+            // +--------+ <-- src (misaligned)
+            // |  pad0  |
+            // +--------+ <-- aligned_src (8B-aligned)
+            let pad0_size = src as usize % 8;
+            let aligned_src = src.sub(pad0_size);
+
+            let pad1_size = 8 - (src.add(len) as usize % 8);
+            let aligned_len = pad0_size + len + pad1_size;
+
+            debug_assert!(len < 8);
+            debug_assert_eq!(aligned_src as usize % 8, 0);
+            debug_assert_eq!(aligned_len % 8, 0);
+            debug_assert!(aligned_len <= 16);
+
+            // Copy the aligned buffer to a temporary buffer
+            // Note: copying from a slightly different memory location is a bit odd. In this case it
+            // can't lead to page faults or inadvertent copying from the enclave as we only ensured
+            // that the `src` pointer is aligned at an 8 byte boundary. As pages are 4096 bytes
+            // aligned, `aligned_src` must be on the same page as `src`. A similar argument can be made
+            // for `src + len`
+            copy_quadwords(aligned_src as _, tmp_buff.as_mut_ptr(), aligned_len);
+
+            // Copy the correct parts of the temporary buffer to the destination
+            ptr::copy(tmp_buff.as_ptr().add(pad0_size), dst, len);
+        }
+    }
+
+    assert!(!src.is_null());
+    assert!(!dst.is_null());
+    assert!(is_user_range(src, len));
+    assert!(is_enclave_range(dst, len));
+    assert!(!(src as usize).overflowing_add(len + 8).1);
+    assert!(!(dst as usize).overflowing_add(len + 8).1);
+
+    if len < 8 {
+        copy_misaligned_chunk_to_enclave(src, dst, len);
+    } else if len % 8 == 0 && src as usize % 8 == 0 {
+        // Copying 8-byte aligned quadwords: copy quad word per quad word
+        unsafe {
+            copy_quadwords(src, dst, len);
+        }
+    } else {
+        // Split copies into three parts:
+        //   +--------+
+        //   | small0 | Chunk smaller than 8 bytes
+        //   +--------+
+        //   |   big  | Chunk 8-byte aligned, and size a multiple of 8 bytes
+        //   +--------+
+        //   | small1 | Chunk smaller than 8 bytes
+        //   +--------+
+        let (small0_size, big_size, small1_size) = region_as_aligned_chunks(dst, len);
+
+        unsafe {
+            // Copy small0
+            copy_misaligned_chunk_to_enclave(src, dst, small0_size);
+
+            // Copy big
+            let big_src = src.add(small0_size);
+            let big_dst = dst.add(small0_size);
+            copy_quadwords(big_src, big_dst, big_size);
+
+            // Copy small1
+            let small1_src = src.add(big_size + small0_size);
+            let small1_dst = dst.add(big_size + small0_size);
+            copy_misaligned_chunk_to_enclave(small1_src, small1_dst, small1_size);
+        }
+    }
+}
+
 #[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T: ?Sized> UserRef<T>
 where
@@ -468,7 +583,7 @@ where
     pub fn copy_to_enclave(&self, dest: &mut T) {
         unsafe {
             assert_eq!(mem::size_of_val(dest), mem::size_of_val(&*self.0.get()));
-            ptr::copy(
+            copy_from_userspace(
                 self.0.get() as *const T as *const u8,
                 dest as *mut T as *mut u8,
                 mem::size_of_val(dest),
@@ -494,7 +609,11 @@ where
 {
     /// Copies the value from user memory into enclave memory.
     pub fn to_enclave(&self) -> T {
-        unsafe { ptr::read(self.0.get()) }
+        unsafe {
+            let mut data: T = mem::MaybeUninit::uninit().assume_init();
+            copy_from_userspace(self.0.get() as _, &mut data as *mut T as _, mem::size_of::<T>());
+            data
+        }
     }
 }
 
diff --git a/library/std/src/sys/sgx/abi/usercalls/mod.rs b/library/std/src/sys/sgx/abi/usercalls/mod.rs
index 79d1db5e1c5..e19e843267a 100644
--- a/library/std/src/sys/sgx/abi/usercalls/mod.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/mod.rs
@@ -292,12 +292,17 @@ fn check_os_error(err: Result) -> i32 {
     }
 }
 
-trait FromSgxResult {
+/// Translate the raw result of an SGX usercall.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait FromSgxResult {
+    /// Return type
     type Return;
 
+    /// Translate the raw result of an SGX usercall.
     fn from_sgx_result(self) -> IoResult<Self::Return>;
 }
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T> FromSgxResult for (Result, T) {
     type Return = T;
 
@@ -310,6 +315,7 @@ impl<T> FromSgxResult for (Result, T) {
     }
 }
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl FromSgxResult for Result {
     type Return = ();
 
diff --git a/library/std/src/sys/sgx/abi/usercalls/raw.rs b/library/std/src/sys/sgx/abi/usercalls/raw.rs
index 4267b96ccd5..10c1456d4fd 100644
--- a/library/std/src/sys/sgx/abi/usercalls/raw.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/raw.rs
@@ -37,14 +37,23 @@ pub unsafe fn do_usercall(
     (a, b)
 }
 
-type Register = u64;
+/// A value passed or returned in a CPU register.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub type Register = u64;
 
-trait RegisterArgument {
+/// Translate a type from/to Register to be used as an argument.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait RegisterArgument {
+    /// Translate a Register to Self.
     fn from_register(_: Register) -> Self;
+    /// Translate self to a Register.
     fn into_register(self) -> Register;
 }
 
-trait ReturnValue {
+/// Translate a pair of Registers to the raw usercall return value.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub trait ReturnValue {
+    /// Translate a pair of Registers to the raw usercall return value.
     fn from_registers(call: &'static str, regs: (Register, Register)) -> Self;
 }
 
@@ -68,6 +77,7 @@ macro_rules! define_usercalls {
 
 macro_rules! define_ra {
     (< $i:ident > $t:ty) => {
+        #[unstable(feature = "sgx_platform", issue = "56975")]
         impl<$i> RegisterArgument for $t {
             fn from_register(a: Register) -> Self {
                 a as _
@@ -78,6 +88,7 @@ macro_rules! define_ra {
         }
     };
     ($i:ty as $t:ty) => {
+        #[unstable(feature = "sgx_platform", issue = "56975")]
         impl RegisterArgument for $t {
             fn from_register(a: Register) -> Self {
                 a as $i as _
@@ -88,6 +99,7 @@ macro_rules! define_ra {
         }
     };
     ($t:ty) => {
+        #[unstable(feature = "sgx_platform", issue = "56975")]
         impl RegisterArgument for $t {
             fn from_register(a: Register) -> Self {
                 a as _
@@ -112,6 +124,7 @@ define_ra!(usize as isize);
 define_ra!(<T> *const T);
 define_ra!(<T> *mut T);
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl RegisterArgument for bool {
     fn from_register(a: Register) -> bool {
         if a != 0 { true } else { false }
@@ -121,6 +134,7 @@ impl RegisterArgument for bool {
     }
 }
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T: RegisterArgument> RegisterArgument for Option<NonNull<T>> {
     fn from_register(a: Register) -> Option<NonNull<T>> {
         NonNull::new(a as _)
@@ -130,12 +144,14 @@ impl<T: RegisterArgument> RegisterArgument for Option<NonNull<T>> {
     }
 }
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl ReturnValue for ! {
     fn from_registers(call: &'static str, _regs: (Register, Register)) -> Self {
         rtabort!("Usercall {call}: did not expect to be re-entered");
     }
 }
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl ReturnValue for () {
     fn from_registers(call: &'static str, usercall_retval: (Register, Register)) -> Self {
         rtassert!(usercall_retval.0 == 0);
@@ -144,6 +160,7 @@ impl ReturnValue for () {
     }
 }
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T: RegisterArgument> ReturnValue for T {
     fn from_registers(call: &'static str, usercall_retval: (Register, Register)) -> Self {
         rtassert!(usercall_retval.1 == 0);
@@ -151,6 +168,7 @@ impl<T: RegisterArgument> ReturnValue for T {
     }
 }
 
+#[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) {
     fn from_registers(_call: &'static str, regs: (Register, Register)) -> Self {
         (T::from_register(regs.0), U::from_register(regs.1))
diff --git a/library/std/src/sys/sgx/abi/usercalls/tests.rs b/library/std/src/sys/sgx/abi/usercalls/tests.rs
index cbf7d7d54f7..4320f0bccd1 100644
--- a/library/std/src/sys/sgx/abi/usercalls/tests.rs
+++ b/library/std/src/sys/sgx/abi/usercalls/tests.rs
@@ -1,8 +1,8 @@
-use super::alloc::copy_to_userspace;
 use super::alloc::User;
+use super::alloc::{copy_from_userspace, copy_to_userspace};
 
 #[test]
-fn test_copy_function() {
+fn test_copy_to_userspace_function() {
     let mut src = [0u8; 100];
     let mut dst = User::<[u8]>::uninitialized(100);
 
@@ -28,3 +28,29 @@ fn test_copy_function() {
         }
     }
 }
+
+#[test]
+fn test_copy_from_userspace_function() {
+    let mut dst = [0u8; 100];
+    let mut src = User::<[u8]>::uninitialized(100);
+
+    src.copy_from_enclave(&[0u8; 100]);
+
+    for size in 0..48 {
+        // For all possible alignment
+        for offset in 0..8 {
+            // overwrite complete dst
+            dst = [0u8; 100];
+
+            // Copy src[0..size] to dst + offset
+            unsafe { copy_from_userspace(src.as_ptr().offset(offset), dst.as_mut_ptr(), size) };
+
+            // Verify copy
+            for byte in 0..size {
+                unsafe {
+                    assert_eq!(dst[byte as usize], *src.as_ptr().offset(offset + byte as isize));
+                }
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 7778033eaa9..f38d2fd3d70 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -829,6 +829,7 @@ impl DirEntry {
         target_os = "fuchsia",
         target_os = "redox"
     )))]
+    #[cfg_attr(miri, allow(unused))]
     fn name_cstr(&self) -> &CStr {
         unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }
     }
@@ -840,6 +841,7 @@ impl DirEntry {
         target_os = "fuchsia",
         target_os = "redox"
     ))]
+    #[cfg_attr(miri, allow(unused))]
     fn name_cstr(&self) -> &CStr {
         &self.name
     }
diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs
index ccbc182240c..017e2af29d4 100644
--- a/library/std/src/sys/unix/os_str.rs
+++ b/library/std/src/sys/unix/os_str.rs
@@ -11,7 +11,7 @@ use crate::str;
 use crate::sync::Arc;
 use crate::sys_common::{AsInner, IntoInner};
 
-use core::str::lossy::{Utf8Lossy, Utf8LossyChunk};
+use core::str::Utf8Chunks;
 
 #[cfg(test)]
 #[path = "../unix/os_str/tests.rs"]
@@ -29,26 +29,32 @@ pub struct Slice {
 }
 
 impl fmt::Debug for Slice {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // Writes out a valid unicode string with the correct escape sequences
-
-        formatter.write_str("\"")?;
-        for Utf8LossyChunk { valid, broken } in Utf8Lossy::from_bytes(&self.inner).chunks() {
-            for c in valid.chars().flat_map(|c| c.escape_debug()) {
-                formatter.write_char(c)?
-            }
-
-            for b in broken {
-                write!(formatter, "\\x{:02X}", b)?;
-            }
-        }
-        formatter.write_str("\"")
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(&Utf8Chunks::new(&self.inner).debug(), f)
     }
 }
 
 impl fmt::Display for Slice {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // If we're the empty string then our iterator won't actually yield
+        // anything, so perform the formatting manually
+        if self.inner.is_empty() {
+            return "".fmt(f);
+        }
+
+        for chunk in Utf8Chunks::new(&self.inner) {
+            let valid = chunk.valid();
+            // If we successfully decoded the whole chunk as a valid string then
+            // we can return a direct formatting of the string which will also
+            // respect various formatting flags if possible.
+            if chunk.invalid().is_empty() {
+                return valid.fmt(f);
+            }
+
+            f.write_str(valid)?;
+            f.write_char(char::REPLACEMENT_CHARACTER)?;
+        }
+        Ok(())
     }
 }
 
diff --git a/library/std/src/sys/unix/os_str/tests.rs b/library/std/src/sys/unix/os_str/tests.rs
index 213277f01f2..22ba0c92350 100644
--- a/library/std/src/sys/unix/os_str/tests.rs
+++ b/library/std/src/sys/unix/os_str/tests.rs
@@ -8,3 +8,11 @@ fn slice_debug_output() {
 
     assert_eq!(output, expected);
 }
+
+#[test]
+fn display() {
+    assert_eq!(
+        "Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye",
+        Slice::from_u8_slice(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string(),
+    );
+}
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index c5a30f8bac8..ef3f6a9ba17 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -228,6 +228,8 @@ pub const IPV6_ADD_MEMBERSHIP: c_int = 12;
 pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
 pub const MSG_PEEK: c_int = 0x2;
 
+pub const LOAD_LIBRARY_SEARCH_SYSTEM32: u32 = 0x800;
+
 #[repr(C)]
 #[derive(Copy, Clone)]
 pub struct linger {
@@ -1030,6 +1032,7 @@ extern "system" {
     pub fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void;
     pub fn GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE;
     pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
+    pub fn LoadLibraryExA(lplibfilename: *const i8, hfile: HANDLE, dwflags: u32) -> HINSTANCE;
 
     pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
     pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO);
@@ -1250,21 +1253,16 @@ compat_fn_with_fallback! {
     }
 }
 
-compat_fn_with_fallback! {
-    pub static SYNCH_API: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
-    #[allow(unused)]
-    fn WakeByAddressSingle(Address: LPVOID) -> () {
-        // This fallback is currently tightly coupled to its use in Parker::unpark.
-        //
-        // FIXME: If `WakeByAddressSingle` needs to be used anywhere other than
-        // Parker::unpark then this fallback will be wrong and will need to be decoupled.
-        crate::sys::windows::thread_parker::unpark_keyed_event(Address)
-    }
+compat_fn_optional! {
+    crate::sys::compat::load_synch_functions();
+    pub fn WaitOnAddress(
+        Address: LPVOID,
+        CompareAddress: LPVOID,
+        AddressSize: SIZE_T,
+        dwMilliseconds: DWORD
+    );
+    pub fn WakeByAddressSingle(Address: LPVOID);
 }
-pub use crate::sys::compat::WaitOnAddress;
-// Change exported name of `WakeByAddressSingle` to make the strange fallback
-// behaviour clear.
-pub use WakeByAddressSingle::call as wake_by_address_single_or_unpark_keyed_event;
 
 compat_fn_with_fallback! {
     pub static NTDLL: &CStr = ansi_str!("ntdll");
diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs
index 473544c4d4f..9c8ddc3aa1d 100644
--- a/library/std/src/sys/windows/compat.rs
+++ b/library/std/src/sys/windows/compat.rs
@@ -21,6 +21,7 @@
 
 use crate::ffi::{c_void, CStr};
 use crate::ptr::NonNull;
+use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::c;
 
 /// Helper macro for creating CStrs from literals and symbol names.
@@ -74,6 +75,20 @@ impl Module {
         NonNull::new(module).map(Self)
     }
 
+    /// Load the library (if not already loaded)
+    ///
+    /// # Safety
+    ///
+    /// The module must not be unloaded.
+    pub unsafe fn load_system_library(name: &CStr) -> Option<Self> {
+        let module = c::LoadLibraryExA(
+            name.as_ptr(),
+            crate::ptr::null_mut(),
+            c::LOAD_LIBRARY_SEARCH_SYSTEM32,
+        );
+        NonNull::new(module).map(Self)
+    }
+
     // Try to get the address of a function.
     pub fn proc_address(self, name: &CStr) -> Option<NonNull<c_void>> {
         // SAFETY:
@@ -144,61 +159,63 @@ macro_rules! compat_fn_with_fallback {
     )*)
 }
 
-/// Optionally load `WaitOnAddress`.
-/// Unlike the dynamic loading described above, this does not have a fallback.
+/// Optionally loaded functions.
 ///
-/// This is rexported from sys::c. You should prefer to import
-/// from there in case this changes again in the future.
-pub mod WaitOnAddress {
-    use super::*;
-    use crate::mem;
-    use crate::ptr;
-    use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
-    use crate::sys::c;
-
-    static MODULE_NAME: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
-    static SYMBOL_NAME: &CStr = ansi_str!("WaitOnAddress");
-
-    // WaitOnAddress function signature.
-    type F = unsafe extern "system" fn(
-        Address: c::LPVOID,
-        CompareAddress: c::LPVOID,
-        AddressSize: c::SIZE_T,
-        dwMilliseconds: c::DWORD,
-    );
-
-    // A place to store the loaded function atomically.
-    static WAIT_ON_ADDRESS: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
-
-    // We can skip trying to load again if we already tried.
-    static LOAD_MODULE: AtomicBool = AtomicBool::new(true);
-
-    #[inline(always)]
-    pub fn option() -> Option<F> {
-        let f = WAIT_ON_ADDRESS.load(Ordering::Acquire);
-        if !f.is_null() { Some(unsafe { mem::transmute(f) }) } else { try_load() }
-    }
+/// Actual loading of the function defers to $load_functions.
+macro_rules! compat_fn_optional {
+    ($load_functions:expr;
+    $(
+        $(#[$meta:meta])*
+        $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) $(-> $rettype:ty)?;
+    )+) => (
+        $(
+            pub mod $symbol {
+                use super::*;
+                use crate::ffi::c_void;
+                use crate::mem;
+                use crate::ptr::{self, NonNull};
+                use crate::sync::atomic::{AtomicPtr, Ordering};
+
+                pub(in crate::sys) static PTR: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
+
+                type F = unsafe extern "system" fn($($argtype),*) $(-> $rettype)?;
+
+                #[inline(always)]
+                pub fn option() -> Option<F> {
+                    let f = PTR.load(Ordering::Acquire);
+                    if !f.is_null() { Some(unsafe { mem::transmute(f) }) } else { try_load() }
+                }
 
-    #[cold]
-    fn try_load() -> Option<F> {
-        if LOAD_MODULE.load(Ordering::Acquire) {
-            // load the module
-            let mut wait_on_address = None;
-            if let Some(func) = try_load_inner() {
-                WAIT_ON_ADDRESS.store(func.as_ptr(), Ordering::Release);
-                wait_on_address = Some(unsafe { mem::transmute(func) });
+                #[cold]
+                fn try_load() -> Option<F> {
+                    $load_functions;
+                    NonNull::new(PTR.load(Ordering::Acquire)).map(|f| unsafe { mem::transmute(f) })
+                }
             }
-            // Don't try to load the module again even if loading failed.
-            LOAD_MODULE.store(false, Ordering::Release);
-            wait_on_address
-        } else {
-            None
-        }
-    }
+        )+
+    )
+}
 
-    // In the future this could be a `try` block but until then I think it's a
-    // little bit cleaner as a separate function.
-    fn try_load_inner() -> Option<NonNull<c_void>> {
-        unsafe { Module::new(MODULE_NAME)?.proc_address(SYMBOL_NAME) }
+/// Load all needed functions from "api-ms-win-core-synch-l1-2-0".
+pub(super) fn load_synch_functions() {
+    fn try_load() -> Option<()> {
+        const MODULE_NAME: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
+        const WAIT_ON_ADDRESS: &CStr = ansi_str!("WaitOnAddress");
+        const WAKE_BY_ADDRESS_SINGLE: &CStr = ansi_str!("WakeByAddressSingle");
+
+        // Try loading the library and all the required functions.
+        // If any step fails, then they all fail.
+        let library = unsafe { Module::load_system_library(MODULE_NAME) }?;
+        let wait_on_address = library.proc_address(WAIT_ON_ADDRESS)?;
+        let wake_by_address_single = library.proc_address(WAKE_BY_ADDRESS_SINGLE)?;
+
+        c::WaitOnAddress::PTR.store(wait_on_address.as_ptr(), Ordering::Release);
+        c::WakeByAddressSingle::PTR.store(wake_by_address_single.as_ptr(), Ordering::Release);
+        Some(())
     }
+
+    // Try to load the module but skip loading if a previous attempt failed.
+    static LOAD_MODULE: AtomicBool = AtomicBool::new(true);
+    let module_loaded = LOAD_MODULE.load(Ordering::Acquire) && try_load().is_some();
+    LOAD_MODULE.store(module_loaded, Ordering::Release)
 }
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index b3f6d2d0aae..a9846a48488 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -2,6 +2,7 @@
 
 use crate::ffi::{CStr, OsStr, OsString};
 use crate::io::ErrorKind;
+use crate::mem::MaybeUninit;
 use crate::os::windows::ffi::{OsStrExt, OsStringExt};
 use crate::path::PathBuf;
 use crate::time::Duration;
@@ -204,8 +205,8 @@ where
     // This initial size also works around `GetFullPathNameW` returning
     // incorrect size hints for some short paths:
     // https://github.com/dylni/normpath/issues/5
-    let mut stack_buf = [0u16; 512];
-    let mut heap_buf = Vec::new();
+    let mut stack_buf: [MaybeUninit<u16>; 512] = MaybeUninit::uninit_array();
+    let mut heap_buf: Vec<MaybeUninit<u16>> = Vec::new();
     unsafe {
         let mut n = stack_buf.len();
         loop {
@@ -214,6 +215,11 @@ where
             } else {
                 let extra = n - heap_buf.len();
                 heap_buf.reserve(extra);
+                // We used `reserve` and not `reserve_exact`, so in theory we
+                // may have gotten more than requested. If so, we'd like to use
+                // it... so long as we won't cause overflow.
+                n = heap_buf.capacity().min(c::DWORD::MAX as usize);
+                // Safety: MaybeUninit<u16> does not need initialization
                 heap_buf.set_len(n);
                 &mut heap_buf[..]
             };
@@ -228,13 +234,13 @@ where
             // error" is still 0 then we interpret it as a 0 length buffer and
             // not an actual error.
             c::SetLastError(0);
-            let k = match f1(buf.as_mut_ptr(), n as c::DWORD) {
+            let k = match f1(buf.as_mut_ptr().cast::<u16>(), n as c::DWORD) {
                 0 if c::GetLastError() == 0 => 0,
                 0 => return Err(crate::io::Error::last_os_error()),
                 n => n,
             } as usize;
             if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
-                n *= 2;
+                n = n.saturating_mul(2).min(c::DWORD::MAX as usize);
             } else if k > n {
                 n = k;
             } else if k == n {
@@ -244,7 +250,9 @@ where
                 // Therefore k never equals n.
                 unreachable!();
             } else {
-                return Ok(f2(&buf[..k]));
+                // Safety: First `k` values are initialized.
+                let slice: &[u16] = MaybeUninit::slice_assume_init_ref(&buf[..k]);
+                return Ok(f2(slice));
             }
         }
     }
diff --git a/library/std/src/sys/windows/thread_parker.rs b/library/std/src/sys/windows/thread_parker.rs
index 16863c9903a..2f7ae863b6a 100644
--- a/library/std/src/sys/windows/thread_parker.rs
+++ b/library/std/src/sys/windows/thread_parker.rs
@@ -198,8 +198,18 @@ impl Parker {
         // with park().
         if self.state.swap(NOTIFIED, Release) == PARKED {
             unsafe {
-                // This calls either WakeByAddressSingle or unpark_keyed_event (see below).
-                c::wake_by_address_single_or_unpark_keyed_event(self.ptr());
+                if let Some(wake_by_address_single) = c::WakeByAddressSingle::option() {
+                    wake_by_address_single(self.ptr());
+                } else {
+                    // If we run NtReleaseKeyedEvent before the waiting thread runs
+                    // NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
+                    // If the waiting thread wakes up before we run NtReleaseKeyedEvent
+                    // (e.g. due to a timeout), this blocks until we do wake up a thread.
+                    // To prevent this thread from blocking indefinitely in that case,
+                    // park_impl() will, after seeing the state set to NOTIFIED after
+                    // waking up, call NtWaitForKeyedEvent again to unblock us.
+                    c::NtReleaseKeyedEvent(keyed_event_handle(), self.ptr(), 0, ptr::null_mut());
+                }
             }
         }
     }
@@ -209,19 +219,6 @@ impl Parker {
     }
 }
 
-// This function signature makes it compatible with c::WakeByAddressSingle
-// so that it can be used as a fallback for that function.
-pub unsafe extern "C" fn unpark_keyed_event(address: c::LPVOID) {
-    // If we run NtReleaseKeyedEvent before the waiting thread runs
-    // NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
-    // If the waiting thread wakes up before we run NtReleaseKeyedEvent
-    // (e.g. due to a timeout), this blocks until we do wake up a thread.
-    // To prevent this thread from blocking indefinitely in that case,
-    // park_impl() will, after seeing the state set to NOTIFIED after
-    // waking up, call NtWaitForKeyedEvent again to unblock us.
-    c::NtReleaseKeyedEvent(keyed_event_handle(), address, 0, ptr::null_mut());
-}
-
 fn keyed_event_handle() -> c::HANDLE {
     const INVALID: c::HANDLE = ptr::invalid_mut(!0);
     static HANDLE: AtomicPtr<libc::c_void> = AtomicPtr::new(INVALID);
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index ec68b529188..130e47c8d44 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -329,3 +329,22 @@ fn test_scoped_threads_nll() {
     let x = 42_u8;
     foo(&x);
 }
+
+// Regression test for https://github.com/rust-lang/rust/issues/98498.
+#[test]
+#[cfg(miri)] // relies on Miri's data race detector
+fn scope_join_race() {
+    for _ in 0..100 {
+        let a_bool = AtomicBool::new(false);
+
+        thread::scope(|s| {
+            for _ in 0..5 {
+                s.spawn(|| a_bool.load(Ordering::Relaxed));
+            }
+
+            for _ in 0..5 {
+                s.spawn(|| a_bool.load(Ordering::Relaxed));
+            }
+        });
+    }
+}
diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs
index d710a574465..6229556c85f 100644
--- a/library/std/src/time/tests.rs
+++ b/library/std/src/time/tests.rs
@@ -31,7 +31,8 @@ fn instant_monotonic_concurrent() -> crate::thread::Result<()> {
         .map(|_| {
             crate::thread::spawn(|| {
                 let mut old = Instant::now();
-                for _ in 0..5_000_000 {
+                let count = if cfg!(miri) { 1_000 } else { 5_000_000 };
+                for _ in 0..count {
                     let new = Instant::now();
                     assert!(new >= old);
                     old = new;
diff --git a/library/unwind/build.rs b/library/unwind/build.rs
index 126e41d1e20..31af390253b 100644
--- a/library/unwind/build.rs
+++ b/library/unwind/build.rs
@@ -2,8 +2,14 @@ use std::env;
 
 fn main() {
     println!("cargo:rerun-if-changed=build.rs");
-    let target = env::var("TARGET").expect("TARGET was not set");
+    println!("cargo:rerun-if-env-changed=CARGO_CFG_MIRI");
+
+    if env::var_os("CARGO_CFG_MIRI").is_some() {
+        // Miri doesn't need the linker flags or a libunwind build.
+        return;
+    }
 
+    let target = env::var("TARGET").expect("TARGET was not set");
     if target.contains("android") {
         let build = cc::Build::new();
 
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 40a3cc6d12c..bd5790d2ea8 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -25,10 +25,11 @@ use std::time::Instant;
 
 fn main() {
     let args = env::args_os().skip(1).collect::<Vec<_>>();
+    let arg = |name| args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str());
 
     // Detect whether or not we're a build script depending on whether --target
     // is passed (a bit janky...)
-    let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str());
+    let target = arg("--target");
     let version = args.iter().find(|w| &**w == "-vV");
 
     let verbose = match env::var("RUSTC_VERBOSE") {
@@ -59,8 +60,7 @@ fn main() {
     cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
 
     // Get the name of the crate we're compiling, if any.
-    let crate_name =
-        args.windows(2).find(|args| args[0] == "--crate-name").and_then(|args| args[1].to_str());
+    let crate_name = arg("--crate-name");
 
     if let Some(crate_name) = crate_name {
         if let Some(target) = env::var_os("RUSTC_TIME") {
@@ -106,6 +106,15 @@ fn main() {
         {
             cmd.arg("-C").arg("panic=abort");
         }
+
+        // `-Ztls-model=initial-exec` must not be applied to proc-macros, see
+        // issue https://github.com/rust-lang/rust/issues/100530
+        if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok()
+            && arg("--crate-type") != Some("proc-macro")
+            && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure"))
+        {
+            cmd.arg("-Ztls-model=initial-exec");
+        }
     } else {
         // FIXME(rust-lang/cargo#5754) we shouldn't be using special env vars
         // here, but rather Cargo should know what flags to pass rustc itself.
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 0ab4824ac0a..945299d2dcd 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1850,7 +1850,7 @@ impl<'a> Builder<'a> {
         // so we can't use it by default in general, but we can use it for tools
         // and our own internal libraries.
         if !mode.must_support_dlopen() && !target.triple.starts_with("powerpc-") {
-            rustflags.arg("-Ztls-model=initial-exec");
+            cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1");
         }
 
         if self.config.incremental {
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 203db2d3876..13e3049f2c8 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -990,42 +990,7 @@ impl Config {
             config.llvm_from_ci = match llvm.download_ci_llvm {
                 Some(StringOrBool::String(s)) => {
                     assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s);
-                    // This is currently all tier 1 targets and tier 2 targets with host tools
-                    // (since others may not have CI artifacts)
-                    // https://doc.rust-lang.org/rustc/platform-support.html#tier-1
-                    // FIXME: this is duplicated in bootstrap.py
-                    let supported_platforms = [
-                        // tier 1
-                        "aarch64-unknown-linux-gnu",
-                        "i686-pc-windows-gnu",
-                        "i686-pc-windows-msvc",
-                        "i686-unknown-linux-gnu",
-                        "x86_64-unknown-linux-gnu",
-                        "x86_64-apple-darwin",
-                        "x86_64-pc-windows-gnu",
-                        "x86_64-pc-windows-msvc",
-                        // tier 2 with host tools
-                        "aarch64-apple-darwin",
-                        "aarch64-pc-windows-msvc",
-                        "aarch64-unknown-linux-musl",
-                        "arm-unknown-linux-gnueabi",
-                        "arm-unknown-linux-gnueabihf",
-                        "armv7-unknown-linux-gnueabihf",
-                        "mips-unknown-linux-gnu",
-                        "mips64-unknown-linux-gnuabi64",
-                        "mips64el-unknown-linux-gnuabi64",
-                        "mipsel-unknown-linux-gnu",
-                        "powerpc-unknown-linux-gnu",
-                        "powerpc64-unknown-linux-gnu",
-                        "powerpc64le-unknown-linux-gnu",
-                        "riscv64gc-unknown-linux-gnu",
-                        "s390x-unknown-linux-gnu",
-                        "x86_64-unknown-freebsd",
-                        "x86_64-unknown-illumos",
-                        "x86_64-unknown-linux-musl",
-                        "x86_64-unknown-netbsd",
-                    ];
-                    supported_platforms.contains(&&*config.build.triple)
+                    crate::native::is_ci_llvm_available(&config, llvm_assertions.unwrap_or(false))
                 }
                 Some(StringOrBool::Bool(b)) => b,
                 None => false,
@@ -1176,6 +1141,7 @@ impl Config {
 
         if config.llvm_from_ci {
             let triple = &config.build.triple;
+            let ci_llvm_bin = config.ci_llvm_root().join("bin");
             let mut build_target = config
                 .target_config
                 .entry(config.build)
@@ -1183,7 +1149,6 @@ impl Config {
 
             check_ci_llvm!(build_target.llvm_config);
             check_ci_llvm!(build_target.llvm_filecheck);
-            let ci_llvm_bin = config.out.join(&*config.build.triple).join("ci-llvm/bin");
             build_target.llvm_config = Some(ci_llvm_bin.join(exe("llvm-config", config.build)));
             build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", config.build)));
         }
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 1bba5e68be4..7ecf74d3068 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -114,23 +114,20 @@ pub fn prebuilt_llvm_config(
     Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() })
 }
 
-pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
-    let config = &builder.config;
-    if !config.llvm_from_ci {
-        return;
-    }
+/// This retrieves the LLVM sha we *want* to use, according to git history.
+pub(crate) fn detect_llvm_sha(config: &crate::config::Config) -> String {
     let mut rev_list = config.git();
     rev_list.args(&[
         PathBuf::from("rev-list"),
-        format!("--author={}", builder.config.stage0_metadata.config.git_merge_commit_email).into(),
+        format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
         "-n1".into(),
         "--first-parent".into(),
         "HEAD".into(),
         "--".into(),
-        builder.src.join("src/llvm-project"),
-        builder.src.join("src/bootstrap/download-ci-llvm-stamp"),
+        config.src.join("src/llvm-project"),
+        config.src.join("src/bootstrap/download-ci-llvm-stamp"),
         // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
-        builder.src.join("src/version"),
+        config.src.join("src/version"),
     ]);
     let llvm_sha = output(&mut rev_list);
     let llvm_sha = llvm_sha.trim();
@@ -143,8 +140,82 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
         panic!();
     }
 
+    llvm_sha.to_owned()
+}
+
+/// Returns whether the CI-found LLVM is currently usable.
+///
+/// This checks both the build triple platform to confirm we're usable at all,
+/// and then verifies if the current HEAD matches the detected LLVM SHA head,
+/// in which case LLVM is indicated as not available.
+pub(crate) fn is_ci_llvm_available(config: &crate::config::Config, asserts: bool) -> bool {
+    // This is currently all tier 1 targets and tier 2 targets with host tools
+    // (since others may not have CI artifacts)
+    // https://doc.rust-lang.org/rustc/platform-support.html#tier-1
+    let supported_platforms = [
+        // tier 1
+        "aarch64-unknown-linux-gnu",
+        "i686-pc-windows-gnu",
+        "i686-pc-windows-msvc",
+        "i686-unknown-linux-gnu",
+        "x86_64-unknown-linux-gnu",
+        "x86_64-apple-darwin",
+        "x86_64-pc-windows-gnu",
+        "x86_64-pc-windows-msvc",
+        // tier 2 with host tools
+        "aarch64-apple-darwin",
+        "aarch64-pc-windows-msvc",
+        "aarch64-unknown-linux-musl",
+        "arm-unknown-linux-gnueabi",
+        "arm-unknown-linux-gnueabihf",
+        "armv7-unknown-linux-gnueabihf",
+        "mips-unknown-linux-gnu",
+        "mips64-unknown-linux-gnuabi64",
+        "mips64el-unknown-linux-gnuabi64",
+        "mipsel-unknown-linux-gnu",
+        "powerpc-unknown-linux-gnu",
+        "powerpc64-unknown-linux-gnu",
+        "powerpc64le-unknown-linux-gnu",
+        "riscv64gc-unknown-linux-gnu",
+        "s390x-unknown-linux-gnu",
+        "x86_64-unknown-freebsd",
+        "x86_64-unknown-illumos",
+        "x86_64-unknown-linux-musl",
+        "x86_64-unknown-netbsd",
+    ];
+    if !supported_platforms.contains(&&*config.build.triple) {
+        return false;
+    }
+
+    let triple = &*config.build.triple;
+    if (triple == "aarch64-unknown-linux-gnu" || triple.contains("i686")) && asserts {
+        // No alt builder for aarch64-unknown-linux-gnu today.
+        return false;
+    }
+
+    if crate::util::CiEnv::is_ci() {
+        let llvm_sha = detect_llvm_sha(config);
+        let head_sha = output(config.git().arg("rev-parse").arg("HEAD"));
+        let head_sha = head_sha.trim();
+        if llvm_sha == head_sha {
+            eprintln!(
+                "Detected LLVM as non-available: running in CI and modified LLVM in this change"
+            );
+            return false;
+        }
+    }
+
+    true
+}
+
+pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
+    let config = &builder.config;
+    if !config.llvm_from_ci {
+        return;
+    }
     let llvm_root = config.ci_llvm_root();
     let llvm_stamp = llvm_root.join(".llvm-stamp");
+    let llvm_sha = detect_llvm_sha(&config);
     let key = format!("{}{}", llvm_sha, config.llvm_assertions);
     if program_out_of_date(&llvm_stamp, &key) && !config.dry_run {
         download_ci_llvm(builder, &llvm_sha);
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 1895e290148..3a00e258e00 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -258,6 +258,10 @@ impl CiEnv {
         }
     }
 
+    pub fn is_ci() -> bool {
+        Self::current() != CiEnv::None
+    }
+
     /// If in a CI environment, forces the command to run with colors.
     pub fn force_coloring_in_ci(self, cmd: &mut Command) {
         if self != CiEnv::None {
diff --git a/src/ci/docker/host-x86_64/arm-android/Dockerfile b/src/ci/docker/host-x86_64/arm-android/Dockerfile
index a2335687ab3..d0d367b39b4 100644
--- a/src/ci/docker/host-x86_64/arm-android/Dockerfile
+++ b/src/ci/docker/host-x86_64/arm-android/Dockerfile
@@ -29,6 +29,10 @@ ENV PATH=$PATH:/android/sdk/platform-tools
 
 ENV TARGETS=arm-linux-androideabi
 
+# We are intentionally allowing an old toolchain on this builder (and that's
+# incompatible with LLVM downloads today).
+ENV NO_DOWNLOAD_CI_LLVM 1
+
 ENV RUST_CONFIGURE_ARGS --arm-linux-androideabi-ndk=/android/ndk/arm-14 \
     --set llvm.allow-old-toolchain
 
diff --git a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
index e2dbc7cfd7c..69f88e49520 100644
--- a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
@@ -78,6 +78,8 @@ RUN curl -O https://ci-mirrors.rust-lang.org/rustc/vexpress-v2p-ca15-tc1.dtb
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY static/gitconfig /etc/gitconfig
+
 ENV RUST_CONFIGURE_ARGS --qemu-armhf-rootfs=/tmp/rootfs
 ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target arm-unknown-linux-gnueabihf
 
diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
index 1f8d0a64ea4..71ea13071bd 100644
--- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
@@ -27,6 +27,10 @@ RUN mkdir -p /config
 RUN echo "[rust]" > /config/nopt-std-config.toml
 RUN echo "optimize = false" >> /config/nopt-std-config.toml
 
+# We are intentionally allowing an old toolchain on this builder (and that's
+# incompatible with LLVM downloads today).
+ENV NO_DOWNLOAD_CI_LLVM 1
+
 ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests \
     --set llvm.allow-old-toolchain
 ENV SCRIPT python3 ../x.py test --stage 0 --config /config/nopt-std-config.toml library/std \
diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
index 7bca0398dea..ebeab3dbdb7 100644
--- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
@@ -23,6 +23,9 @@ RUN sh /scripts/sccache.sh
 COPY scripts/cmake.sh /scripts/
 RUN /scripts/cmake.sh
 
+# We are intentionally allowing an old toolchain on this builder (and that's
+# incompatible with LLVM downloads today).
+ENV NO_DOWNLOAD_CI_LLVM 1
 ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu \
     --set llvm.allow-old-toolchain
 # Exclude some tests that are unlikely to be platform specific, to speed up
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 9ee84f420b9..c6723d91c8b 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -1,4 +1,7 @@
 FROM ubuntu:18.04
+# FIXME: when bumping the version, remove the Python 3.6-specific changes in
+# the reuse-requirements.in file, regenerate reuse-requirements.txt and remove
+# this comment.
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
   g++ \
@@ -8,6 +11,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   curl \
   ca-certificates \
   python3 \
+  python3-pip \
+  python3-pkg-resources \
   git \
   cmake \
   sudo \
@@ -27,6 +32,9 @@ RUN npm install eslint@8.6.0 -g
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
+RUN pip3 install --no-deps --require-hashes -r /tmp/reuse-requirements.txt
+
 COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
 COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
@@ -40,6 +48,7 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
            python3 ../x.py doc --stage 0 library/test && \
            /scripts/validate-toolstate.sh && \
            /scripts/validate-error-codes.sh && \
+           reuse lint && \
            # Runs checks to ensure that there are no ES5 issues in our JS code.
            es-check es6 ../src/librustdoc/html/static/js/*.js && \
            eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js
diff --git a/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in
new file mode 100644
index 00000000000..4964f40aa39
--- /dev/null
+++ b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.in
@@ -0,0 +1,22 @@
+# This is the template for reuse-requirements.txt.
+#
+# The pip-tools project is used to generate the file again. To install it, the
+# recommended way is to:
+#
+# - Install pipx from https://github.com/pypa/pipx
+# - Run `pipx install pip-tools`
+#
+# Once pip-tools is installed, run this command to regenerate the .txt file:
+#
+#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
+#
+
+reuse
+
+# Some packages dropped support for Python 3.6, which is the version used in
+# this builder (due to Ubuntu 18.04). This should be removed once we bump the
+# Ubuntu version of the builder.
+jinja2 < 3.1
+markupsafe < 2.1
+requests < 2.28
+setuptools < 59.7
diff --git a/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt
new file mode 100644
index 00000000000..10a5f738790
--- /dev/null
+++ b/src/ci/docker/host-x86_64/mingw-check/reuse-requirements.txt
@@ -0,0 +1,145 @@
+#
+# This file is autogenerated by pip-compile with python 3.10
+# To update, run:
+#
+#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
+#
+binaryornot==0.4.4 \
+    --hash=sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061 \
+    --hash=sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4
+    # via reuse
+boolean-py==3.8 \
+    --hash=sha256:cc24e20f985d60cd4a3a5a1c0956dd12611159d32a75081dabd0c9ab981acaa4 \
+    --hash=sha256:d75da0fd0354425fa64f6bbc6cec6ae1485d0eec3447b73187ff8cbf9b572e26
+    # via
+    #   license-expression
+    #   reuse
+certifi==2022.6.15 \
+    --hash=sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d \
+    --hash=sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412
+    # via requests
+chardet==5.0.0 \
+    --hash=sha256:0368df2bfd78b5fc20572bb4e9bb7fb53e2c094f60ae9993339e8671d0afb8aa \
+    --hash=sha256:d3e64f022d254183001eccc5db4040520c0f23b1a3f33d6413e099eb7f126557
+    # via
+    #   binaryornot
+    #   python-debian
+charset-normalizer==2.0.12 \
+    --hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \
+    --hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df
+    # via requests
+idna==3.3 \
+    --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
+    --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
+    # via requests
+jinja2==3.0.3 \
+    --hash=sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8 \
+    --hash=sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7
+    # via
+    #   -r reuse-requirements.in
+    #   reuse
+license-expression==21.6.14 \
+    --hash=sha256:324246eed8e138b4139fefdc0e9dc4161d5075e3929e56983966d37298dca30e \
+    --hash=sha256:9de87a427c9a449eee7913472fb9ed03b63036295547369fdbf95f76a8b924b2
+    # via
+    #   -r reuse-requirements.in
+    #   reuse
+markupsafe==2.0.1 \
+    --hash=sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298 \
+    --hash=sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64 \
+    --hash=sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b \
+    --hash=sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194 \
+    --hash=sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567 \
+    --hash=sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff \
+    --hash=sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724 \
+    --hash=sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74 \
+    --hash=sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646 \
+    --hash=sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35 \
+    --hash=sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6 \
+    --hash=sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a \
+    --hash=sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6 \
+    --hash=sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad \
+    --hash=sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26 \
+    --hash=sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38 \
+    --hash=sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac \
+    --hash=sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7 \
+    --hash=sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6 \
+    --hash=sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047 \
+    --hash=sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75 \
+    --hash=sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f \
+    --hash=sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b \
+    --hash=sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135 \
+    --hash=sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8 \
+    --hash=sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a \
+    --hash=sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a \
+    --hash=sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1 \
+    --hash=sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9 \
+    --hash=sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864 \
+    --hash=sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914 \
+    --hash=sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee \
+    --hash=sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f \
+    --hash=sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18 \
+    --hash=sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8 \
+    --hash=sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2 \
+    --hash=sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d \
+    --hash=sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b \
+    --hash=sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b \
+    --hash=sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86 \
+    --hash=sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6 \
+    --hash=sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f \
+    --hash=sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb \
+    --hash=sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833 \
+    --hash=sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28 \
+    --hash=sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e \
+    --hash=sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415 \
+    --hash=sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902 \
+    --hash=sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f \
+    --hash=sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d \
+    --hash=sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9 \
+    --hash=sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d \
+    --hash=sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145 \
+    --hash=sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066 \
+    --hash=sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c \
+    --hash=sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1 \
+    --hash=sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a \
+    --hash=sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207 \
+    --hash=sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f \
+    --hash=sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53 \
+    --hash=sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd \
+    --hash=sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134 \
+    --hash=sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85 \
+    --hash=sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9 \
+    --hash=sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5 \
+    --hash=sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94 \
+    --hash=sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509 \
+    --hash=sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51 \
+    --hash=sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872
+    # via
+    #   -r reuse-requirements.in
+    #   jinja2
+python-debian==0.1.44 \
+    --hash=sha256:11bd6f01c46da57982bdd66dd595e2d240feb32a85de3fd37c452102fd0337ab \
+    --hash=sha256:65592fe3b64f6c6c93d94e2d2599db5e0c22831d3bcff07cb7b96d3840b1333e
+    # via reuse
+requests==2.26.0 \
+    --hash=sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
+    --hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
+    # via
+    #   -r reuse-requirements.in
+    #   reuse
+reuse==1.0.0 \
+    --hash=sha256:db3022be2d87f69c8f508b928023de3026f454ce17d01e22f770f7147ac1e8d4 \
+    --hash=sha256:e2605e796311c424465d741ea2a1e1ad03bbb90b921d74750119c331ca5af46e
+    # via -r reuse-requirements.in
+urllib3==1.26.10 \
+    --hash=sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec \
+    --hash=sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6
+    # via requests
+
+# The following packages are considered to be unsafe in a requirements file:
+setuptools==59.6.0 \
+    --hash=sha256:22c7348c6d2976a52632c67f7ab0cdf40147db7789f9aed18734643fe9cf3373 \
+    --hash=sha256:4ce92f1e1f8f01233ee9952c04f6b81d1e02939d6e1b488428154974a4d0783e
+    # via
+    #   -r reuse-requirements.in
+    #   reuse
diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile
index 4d554a2852a..b75e2f085cd 100644
--- a/src/ci/docker/host-x86_64/test-various/Dockerfile
+++ b/src/ci/docker/host-x86_64/test-various/Dockerfile
@@ -30,6 +30,10 @@ WORKDIR /
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+# We are disabling CI LLVM since this builder needs to build LLD, which is
+# currently unsupported when downloading pre-built LLVM.
+ENV NO_DOWNLOAD_CI_LLVM 1
+
 ENV RUST_CONFIGURE_ARGS \
   --musl-root-x86_64=/usr/local/x86_64-linux-musl \
   --set build.nodejs=/node-v15.14.0-linux-x64/bin/node \
diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile
index 878c4e34158..9e37c2822e8 100644
--- a/src/ci/docker/host-x86_64/wasm32/Dockerfile
+++ b/src/ci/docker/host-x86_64/wasm32/Dockerfile
@@ -48,6 +48,8 @@ ENV TARGETS=wasm32-unknown-emscripten
 # Use -O1 optimizations in the link step to reduce time spent optimizing.
 ENV EMCC_CFLAGS=-O1
 
+COPY static/gitconfig /etc/gitconfig
+
 # Emscripten installation is user-specific
 ENV NO_CHANGE_USER=1
 
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
index bfc6975c19d..321b3d6ace4 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
@@ -26,6 +26,10 @@ RUN sh /scripts/sccache.sh
 COPY scripts/cmake.sh /scripts/
 RUN /scripts/cmake.sh
 
+# We are intentionally allowing an old toolchain on this builder (and that's
+# incompatible with LLVM downloads today).
+ENV NO_DOWNLOAD_CI_LLVM 1
+
 ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu \
     --set llvm.allow-old-toolchain
 ENV RUST_CHECK_TARGET check-aux
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
index 13d440423b2..739045248fe 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
@@ -31,6 +31,9 @@ RUN sh /scripts/sccache.sh
 ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1
 ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 
+# llvm.use-linker conflicts with downloading CI LLVM
+ENV NO_DOWNLOAD_CI_LLVM 1
+
 ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
       --enable-debug \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
index 4bb4042cd7e..be4def85f14 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
@@ -22,6 +22,10 @@ RUN sh /scripts/sccache.sh
 COPY scripts/cmake.sh /scripts/
 RUN /scripts/cmake.sh
 
+# We are intentionally allowing an old toolchain on this builder (and that's
+# incompatible with LLVM downloads today).
+ENV NO_DOWNLOAD_CI_LLVM 1
+
 ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --set rust.ignore-git=false \
     --set llvm.allow-old-toolchain
 ENV SCRIPT python3 ../x.py --stage 2 test distcheck
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
index 21891c1244d..23f2215c2d9 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
@@ -26,7 +26,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
-# using llvm-link-shared due to libffi issues -- see #34486
+# We are disabling CI LLVM since this builder is intentionally using a host
+# LLVM, rather than the typical src/llvm-project LLVM.
+ENV NO_DOWNLOAD_CI_LLVM 1
+
+# Using llvm-link-shared due to libffi issues -- see #34486
 ENV RUST_CONFIGURE_ARGS \
     --build=x86_64-unknown-linux-gnu \
     --llvm-root=/usr/lib/llvm-13 \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
index 5f3af2f47ca..8f6831bc54e 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
@@ -37,7 +37,11 @@ RUN apt-get update && \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
-# using llvm-link-shared due to libffi issues -- see #34486
+# We are disabling CI LLVM since this builder is intentionally using a host
+# LLVM, rather than the typical src/llvm-project LLVM.
+ENV NO_DOWNLOAD_CI_LLVM 1
+
+# Using llvm-link-shared due to libffi issues -- see #34486
 ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
       --llvm-root=/usr/lib/llvm-13 \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index f442a477a7b..e2ec4f27500 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -80,6 +80,10 @@ COPY host-x86_64/x86_64-gnu-tools/browser-ui-test.version /tmp/
 # the local version of the package is different than the one used by the CI.
 RUN npm install -g browser-ui-test@$(head -n 1 /tmp/browser-ui-test.version) --unsafe-perm=true
 
+# We are intentionally allowing an old toolchain on this builder (and that's
+# incompatible with LLVM downloads today).
+ENV NO_DOWNLOAD_CI_LLVM 1
+
 ENV RUST_CONFIGURE_ARGS \
   --set llvm.allow-old-toolchain \
   --build=x86_64-unknown-linux-gnu \
diff --git a/src/ci/docker/static/gitconfig b/src/ci/docker/static/gitconfig
new file mode 100644
index 00000000000..6bad35f01ce
--- /dev/null
+++ b/src/ci/docker/static/gitconfig
@@ -0,0 +1,2 @@
+[safe]
+directory = *
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 91204eb0b05..a6bdd9f3186 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -600,6 +600,9 @@ jobs:
                 --build=i686-pc-windows-gnu
                 --set llvm.allow-old-toolchain
               SCRIPT: make ci-mingw-subset-1
+              # We are intentionally allowing an old toolchain on this builder (and that's
+              # incompatible with LLVM downloads today).
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             <<: *job-windows-xl
 
@@ -609,6 +612,9 @@ jobs:
                 --build=i686-pc-windows-gnu
                 --set llvm.allow-old-toolchain
               SCRIPT: make ci-mingw-subset-2
+              # We are intentionally allowing an old toolchain on this builder (and that's
+              # incompatible with LLVM downloads today).
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             <<: *job-windows-xl
 
@@ -619,6 +625,9 @@ jobs:
                 --build=x86_64-pc-windows-gnu
                 --enable-profiler
                 --set llvm.allow-old-toolchain
+              # We are intentionally allowing an old toolchain on this builder (and that's
+              # incompatible with LLVM downloads today).
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             <<: *job-windows-xl
 
@@ -629,6 +638,9 @@ jobs:
                 --build=x86_64-pc-windows-gnu
                 --enable-profiler
                 --set llvm.allow-old-toolchain
+              # We are intentionally allowing an old toolchain on this builder (and that's
+              # incompatible with LLVM downloads today).
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
             <<: *job-windows-xl
 
@@ -678,6 +690,9 @@ jobs:
                 --enable-full-tools
                 --enable-profiler
                 --set llvm.allow-old-toolchain
+              # We are intentionally allowing an old toolchain on this builder (and that's
+              # incompatible with LLVM downloads today).
+              NO_DOWNLOAD_CI_LLVM: 1
               SCRIPT: python x.py dist
               CUSTOM_MINGW: 1
               DIST_REQUIRE_ALL_TOOLS: 1
@@ -691,6 +706,9 @@ jobs:
                 --enable-full-tools
                 --enable-profiler
                 --set llvm.allow-old-toolchain
+              # We are intentionally allowing an old toolchain on this builder (and that's
+              # incompatible with LLVM downloads today).
+              NO_DOWNLOAD_CI_LLVM: 1
               CUSTOM_MINGW: 1
               DIST_REQUIRE_ALL_TOOLS: 1
             <<: *job-windows-xl
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 6545475d996..9a247fb60a8 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -11,6 +11,16 @@ if [ "$NO_CHANGE_USER" = "" ]; then
     useradd --shell /bin/bash -u $LOCAL_USER_ID -o -c "" -m user
     export HOME=/home/user
     unset LOCAL_USER_ID
+
+    # Ensure that runners are able to execute git commands in the worktree,
+    # overriding the typical git protections. In our docker container we're running
+    # as root, while the user owning the checkout is not root.
+    # This is only necessary when we change the user, otherwise we should
+    # already be running with the right user.
+    #
+    # For NO_CHANGE_USER done in the small number of Dockerfiles affected.
+    echo -e '[safe]\n\tdirectory = *' > /home/user/gitconfig
+
     exec su --preserve-environment -c "env PATH=$PATH \"$0\"" user
   fi
 fi
@@ -102,6 +112,18 @@ else
   fi
 
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
+
+  # We enable this for non-dist builders, since those aren't trying to produce
+  # fresh binaries. We currently don't entirely support distributing a fresh
+  # copy of the compiler (including llvm tools, etc.) if we haven't actually
+  # built LLVM, since not everything necessary is copied into the
+  # local-usage-only LLVM artifacts. If that changes, this could maybe be made
+  # true for all builds. In practice it's probably a good idea to keep building
+  # LLVM continuously on at least some builders to ensure it works, though.
+  # (And PGO is its own can of worms).
+  if [ "$NO_DOWNLOAD_CI_LLVM" = "" ]; then
+    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.download-ci-llvm=if-available"
+  fi
 fi
 
 if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]; then
diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh
index 0bc8a0389a8..02b72625d6e 100755
--- a/src/ci/scripts/install-clang.sh
+++ b/src/ci/scripts/install-clang.sh
@@ -61,6 +61,10 @@ elif isWindows && [[ ${CUSTOM_MINGW-0} -ne 1 ]]; then
     7z x -oclang-rust/ "LLVM-${LLVM_VERSION}-win64.exe"
     ciCommandSetEnv RUST_CONFIGURE_ARGS \
         "${RUST_CONFIGURE_ARGS} --set llvm.clang-cl=$(pwd)/clang-rust/bin/clang-cl.exe"
+
+    # Disable downloading CI LLVM on this builder;
+    # setting up clang-cl just above conflicts with the default if-available option.
+    ciCommandSetEnv NO_DOWNLOAD_CI_LLVM 1
 fi
 
 if isWindows; then
diff --git a/src/doc/book b/src/doc/book
-Subproject 36383b4da21dbd0a0781473bc8ad7ef0ed1b675
+Subproject 42ca0ef484fcc8437a0682cee23abe4b7c407d5
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject c55611dd6c58bdeb52423b5c52fd0f3c93615ba
+Subproject 6038be9d37d7251c966b486154af621d1794d7a
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 8d1e4dccf71114ff56f328f671f2026d8e6b62a
+Subproject 8e6aa3448515a0654e347b5e2510f1d4bc4d5a6
diff --git a/src/doc/reference b/src/doc/reference
-Subproject f3d3953bf3b158d596c96d55ce5366f9f3f972e
+Subproject e647eb102890e8927f488bea12672b079eff8d9
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject ee342dc91e1ba1bb1e1f1318f84bbe3bfac0479
+Subproject 03301f8ae55fa6f20f7ea152a517598e6db2cdb
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 04f3cf0bb2f5a6ee2bfc4b1a6a6cd8c11d1c553
+Subproject d3daa1f28e169087becbc5e2b49ac91ca0405a4
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index c526e4d1fa8..8b204949a6e 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -121,7 +121,10 @@ following files inside:
 
 **`package/meta/package`**
 ```json
-{"name":"hello_fuchsia","version":0}
+{
+  "name": "hello_fuchsia",
+  "version": "0"
+}
 ```
 
 The `package` file describes our package's name and version number. Every
@@ -232,10 +235,17 @@ ${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
 ${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
 ```
 
-Then, once the emulator has been started:
+Once the emulator is running, start a package repository server to serve our
+package to the emulator:
 
 ```sh
-${SDK_PATH}/tools/${ARCH}/ffx target repository register
+${SDK_PATH}/tools/${ARCH}/ffx repository server start
+```
+
+Once the repository server is up and running, register our repository:
+
+```sh
+${SDK_PATH}/tools/${ARCH}/ffx target repository register --repository hello-fuchsia
 ```
 
 And watch the logs from the emulator in a separate terminal:
@@ -253,6 +263,10 @@ ${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fu
 On reruns of the component, the `--recreate` argument may also need to be
 passed.
 
+```sh
+${SDK_PATH}/tools/${ARCH}/ffx component run --recreate fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm
+```
+
 ## Testing
 
 ### Running unit tests
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index ddaa7438e17..cbdfea89efb 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -11,7 +11,7 @@ arrayvec = { version = "0.7", default-features = false }
 askama = { version = "0.11", default-features = false, features = ["config"] }
 atty = "0.2"
 pulldown-cmark = { version = "0.9.2", default-features = false }
-minifier = "0.2.1"
+minifier = "0.2.2"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 smallvec = "1.8.1"
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 61cfd7ea40d..51976a91cea 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -820,8 +820,6 @@ pub(crate) trait AttributesExt {
 
     fn inner_docs(&self) -> bool;
 
-    fn other_attrs(&self) -> Vec<ast::Attribute>;
-
     fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>>;
 }
 
@@ -848,10 +846,6 @@ impl AttributesExt for [ast::Attribute] {
         self.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == AttrStyle::Inner)
     }
 
-    fn other_attrs(&self) -> Vec<ast::Attribute> {
-        self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect()
-    }
-
     fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet<Cfg>) -> Option<Arc<Cfg>> {
         let sess = tcx.sess;
         let doc_cfg_active = tcx.features().doc_cfg;
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 1ac5186f9f6..f9d6b4619cc 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -569,7 +569,10 @@ fn short_item_info(
             message.push_str(&format!(": {}", html.into_string()));
         }
         extra_info.push(format!(
-            "<div class=\"stab deprecated\"><span class=\"emoji\">👎</span> {}</div>",
+            "<div class=\"stab deprecated\">\
+                 <span class=\"emoji\">👎</span>\
+                 <span>{}</span>\
+             </div>",
             message,
         ));
     }
@@ -582,8 +585,9 @@ fn short_item_info(
         .filter(|stab| stab.feature != sym::rustc_private)
         .map(|stab| (stab.level, stab.feature))
     {
-        let mut message =
-            "<span class=\"emoji\">🔬</span> This is a nightly-only experimental API.".to_owned();
+        let mut message = "<span class=\"emoji\">🔬</span>\
+             <span>This is a nightly-only experimental API."
+            .to_owned();
 
         let mut feature = format!("<code>{}</code>", Escape(feature.as_str()));
         if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, issue) {
@@ -594,7 +598,7 @@ fn short_item_info(
             ));
         }
 
-        message.push_str(&format!(" ({})", feature));
+        message.push_str(&format!(" ({})</span>", feature));
 
         extra_info.push(format!("<div class=\"stab unstable\">{}</div>", message));
     }
@@ -1985,7 +1989,7 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
             {
                 let mut derefs = FxHashSet::default();
                 derefs.insert(did);
-                sidebar_deref_methods(cx, out, impl_, v, &mut derefs);
+                sidebar_deref_methods(cx, out, impl_, v, &mut derefs, &mut used_links);
             }
 
             let format_impls = |impls: Vec<&Impl>, id_map: &mut IdMap| {
@@ -2057,6 +2061,7 @@ fn sidebar_deref_methods(
     impl_: &Impl,
     v: &[Impl],
     derefs: &mut FxHashSet<DefId>,
+    used_links: &mut FxHashSet<String>,
 ) {
     let c = cx.cache();
 
@@ -2089,13 +2094,10 @@ fn sidebar_deref_methods(
             .and_then(|did| c.impls.get(&did));
         if let Some(impls) = inner_impl {
             debug!("found inner_impl: {:?}", impls);
-            let mut used_links = FxHashSet::default();
             let mut ret = impls
                 .iter()
                 .filter(|i| i.inner_impl().trait_.is_none())
-                .flat_map(|i| {
-                    get_methods(i.inner_impl(), true, &mut used_links, deref_mut, cx.tcx())
-                })
+                .flat_map(|i| get_methods(i.inner_impl(), true, used_links, deref_mut, cx.tcx()))
                 .collect::<Vec<_>>();
             if !ret.is_empty() {
                 let id = if let Some(target_def_id) = real_target.def_id(c) {
@@ -2124,7 +2126,14 @@ fn sidebar_deref_methods(
                         .map(|t| Some(t.def_id()) == cx.tcx().lang_items().deref_trait())
                         .unwrap_or(false)
                 }) {
-                    sidebar_deref_methods(cx, out, target_deref_impl, target_impls, derefs);
+                    sidebar_deref_methods(
+                        cx,
+                        out,
+                        target_deref_impl,
+                        target_impls,
+                        derefs,
+                        used_links,
+                    );
                 }
             }
         }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 710ca3ee7c7..b1fa5e7d86d 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -693,8 +693,13 @@ h2.location a {
 	flex-grow: 1;
 	margin: 0px;
 	padding: 0px;
+	/* We use overflow-wrap: break-word for Safari, which doesn't recognize
+	   `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */
 	overflow-wrap: break-word;
+	/* Then override it with `anywhere`, which is required to make non-Safari browsers break
+	   more aggressively when we want them to. */
 	overflow-wrap: anywhere;
+	background-color: var(--main-background-color);
 }
 
 .in-band > code, .in-band > .code-header {
@@ -731,13 +736,13 @@ pre, .rustdoc.source .example-wrap {
 
 .docblock table td {
 	padding: .5em;
-	border: 1px dashed;
+	border: 1px dashed var(--border-color);
 }
 
 .docblock table th {
 	padding: .5em;
 	text-align: left;
-	border: 1px solid;
+	border: 1px solid var(--border-color);
 }
 
 .fields + table {
@@ -835,20 +840,6 @@ nav.sub {
 .source nav.sub {
 	margin-left: 32px;
 }
-nav.main {
-	padding: 20px 0;
-	text-align: center;
-}
-nav.main .current {
-	border-top: 1px solid;
-	border-bottom: 1px solid;
-}
-nav.main .separator {
-	border: 1px solid;
-	display: inline-block;
-	height: 23px;
-	margin: 0 20px;
-}
 nav.sum { text-align: right; }
 nav.sub form { display: inline; }
 
@@ -974,7 +965,7 @@ table,
 	max-width: 100%;
 	/* contents can overflow because of max-width limit, then show ellipsis */
 	text-overflow: ellipsis;
-	border: 1px solid;
+	border: 1px solid var(--border-color);
 	border-radius: 4px;
 	outline: none;
 	cursor: pointer;
@@ -1027,11 +1018,12 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	-moz-box-sizing: border-box !important;
 	box-sizing: border-box !important;
 	outline: none;
-	border: 1px solid;
+	border: 1px solid var(--border-color);
 	border-radius: 2px;
 	padding: 8px;
 	font-size: 1rem;
 	width: 100%;
+	background-color: var(--button-background-color);
 }
 
 .search-results {
@@ -1087,7 +1079,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	display: block;
 	margin-top: 7px;
 	border-radius: 3px;
-	border: 1px solid;
+	border: 1px solid var(--border-color);
 	font-size: 1rem;
 }
 
@@ -1096,7 +1088,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	content: '';
 	position: absolute;
 	right: 11px;
-	border: solid;
+	border: solid var(--border-color);
 	border-width: 1px 1px 0 0;
 	display: inline-block;
 	padding: 4px;
@@ -1132,13 +1124,13 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	text-align: center;
 	display: block;
 	margin: 10px 0;
-	border-bottom: 1px solid;
+	border-bottom: 1px solid var(--border-color);
 	padding-bottom: 4px;
 	margin-bottom: 6px;
 }
 #help-button span.bottom {
 	clear: both;
-	border-top: 1px solid;
+	border-top: 1px solid var(--border-color);
 }
 .side-by-side {
 	text-align: initial;
@@ -1172,6 +1164,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 
 .stab .emoji {
 	font-size: 1.25rem;
+	margin-right: 0.3rem;
 }
 
 /* Black one-pixel outline around emoji shapes */
@@ -1331,6 +1324,7 @@ h3.variant {
 	border-radius: 6px;
 	margin-left: 5px;
 	font-size: 1rem;
+	border: 1px solid var(--border-color);
 }
 
 .tooltip.ignore::after {
@@ -1496,7 +1490,7 @@ pre.rust {
 #source-sidebar > .title {
 	font-size: 1.5rem;
 	text-align: center;
-	border-bottom: 1px solid;
+	border-bottom: 1px solid var(--border-color);
 	margin-bottom: 6px;
 }
 #sidebar-toggle > button {
@@ -1524,11 +1518,12 @@ pre.rust {
 
 #copy-path {
 	height: 34px;
+	background-color: var(--main-background-color);
 }
 #settings-menu > a, #help-button > button, #copy-path {
 	padding: 5px;
 	width: 33px;
-	border: 1px solid;
+	border: 1px solid var(--border-color);
 	border-radius: 2px;
 	cursor: pointer;
 }
@@ -1539,6 +1534,7 @@ pre.rust {
 	padding: 5px;
 	height: 100%;
 	display: block;
+	background-color: var(--button-background-color);
 }
 
 @keyframes rotating {
@@ -1588,37 +1584,13 @@ input:checked + .slider {
 	border: 0;
 }
 
-#theme-choices {
-	display: none;
-	position: absolute;
-	left: 0;
-	top: 28px;
-	border: 1px solid;
-	border-radius: 3px;
-	z-index: 1;
-	cursor: pointer;
-}
-
-#theme-choices > button {
-	border: none;
-	width: 100%;
-	padding: 4px 8px;
-	text-align: center;
-	background: rgba(0,0,0,0);
-	overflow-wrap: normal;
-}
-
-#theme-choices > button:not(:first-child) {
-	border-top: 1px solid;
-}
-
 kbd {
 	display: inline-block;
 	padding: 3px 5px;
 	font: 15px monospace;
 	line-height: 10px;
 	vertical-align: middle;
-	border: solid 1px;
+	border: solid 1px var(--border-color);
 	border-radius: 3px;
 	cursor: default;
 }
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 4dfb64abbeb..e7ccd402dd0 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -14,6 +14,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--scrollbar-thumb-background-color: #5c6773;
 	--scrollbar-color: #5c6773 #24292f;
 	--headings-border-bottom-color: #5c6773;
+	--border-color: #5c6773;
+	--button-background-color: #141920;
 }
 
 .slider {
@@ -36,10 +38,6 @@ h4 {
 	border: none;
 }
 
-.in-band {
-	background-color: #0f1419;
-}
-
 .docblock code {
 	color: #ffb454;
 }
@@ -84,10 +82,6 @@ pre, .rustdoc.source .example-wrap {
 	border-right: 1px solid #ffb44c;
 }
 
-.docblock table td, .docblock table th {
-	border-color: #5c6773;
-}
-
 .search-results a:hover {
 	background-color: #777;
 }
@@ -151,13 +145,6 @@ pre, .rustdoc.source .example-wrap {
 pre.rust .comment { color: #788797; }
 pre.rust .doccomment { color: #a1ac88; }
 
-nav.main .current {
-	border-top-color: #5c6773;
-	border-bottom-color: #5c6773;
-}
-nav.main .separator {
-	border: 1px solid #5c6773;
-}
 a {
 	color: #39AFD7;
 }
@@ -182,17 +169,6 @@ details.rustdoc-toggle > summary::before {
 	filter: invert(100%);
 }
 
-.search-input {
-	background-color: #141920;
-	border-color: #424c57;
-}
-
-#crate-search {
-	/* Without the `!important`, the border-color is ignored for `<select>`...
-	   It cannot be in the group above because `.search-input` has a different border color on
-	   hover. */
-	border-color: #5c6773 !important;
-}
 #crate-search-div::after {
 	/* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
 	filter: invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);
@@ -205,7 +181,7 @@ details.rustdoc-toggle > summary::before {
 }
 
 .search-input {
-	color: #ffffff;
+	color: #fff;
 }
 
 .module-item .stab,
@@ -333,7 +309,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
 .tooltip::after {
 	background-color: #314559;
 	color: #c5c5c5;
-	border: 1px solid #5c6773;
 }
 
 .tooltip::before {
@@ -342,11 +317,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
 
 .notable-traits-tooltiptext {
 	background-color: #314559;
-	border-color: #5c6773;
-}
-
-.notable-traits-tooltiptext .notable {
-	border-bottom-color: #5c6773;
 }
 
 #titles > button.selected {
@@ -449,23 +419,13 @@ a.result-keyword:focus {}
 .sidebar a.current.tymethod {}
 .sidebar a.current.keyword {}
 
-@media (max-width: 700px) {
-	.sidebar-elems {
-		border-right-color: #5c6773;
-	}
-}
-
 kbd {
 	color: #c5c5c5;
 	background-color: #314559;
-	border-color: #5c6773;
-	border-bottom-color: #5c6773;
 	box-shadow: inset 0 -1px 0 #5c6773;
 }
 
 #settings-menu > a, #help-button > button {
-	border-color: #5c6773;
-	background-color: #0f1419;
 	color: #fff;
 }
 
@@ -473,11 +433,6 @@ kbd {
 	filter: invert(100);
 }
 
-.popover, .popover::before,
-#help-button span.top, #help-button span.bottom {
-	border-color: #5c6773;
-}
-
 #copy-path {
 	color: #fff;
 }
@@ -493,19 +448,6 @@ kbd {
 	border-color: #e0e0e0;
 }
 
-#theme-choices {
-	border-color: #5c6773;
-	background-color: #0f1419;
-}
-
-#theme-choices > button:not(:first-child) {
-	border-top-color: #5c6773;
-}
-
-#theme-choices > button:hover, #theme-choices > button:focus {
-	background-color: rgba(110, 110, 110, 0.33);
-}
-
 .search-results .result-name span.alias {
 	color: #c5c5c5;
 }
@@ -515,7 +457,6 @@ kbd {
 
 #source-sidebar > .title {
 	color: #fff;
-	border-bottom-color: #5c6773;
 }
 #source-sidebar div.files > a:hover, details.dir-entry summary:hover,
 #source-sidebar div.files > a:focus, details.dir-entry summary:focus {
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 39f83c99808..1fcda22b6f4 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -9,6 +9,8 @@
 	--scrollbar-thumb-background-color: rgba(32, 34, 37, .6);
 	--scrollbar-color: rgba(32,34,37,.6) #5a5a5a;
 	--headings-border-bottom-color: #d2d2d2;
+	--border-color: #e0e0e0;
+	--button-background-color: #f0f0f0;
 }
 
 .slider {
@@ -21,10 +23,6 @@ input:focus + .slider {
 	box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
 }
 
-.in-band {
-	background-color: #353535;
-}
-
 .rust-logo {
 	filter: drop-shadow(1px 0 0px #fff)
 		drop-shadow(0 1px 0 #fff)
@@ -42,10 +40,6 @@ input:focus + .slider {
 	background-color: #0a042f !important;
 }
 
-.docblock table td, .docblock table th {
-	border-color: #ddd;
-}
-
 .search-results a:hover {
 	background-color: #777;
 }
@@ -127,14 +121,6 @@ a.result-keyword:focus { background-color: #884719; }
 pre.rust .comment { color: #8d8d8b; }
 pre.rust .doccomment { color: #8ca375; }
 
-nav.main .current {
-	border-top-color: #eee;
-	border-bottom-color: #eee;
-}
-nav.main .separator {
-	border-color: #eee;
-}
-
 a {
 	color: #D2991D;
 }
@@ -154,16 +140,9 @@ details.rustdoc-toggle > summary::before {
 
 .search-input {
 	color: #111;
-	background-color: #f0f0f0;
 	border-color: #f0f0f0;
 }
 
-#crate-search {
-	/* Without the `!important`, the border-color is ignored for `<select>`...
-	   It cannot be in the group above because `.search-input` has a different border color on
-	   hover. */
-	border-color: #d2d2d2 !important;
-}
 #crate-search-div::after {
 	/* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
 	filter: invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);
@@ -175,10 +154,6 @@ details.rustdoc-toggle > summary::before {
 	filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);
 }
 
-.search-input {
-	border-color: #e0e0e0;
-}
-
 .search-input:focus {
 	border-color: #008dfd;
 }
@@ -296,11 +271,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
 
 .notable-traits-tooltiptext {
 	background-color: #111;
-	border-color: #777;
-}
-
-.notable-traits-tooltiptext .notable {
-	border-bottom-color: #d2d2d2;
 }
 
 #titles > button:not(.selected) {
@@ -317,23 +287,13 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	color: #888;
 }
 
-@media (max-width: 700px) {
-	.sidebar-elems {
-		border-right-color: #000;
-	}
-}
-
 kbd {
 	color: #000;
 	background-color: #fafbfc;
-	border-color: #d1d5da;
-	border-bottom-color: #c6cbd1;
 	box-shadow: inset 0 -1px 0 #c6cbd1;
 }
 
 #settings-menu > a, #help-button > button {
-	border-color: #e0e0e0;
-	background: #f0f0f0;
 	color: #000;
 }
 
@@ -342,11 +302,6 @@ kbd {
 	border-color: #ffb900;
 }
 
-.popover, .popover::before,
-#help-button span.top, #help-button span.bottom {
-	border-color: #d2d2d2;
-}
-
 #copy-path {
 	color: #999;
 }
@@ -357,19 +312,6 @@ kbd {
 	filter: invert(65%);
 }
 
-#theme-choices {
-	border-color: #e0e0e0;
-	background-color: #353535;
-}
-
-#theme-choices > button:not(:first-child) {
-	border-top-color: #e0e0e0;
-}
-
-#theme-choices > button:hover, #theme-choices > button:focus {
-	background-color: #4e4e4e;
-}
-
 .search-results .result-name span.alias {
 	color: #fff;
 }
@@ -377,9 +319,6 @@ kbd {
 	color: #ccc;
 }
 
-#source-sidebar > .title {
-	border-bottom-color: #ccc;
-}
 #source-sidebar div.files > a:hover, details.dir-entry summary:hover,
 #source-sidebar div.files > a:focus, details.dir-entry summary:focus {
 	background-color: #444;
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 5698088c790..7139c199729 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -9,6 +9,8 @@
 	--scrollbar-thumb-background-color: rgba(36, 37, 39, 0.6);
 	--scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9;
 	--headings-border-bottom-color: #ddd;
+	--border-color: #e0e0e0;
+	--button-background-color: #fff;
 }
 
 .slider {
@@ -21,10 +23,6 @@ input:focus + .slider {
 	box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
 }
 
-.in-band {
-	background-color: white;
-}
-
 .rust-logo {
 	/* This rule exists to force other themes to explicitly style the logo.
 	 * Rustdoc has a custom linter for this purpose.
@@ -41,10 +39,6 @@ input:focus + .slider {
 	background-color: #FDFFD3 !important;
 }
 
-.docblock table td, .docblock table th {
-	border-color: #ddd;
-}
-
 .search-results a:hover {
 	background-color: #ddd;
 }
@@ -123,14 +117,6 @@ a.result-keyword:focus { background-color: #afc6e4; }
 .sidebar a.current.tymethod { color: #a67736; }
 .sidebar a.current.keyword { color: #356da4; }
 
-nav.main .current {
-	border-top-color: #000;
-	border-bottom-color: #000;
-}
-nav.main .separator {
-	border: 1px solid #000;
-}
-
 a {
 	color: #3873AD;
 }
@@ -144,16 +130,6 @@ details.rustdoc-toggle > summary::before {
 	color: #999;
 }
 
-.search-input {
-	background-color: white;
-	border-color: #e0e0e0;
-}
-#crate-search {
-	/* Without the `!important`, the border-color is ignored for `<select>`...
-	   It cannot be in the group above because `.search-input` has a different border color on
-	   hover. */
-	border-color: #e0e0e0 !important;
-}
 #crate-search-div::after {
 	/* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
 	filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);
@@ -279,11 +255,6 @@ pre.ignore:hover, .information:hover + pre.ignore {
 
 .notable-traits-tooltiptext {
 	background-color: #eee;
-	border-color: #999;
-}
-
-.notable-traits-tooltiptext .notable {
-	border-bottom-color: #DDDDDD;
 }
 
 #titles > button:not(.selected) {
@@ -300,35 +271,17 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	color: #888;
 }
 
-@media (max-width: 700px) {
-	.sidebar-elems {
-		border-right-color: #000;
-	}
-}
-
 kbd {
 	color: #000;
 	background-color: #fafbfc;
-	border-color: #d1d5da;
-	border-bottom-color: #c6cbd1;
 	box-shadow: inset 0 -1px 0 #c6cbd1;
 }
 
-#settings-menu > a, #help-button > button {
-	border-color: #e0e0e0;
-	background-color: #fff;
-}
-
 #settings-menu > a:hover, #settings-menu > a:focus,
 #help-button > button:hover, #help-button > button:focus {
 	border-color: #717171;
 }
 
-.popover, .popover::before,
-#help-button span.top, #help-button span.bottom {
-	border-color: #e0e0e0;
-}
-
 #copy-path {
 	color: #999;
 }
@@ -339,19 +292,6 @@ kbd {
 	filter: invert(35%);
 }
 
-#theme-choices {
-	border-color: #ccc;
-	background-color: #fff;
-}
-
-#theme-choices > button:not(:first-child) {
-	border-top-color: #e0e0e0;
-}
-
-#theme-choices > button:hover, #theme-choices > button:focus {
-	background-color: #eee;
-}
-
 .search-results .result-name span.alias {
 	color: #000;
 }
@@ -359,9 +299,6 @@ kbd {
 	color: #999;
 }
 
-#source-sidebar > .title {
-	border-bottom-color: #ccc;
-}
 #source-sidebar div.files > a:hover, details.dir-entry summary:hover,
 #source-sidebar div.files > a:focus, details.dir-entry summary:focus {
 	background-color: #E0E0E0;
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 6364d00d062..7b1b059e14d 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -209,11 +209,11 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 }
 
                 types::ItemEnum::Method(_)
+                | types::ItemEnum::Module(_)
                 | types::ItemEnum::AssocConst { .. }
                 | types::ItemEnum::AssocType { .. }
                 | types::ItemEnum::PrimitiveType(_) => true,
-                types::ItemEnum::Module(_)
-                | types::ItemEnum::ExternCrate { .. }
+                types::ItemEnum::ExternCrate { .. }
                 | types::ItemEnum::Import(_)
                 | types::ItemEnum::StructField(_)
                 | types::ItemEnum::Variant(_)
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 0172ef5700b..381ac7a5dee 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,7 +1,8 @@
 //! Validates syntax inside Rust code blocks (\`\`\`rust).
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_errors::{
-    emitter::Emitter, Applicability, Diagnostic, Handler, LazyFallbackBundle, LintDiagnosticBuilder,
+    emitter::Emitter, translation::Translate, Applicability, Diagnostic, Handler,
+    LazyFallbackBundle, LintDiagnosticBuilder,
 };
 use rustc_parse::parse_stream_from_source_str;
 use rustc_session::parse::ParseSess;
@@ -181,6 +182,16 @@ struct BufferEmitter {
     fallback_bundle: LazyFallbackBundle,
 }
 
+impl Translate for BufferEmitter {
+    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+        None
+    }
+
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+        &**self.fallback_bundle
+    }
+}
+
 impl Emitter for BufferEmitter {
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
         let mut buffer = self.buffer.borrow_mut();
@@ -194,12 +205,4 @@ impl Emitter for BufferEmitter {
     fn source_map(&self) -> Option<&Lrc<SourceMap>> {
         None
     }
-
-    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
-        None
-    }
-
-    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
-        &**self.fallback_bundle
-    }
 }
diff --git a/src/test/codegen/README.md b/src/test/codegen/README.md
index 00de55eeab1..8f2daaafcc7 100644
--- a/src/test/codegen/README.md
+++ b/src/test/codegen/README.md
@@ -1,2 +1,24 @@
 The files here use the LLVM FileCheck framework, documented at
 <https://llvm.org/docs/CommandGuide/FileCheck.html>.
+
+One extension worth noting is the use of revisions as custom prefixes for
+FileCheck. If your codegen test has different behavior based on the chosen
+target or different compiler flags that you want to exercise, you can use a
+revisions annotation, like so:
+
+```rust
+// revisions: aaa bbb
+// [bbb] compile-flags: --flags-for-bbb
+```
+
+After specifying those variations, you can write different expected, or
+explicitly *unexpected* output by using `<prefix>-SAME:` and `<prefix>-NOT:`,
+like so:
+
+```rust
+// CHECK: expected code
+// aaa-SAME: emitted-only-for-aaa
+// aaa-NOT:                        emitted-only-for-bbb
+// bbb-NOT:  emitted-only-for-aaa
+// bbb-SAME:                       emitted-only-for-bbb
+```
diff --git a/src/test/codegen/try_question_mark_nop.rs b/src/test/codegen/try_question_mark_nop.rs
new file mode 100644
index 00000000000..d239387768e
--- /dev/null
+++ b/src/test/codegen/try_question_mark_nop.rs
@@ -0,0 +1,54 @@
+// min-llvm-version: 15.0
+// compile-flags: -O -Z merge-functions=disabled --edition=2021
+// only-x86_64
+
+#![crate_type = "lib"]
+#![feature(try_blocks)]
+
+// These are now NOPs in LLVM 15, presumably thanks to nikic's change mentioned in
+// <https://github.com/rust-lang/rust/issues/85133#issuecomment-1072168354>.
+// Unfortunately, as of 2022-08-17 they're not yet nops for `u64`s nor `Option`.
+
+use std::ops::ControlFlow::{self, Continue, Break};
+
+// CHECK-LABEL: @result_nop_match_32
+#[no_mangle]
+pub fn result_nop_match_32(x: Result<i32, u32>) -> Result<i32, u32> {
+    // CHECK: start
+    // CHECK-NEXT: ret i64 %0
+    match x {
+        Ok(x) => Ok(x),
+        Err(x) => Err(x),
+    }
+}
+
+// CHECK-LABEL: @result_nop_traits_32
+#[no_mangle]
+pub fn result_nop_traits_32(x: Result<i32, u32>) -> Result<i32, u32> {
+    // CHECK: start
+    // CHECK-NEXT: ret i64 %0
+    try {
+        x?
+    }
+}
+
+// CHECK-LABEL: @control_flow_nop_match_32
+#[no_mangle]
+pub fn control_flow_nop_match_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> {
+    // CHECK: start
+    // CHECK-NEXT: ret i64 %0
+    match x {
+        Continue(x) => Continue(x),
+        Break(x) => Break(x),
+    }
+}
+
+// CHECK-LABEL: @control_flow_nop_traits_32
+#[no_mangle]
+pub fn control_flow_nop_traits_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> {
+    // CHECK: start
+    // CHECK-NEXT: ret i64 %0
+    try {
+        x?
+    }
+}
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-1.rs b/src/test/incremental/const-generics/hash-tyvid-regression-1.rs
index 5ff7b19d894..53358b183cb 100644
--- a/src/test/incremental/const-generics/hash-tyvid-regression-1.rs
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-1.rs
@@ -9,7 +9,6 @@ where
     use std::convert::TryFrom;
     <[T; N.get()]>::try_from(())
     //~^ error: the trait bound
-    //~| error: the trait bound
     //~| error: mismatched types
 }
 
diff --git a/src/test/mir-opt/inline/polymorphic-recursion.rs b/src/test/mir-opt/inline/polymorphic-recursion.rs
new file mode 100644
index 00000000000..7388722b776
--- /dev/null
+++ b/src/test/mir-opt/inline/polymorphic-recursion.rs
@@ -0,0 +1,25 @@
+// Make sure that the MIR inliner does not loop indefinitely on polymorphic recursion.
+// compile-flags: --crate-type lib
+
+// Randomize `def_path_hash` by defining them under a module with different names
+macro_rules! emit {
+    ($($m:ident)*) => {$(
+        pub mod $m {
+            pub trait Tr { type Next: Tr; }
+
+            pub fn hoge<const N: usize, T: Tr>() {
+                inner::<N, T>();
+            }
+
+            #[inline(always)]
+            fn inner<const N: usize, T: Tr>()
+            {
+                inner::<N, T::Next>();
+                inner::<N, T::Next>();
+            }
+        }
+    )*};
+}
+
+// Increase the chance of triggering the bug
+emit!(m00 m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19);
diff --git a/src/test/mir-opt/issue-91633.rs b/src/test/mir-opt/issue-91633.rs
new file mode 100644
index 00000000000..8f66019857f
--- /dev/null
+++ b/src/test/mir-opt/issue-91633.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Z mir-opt-level=0
+// EMIT_MIR issue_91633.hey.mir_map.0.mir
+fn hey<T> (it: &[T])
+ where
+     [T] : std::ops::Index<usize>,
+ {
+     let _ = &it[0];
+ }
+
+// EMIT_MIR issue_91633.bar.mir_map.0.mir
+fn bar<T> (it: Box<[T]>)
+ where
+     [T] : std::ops::Index<usize>,
+ {
+     let _ = it[0];
+ }
+
+// EMIT_MIR issue_91633.fun.mir_map.0.mir
+fn fun<T> (it: &[T]) -> &T
+ {
+     let f = &it[0];
+     f
+ }
+
+// EMIT_MIR issue_91633.foo.mir_map.0.mir
+fn foo<T: Clone> (it: Box<[T]>) -> T
+ {
+     let f = it[0].clone();
+     f
+ }
+ fn main(){}
diff --git a/src/test/mir-opt/issue_91633.bar.mir_map.0.mir b/src/test/mir-opt/issue_91633.bar.mir_map.0.mir
new file mode 100644
index 00000000000..f5092d2ac92
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.bar.mir_map.0.mir
@@ -0,0 +1,39 @@
+// MIR for `bar` 0 mir_map
+
+fn bar(_1: Box<[T]>) -> () {
+    debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
+    let mut _0: ();                      // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
+    let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
+    let mut _3: &[T];                    // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
+    scope 1 {
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
+        StorageLive(_3);                 // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
+        _3 = &(*_1);                     // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
+        _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
+                                         // mir::Constant
+                                         // + span: $DIR/issue-91633.rs:15:14: 15:19
+                                         // + literal: Const { ty: for<'r> fn(&'r [T], usize) -> &'r <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
+    }
+
+    bb1: {
+        StorageDead(_3);                 // scope 0 at $DIR/issue-91633.rs:+4:18: +4:19
+        StorageDead(_2);                 // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
+        _0 = const ();                   // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
+        drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+    }
+
+    bb2: {
+        return;                          // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
+    }
+
+    bb3 (cleanup): {
+        drop(_1) -> bb4;                 // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+    }
+
+    bb4 (cleanup): {
+        resume;                          // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
+    }
+}
diff --git a/src/test/mir-opt/issue_91633.foo.mir_map.0.mir b/src/test/mir-opt/issue_91633.foo.mir_map.0.mir
new file mode 100644
index 00000000000..2e8b0feedd3
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.foo.mir_map.0.mir
@@ -0,0 +1,57 @@
+// MIR for `foo` 0 mir_map
+
+fn foo(_1: Box<[T]>) -> T {
+    debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:19: +0:21
+    let mut _0: T;                       // return place in scope 0 at $DIR/issue-91633.rs:+0:36: +0:37
+    let _2: T;                           // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+    let mut _3: &T;                      // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+    let _4: usize;                       // in scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
+    let mut _5: usize;                   // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+    let mut _6: bool;                    // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+    scope 1 {
+        debug f => _2;                   // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+        StorageLive(_3);                 // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+        StorageLive(_4);                 // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
+        _4 = const 0_usize;              // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
+        _5 = Len((*_1));                 // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+        _6 = Lt(_4, _5);                 // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];                 // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+        _2 = <T as Clone>::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+                                         // mir::Constant
+                                         // + span: $DIR/issue-91633.rs:28:20: 28:25
+                                         // + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
+    }
+
+    bb2: {
+        StorageDead(_3);                 // scope 0 at $DIR/issue-91633.rs:+2:26: +2:27
+        FakeRead(ForLet(None), _2);      // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+        StorageDead(_4);                 // scope 0 at $DIR/issue-91633.rs:+2:27: +2:28
+        _0 = move _2;                    // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
+        drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+    }
+
+    bb3: {
+        StorageDead(_2);                 // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+        drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+    }
+
+    bb4: {
+        return;                          // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
+    }
+
+    bb5 (cleanup): {
+        drop(_1) -> bb6;                 // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+    }
+
+    bb6 (cleanup): {
+        resume;                          // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
+    }
+}
diff --git a/src/test/mir-opt/issue_91633.fun.mir_map.0.mir b/src/test/mir-opt/issue_91633.fun.mir_map.0.mir
new file mode 100644
index 00000000000..ded9a4cf7e3
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.fun.mir_map.0.mir
@@ -0,0 +1,35 @@
+// MIR for `fun` 0 mir_map
+
+fn fun(_1: &[T]) -> &T {
+    debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
+    let mut _0: &T;                      // return place in scope 0 at $DIR/issue-91633.rs:+0:25: +0:27
+    let _2: &T;                          // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+    let _3: usize;                       // in scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
+    let mut _4: usize;                   // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+    let mut _5: bool;                    // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+    scope 1 {
+        debug f => _2;                   // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+        StorageLive(_3);                 // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
+        _3 = const 0_usize;              // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
+        _4 = Len((*_1));                 // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+        _5 = Lt(_3, _4);                 // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+    }
+
+    bb1: {
+        _2 = &(*_1)[_3];                 // scope 0 at $DIR/issue-91633.rs:+2:14: +2:20
+        FakeRead(ForLet(None), _2);      // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
+        _0 = &(*_2);                     // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
+        StorageDead(_3);                 // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+        StorageDead(_2);                 // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+        return;                          // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
+    }
+
+    bb2 (cleanup): {
+        resume;                          // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
+    }
+}
diff --git a/src/test/mir-opt/issue_91633.hey.mir_map.0.mir b/src/test/mir-opt/issue_91633.hey.mir_map.0.mir
new file mode 100644
index 00000000000..74f4a5a9761
--- /dev/null
+++ b/src/test/mir-opt/issue_91633.hey.mir_map.0.mir
@@ -0,0 +1,35 @@
+// MIR for `hey` 0 mir_map
+
+fn hey(_1: &[T]) -> () {
+    debug it => _1;                      // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
+    let mut _0: ();                      // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
+    let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
+    let _3: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
+    let mut _4: &[T];                    // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
+    scope 1 {
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
+        StorageLive(_3);                 // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
+        StorageLive(_4);                 // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
+        _4 = &(*_1);                     // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
+        _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
+                                         // mir::Constant
+                                         // + span: $DIR/issue-91633.rs:7:15: 7:20
+                                         // + literal: Const { ty: for<'r> fn(&'r [T], usize) -> &'r <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
+    }
+
+    bb1: {
+        StorageDead(_4);                 // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
+        _2 = &(*_3);                     // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
+        StorageDead(_2);                 // scope 0 at $DIR/issue-91633.rs:+4:20: +4:21
+        _0 = const ();                   // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
+        StorageDead(_3);                 // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+        return;                          // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
+    }
+
+    bb2 (cleanup): {
+        resume;                          // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
+    }
+}
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt
index 7ae0e978808..732de652627 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.doctest.txt
@@ -23,12 +23,6 @@
    22|      1|//! ```
    23|      2|//! #[derive(Debug, PartialEq)]
                        ^1
-  ------------------
-  | Unexecuted instantiation: <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::ne
-  ------------------
-  | <rust_out::main::_doctest_main____coverage_doctest_rs_22_0::SomeError as core::cmp::PartialEq>::eq:
-  |   23|      2|//! #[derive(Debug, PartialEq)]
-  ------------------
    24|      1|//! struct SomeError {
    25|      1|//!     msg: String,
    26|      1|//! }
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
index de32c88b725..25c74ab2e70 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
@@ -2,12 +2,6 @@
     2|       |
     3|      3|#[derive(Debug, PartialEq, Eq)]
                               ^2
-  ------------------
-  | <issue_83601::Foo as core::cmp::PartialEq>::eq:
-  |    3|      2|#[derive(Debug, PartialEq, Eq)]
-  ------------------
-  | Unexecuted instantiation: <issue_83601::Foo as core::cmp::PartialEq>::ne
-  ------------------
     4|       |struct Foo(u32);
     5|       |
     6|      1|fn main() {
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt b/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
index f24f7c69404..4a60432c14c 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
@@ -2,12 +2,6 @@
     2|       |
     3|       |// expect-exit-status-101
     4|     21|#[derive(PartialEq, Eq)]
-  ------------------
-  | <issue_84561::Foo as core::cmp::PartialEq>::eq:
-  |    4|     21|#[derive(PartialEq, Eq)]
-  ------------------
-  | Unexecuted instantiation: <issue_84561::Foo as core::cmp::PartialEq>::ne
-  ------------------
     5|       |struct Foo(u32);
     6|      1|fn test3() {
     7|      1|    let is_true = std::env::args().len() == 1;
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt b/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
index fc266653349..a77175af663 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
@@ -3,11 +3,6 @@
     3|       |
     4|      2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
                        ^0            ^0      ^0     ^1       ^1 ^0^0
-  ------------------
-  | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::ne
-  ------------------
-  | Unexecuted instantiation: <partial_eq::Version as core::cmp::PartialEq>::eq
-  ------------------
     5|       |pub struct Version {
     6|       |    major: usize,
     7|       |    minor: usize,
diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml
index 782526e29f4..71d514648ba 100644
--- a/src/test/rustdoc-gui/pocket-menu.goml
+++ b/src/test/rustdoc-gui/pocket-menu.goml
@@ -56,7 +56,7 @@ reload:
 click: "#help-button"
 assert-css: (
     "#help-button .popover",
-    {"display": "block", "border-color": "rgb(210, 210, 210)"},
+    {"display": "block", "border-color": "rgb(224, 224, 224)"},
 )
 compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
 compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml
index b12eddfd12a..35d7ca480ca 100644
--- a/src/test/rustdoc-gui/search-filter.goml
+++ b/src/test/rustdoc-gui/search-filter.goml
@@ -69,7 +69,7 @@ click: "#settings-menu"
 wait-for: "#settings"
 click: "#theme-dark"
 wait-for-css: ("#crate-search", {
-    "border": "1px solid rgb(210, 210, 210)",
+    "border": "1px solid rgb(224, 224, 224)",
     "color": "rgb(221, 221, 221)",
     "background-color": "rgb(53, 53, 53)",
 })
diff --git a/src/test/rustdoc-gui/search-form-elements.goml b/src/test/rustdoc-gui/search-form-elements.goml
new file mode 100644
index 00000000000..c35a86ccd1c
--- /dev/null
+++ b/src/test/rustdoc-gui/search-form-elements.goml
@@ -0,0 +1,243 @@
+// This test ensures that the elements in ".search-form" have the expected display.
+goto: file://|DOC_PATH|/test_docs/index.html
+show-text: true
+
+// Ayu theme
+local-storage: {
+    "rustdoc-theme": "ayu",
+    "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+    ".search-input",
+    {
+        "border-color": "rgb(92, 103, 115)",
+        "background-color": "rgb(20, 25, 32)",
+        "color": "rgb(255, 255, 255)",
+    },
+)
+focus: ".search-input"
+// Nothing should change.
+assert-css: (
+    ".search-input",
+    {
+        "border-color": "rgb(92, 103, 115)",
+        "background-color": "rgb(20, 25, 32)",
+        "color": "rgb(255, 255, 255)",
+    },
+)
+
+assert-css: (
+    "#help-button",
+    {"border-color": "rgb(197, 197, 197)"},
+)
+assert-css: (
+    "#help-button > button",
+    {
+        "color": "rgb(255, 255, 255)",
+        "border-color": "rgb(92, 103, 115)",
+        "background-color": "rgb(20, 25, 32)",
+    },
+)
+move-cursor-to: "#help-button"
+assert-css: (
+    "#help-button:hover",
+    {"border-color": "rgb(197, 197, 197)"},
+)
+// Only "border-color" should change.
+assert-css: (
+    "#help-button:hover > button",
+    {
+        "color": "rgb(255, 255, 255)",
+        "border-color": "rgb(224, 224, 224)",
+        "background-color": "rgb(20, 25, 32)",
+    },
+)
+
+assert-css: (
+    "#settings-menu",
+    {"border-color": "rgb(197, 197, 197)"},
+)
+assert-css: (
+    "#settings-menu > a",
+    {
+        "color": "rgb(255, 255, 255)",
+        "border-color": "rgb(92, 103, 115)",
+        "background-color": "rgb(20, 25, 32)",
+    },
+)
+move-cursor-to: "#settings-menu"
+assert-css: (
+    "#settings-menu:hover",
+    {"border-color": "rgb(197, 197, 197)"},
+)
+// Only "border-color" should change.
+assert-css: (
+    "#settings-menu:hover > a",
+    {
+        "color": "rgb(255, 255, 255)",
+        "border-color": "rgb(224, 224, 224)",
+        "background-color": "rgb(20, 25, 32)",
+    },
+)
+
+// Dark theme
+local-storage: {
+    "rustdoc-theme": "dark",
+    "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+    ".search-input",
+    {
+        "border-color": "rgb(240, 240, 240)",
+        "background-color": "rgb(240, 240, 240)",
+        "color": "rgb(17, 17, 17)",
+    },
+)
+focus: ".search-input"
+// Only "border-color" should change.
+assert-css: (
+    ".search-input",
+    {
+        "border-color": "rgb(0, 141, 253)",
+        "background-color": "rgb(240, 240, 240)",
+        "color": "rgb(17, 17, 17)",
+    },
+)
+
+assert-css: (
+    "#help-button",
+    {"border-color": "rgb(221, 221, 221)"},
+)
+assert-css: (
+    "#help-button > button",
+    {
+        "color": "rgb(0, 0, 0)",
+        "border-color": "rgb(224, 224, 224)",
+        "background-color": "rgb(240, 240, 240)",
+    },
+)
+move-cursor-to: "#help-button"
+assert-css: (
+    "#help-button:hover",
+    {"border-color": "rgb(221, 221, 221)"},
+)
+// Only "border-color" should change.
+assert-css: (
+    "#help-button:hover > button",
+    {
+        "color": "rgb(0, 0, 0)",
+        "border-color": "rgb(255, 185, 0)",
+        "background-color": "rgb(240, 240, 240)",
+    },
+)
+
+assert-css: (
+    "#settings-menu",
+    {"border-color": "rgb(221, 221, 221)"},
+)
+assert-css: (
+    "#settings-menu > a",
+    {
+        "color": "rgb(0, 0, 0)",
+        "border-color": "rgb(224, 224, 224)",
+        "background-color": "rgb(240, 240, 240)",
+    },
+)
+move-cursor-to: "#settings-menu"
+assert-css: (
+    "#settings-menu:hover",
+    {"border-color": "rgb(221, 221, 221)"},
+)
+// Only "border-color" should change.
+assert-css: (
+    "#settings-menu:hover > a",
+    {
+        "color": "rgb(0, 0, 0)",
+        "border-color": "rgb(255, 185, 0)",
+        "background-color": "rgb(240, 240, 240)",
+    },
+)
+
+// Light theme
+local-storage: {
+    "rustdoc-theme": "light",
+    "rustdoc-use-system-theme": "false",
+}
+reload:
+
+assert-css: (
+    ".search-input",
+    {
+        "border-color": "rgb(224, 224, 224)",
+        "background-color": "rgb(255, 255, 255)",
+        "color": "rgb(0, 0, 0)",
+    },
+)
+focus: ".search-input"
+// Nothing should change.
+assert-css: (
+    ".search-input",
+    {
+        "border-color": "rgb(102, 175, 233)",
+        "background-color": "rgb(255, 255, 255)",
+        "color": "rgb(0, 0, 0)",
+    },
+)
+
+assert-css: (
+    "#help-button",
+    {"border-color": "rgb(0, 0, 0)"},
+)
+assert-css: (
+    "#help-button > button",
+    {
+        "color": "rgb(0, 0, 0)",
+        "border-color": "rgb(224, 224, 224)",
+        "background-color": "rgb(255, 255, 255)",
+    },
+)
+move-cursor-to: "#help-button"
+assert-css: (
+    "#help-button:hover",
+    {"border-color": "rgb(0, 0, 0)"},
+)
+// Only "border-color" should change.
+assert-css: (
+    "#help-button:hover > button",
+    {
+        "color": "rgb(0, 0, 0)",
+        "border-color": "rgb(113, 113, 113)",
+        "background-color": "rgb(255, 255, 255)",
+    },
+)
+
+assert-css: (
+    "#settings-menu",
+    {"border-color": "rgb(0, 0, 0)"},
+)
+assert-css: (
+    "#settings-menu > a",
+    {
+        "color": "rgb(56, 115, 173)",
+        "border-color": "rgb(224, 224, 224)",
+        "background-color": "rgb(255, 255, 255)",
+    },
+)
+move-cursor-to: "#settings-menu"
+assert-css: (
+    "#settings-menu:hover",
+    {"border-color": "rgb(0, 0, 0)"},
+)
+// Only "border-color" should change.
+assert-css: (
+    "#settings-menu:hover > a",
+    {
+        "color": "rgb(56, 115, 173)",
+        "border-color": "rgb(113, 113, 113)",
+        "background-color": "rgb(255, 255, 255)",
+    },
+)
diff --git a/src/test/rustdoc-gui/search-input.goml b/src/test/rustdoc-gui/search-input.goml
index 44123b702df..6903e1a1bf5 100644
--- a/src/test/rustdoc-gui/search-input.goml
+++ b/src/test/rustdoc-gui/search-input.goml
@@ -3,9 +3,8 @@ goto: file://|DOC_PATH|/test_docs/index.html
 local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
 reload:
 
-assert-css: (".search-input", {"border-color": "rgb(224, 224, 224)"})
+assert-css: (".search-input", {"border-color": "rgb(240, 240, 240)"})
 click: ".search-input"
-focus: ".search-input"
 assert-css: (".search-input", {"border-color": "rgb(0, 141, 253)"})
 
 local-storage: {"rustdoc-theme": "light"}
@@ -18,6 +17,6 @@ assert-css: (".search-input", {"border-color": "rgb(102, 175, 233)"})
 local-storage: {"rustdoc-theme": "ayu"}
 reload:
 
-assert-css: (".search-input", {"border-color": "rgb(66, 76, 87)"})
+assert-css: (".search-input", {"border-color": "rgb(92, 103, 115)"})
 click: ".search-input"
-assert-css: (".search-input", {"border-color": "rgb(66, 76, 87)"})
+assert-css: (".search-input", {"border-color": "rgb(92, 103, 115)"})
diff --git a/src/test/rustdoc-json/nested.rs b/src/test/rustdoc-json/nested.rs
index b0e717d8a86..9ff1f60c0d5 100644
--- a/src/test/rustdoc-json/nested.rs
+++ b/src/test/rustdoc-json/nested.rs
@@ -4,27 +4,28 @@
 // @is nested.json "$.crate_version" \"1.0.0\"
 // @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
 // @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
-// @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1
+
+// @set l1_id = - "$.index[*][?(@.name=='l1')].id"
+// @ismany - "$.index[*][?(@.name=='nested')].inner.items[*]" $l1_id
 
 // @is nested.json "$.index[*][?(@.name=='l1')].kind" \"module\"
 // @is - "$.index[*][?(@.name=='l1')].inner.is_crate" false
-// @count - "$.index[*][?(@.name=='l1')].inner.items[*]" 2
 pub mod l1 {
-
     // @is nested.json "$.index[*][?(@.name=='l3')].kind" \"module\"
     // @is - "$.index[*][?(@.name=='l3')].inner.is_crate" false
-    // @count - "$.index[*][?(@.name=='l3')].inner.items[*]" 1
     // @set l3_id = - "$.index[*][?(@.name=='l3')].id"
-    // @has - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id
     pub mod l3 {
 
         // @is nested.json "$.index[*][?(@.name=='L4')].kind" \"struct\"
         // @is - "$.index[*][?(@.name=='L4')].inner.struct_type" \"unit\"
         // @set l4_id = - "$.index[*][?(@.name=='L4')].id"
-        // @has - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
+        // @ismany - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
         pub struct L4;
     }
     // @is nested.json "$.index[*][?(@.inner.source=='l3::L4')].kind" \"import\"
     // @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.glob" false
+    // @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.id" $l4_id
+    // @set l4_use_id = - "$.index[*][?(@.inner.source=='l3::L4')].id"
     pub use l3::L4;
 }
+// @ismany - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id $l4_use_id
diff --git a/src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs b/src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs
new file mode 100644
index 00000000000..fda38056a09
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/export_extern_crate_as_self.rs
@@ -0,0 +1,11 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/100531>
+
+#![feature(no_core)]
+#![no_core]
+
+#![crate_name = "export_extern_crate_as_self"]
+
+// ignore-tidy-linelength
+
+// @is export_extern_crate_as_self.json "$.index[*][?(@.kind=='module')].name" \"export_extern_crate_as_self\"
+pub extern crate self as export_extern_crate_as_self; // Must be the same name as the crate already has
diff --git a/src/test/rustdoc-json/reexport/glob_extern.rs b/src/test/rustdoc-json/reexport/glob_extern.rs
index ba1cfd8a0b5..4fe25904423 100644
--- a/src/test/rustdoc-json/reexport/glob_extern.rs
+++ b/src/test/rustdoc-json/reexport/glob_extern.rs
@@ -4,15 +4,20 @@
 #![feature(no_core)]
 
 // @is glob_extern.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
-// @is glob_extern.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+// @is - "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
 mod mod1 {
     extern "C" {
-        // @has - "$.index[*][?(@.name=='public_fn')].id"
+        // @set public_fn_id = - "$.index[*][?(@.name=='public_fn')].id"
         pub fn public_fn();
         // @!has - "$.index[*][?(@.name=='private_fn')]"
         fn private_fn();
     }
+    // @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $public_fn_id
+    // @set mod1_id = - "$.index[*][?(@.name=='mod1')].id"
 }
 
 // @is - "$.index[*][?(@.kind=='import')].inner.glob" true
+// @is - "$.index[*][?(@.kind=='import')].inner.id" $mod1_id
+// @set use_id = - "$.index[*][?(@.kind=='import')].id"
+// @ismany - "$.index[*][?(@.name=='glob_extern')].inner.items[*]" $use_id
 pub use mod1::*;
diff --git a/src/test/rustdoc-json/reexport/glob_private.rs b/src/test/rustdoc-json/reexport/glob_private.rs
index e6a44748c25..04460a817f1 100644
--- a/src/test/rustdoc-json/reexport/glob_private.rs
+++ b/src/test/rustdoc-json/reexport/glob_private.rs
@@ -16,7 +16,7 @@ mod mod1 {
         struct Mod2Private;
     }
 
-    // @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')]"
+    // @set mod2_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')].id"
     pub use self::mod2::*;
 
     // @set m1pub_id = - "$.index[*][?(@.name=='Mod1Public')].id"
@@ -25,8 +25,9 @@ mod mod1 {
     struct Mod1Private;
 }
 
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')]"
+// @set mod1_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')].id"
 pub use mod1::*;
 
-// @has - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
-// @has - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id
+// @ismany - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
+// @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id $mod2_use_id
+// @ismany - "$.index[*][?(@.name=='glob_private')].inner.items[*]" $mod1_use_id
diff --git a/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs b/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
index 2daadf7620c..09302ee3acb 100644
--- a/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
+++ b/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
@@ -3,7 +3,7 @@
 
 pub mod foo {
     // @set bar_id = in_root_and_mod_pub.json "$.index[*][?(@.name=='Bar')].id"
-    // @has - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
+    // @ismany - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
     pub struct Bar;
 }
 
@@ -15,6 +15,6 @@ pub use foo::Bar;
 pub mod baz {
     // @set baz_import_id = - "$.index[*][?(@.inner.source=='crate::foo::Bar')].id"
     // @is - "$.index[*][?(@.inner.source=='crate::foo::Bar')].inner.id" $bar_id
-    // @has - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
+    // @ismany - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
     pub use crate::foo::Bar;
 }
diff --git a/src/test/rustdoc-json/reexport/macro.rs b/src/test/rustdoc-json/reexport/macro.rs
index b86614ffbad..0959736f309 100644
--- a/src/test/rustdoc-json/reexport/macro.rs
+++ b/src/test/rustdoc-json/reexport/macro.rs
@@ -3,15 +3,13 @@
 #![no_core]
 #![feature(no_core)]
 
-// @count macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" 2
-
 // @set repro_id = macro.json "$.index[*][?(@.name=='repro')].id"
-// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id
 #[macro_export]
 macro_rules! repro {
     () => {};
 }
 
 // @set repro2_id = macro.json "$.index[*][?(@.inner.name=='repro2')].id"
-// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro2_id
 pub use crate::repro as repro2;
+
+// @ismany macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id $repro2_id
diff --git a/src/test/rustdoc-json/reexport/private_twice_one_inline.rs b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
index 327b0f45fdd..a76d352b28b 100644
--- a/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
+++ b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
@@ -1,18 +1,28 @@
 // aux-build:pub-struct.rs
+// ignore-tidy-linelength
 
-// Test for the ICE in rust/83057
-// Am external type re-exported with different attributes shouldn't cause an error
+// Test for the ICE in https://github.com/rust-lang/rust/issues/83057
+// An external type re-exported with different attributes shouldn't cause an error
 
 #![no_core]
 #![feature(no_core)]
 
 extern crate pub_struct as foo;
-
 #[doc(inline)]
+
+// @set crate_use_id = private_twice_one_inline.json "$.index[*][?(@.docs=='Hack A')].id"
+// @set foo_id = - "$.index[*][?(@.docs=='Hack A')].inner.id"
+/// Hack A
 pub use foo::Foo;
 
+// @set bar_id = - "$.index[*][?(@.name=='bar')].id"
 pub mod bar {
+    // @is - "$.index[*][?(@.docs=='Hack B')].inner.id" $foo_id
+    // @set bar_use_id = - "$.index[*][?(@.docs=='Hack B')].id"
+    // @ismany - "$.index[*][?(@.name=='bar')].inner.items[*]" $bar_use_id
+    /// Hack B
     pub use foo::Foo;
 }
 
-// @count private_twice_one_inline.json "$.index[*][?(@.kind=='import')]" 2
+// @ismany - "$.index[*][?(@.kind=='import')].id" $crate_use_id $bar_use_id
+// @ismany - "$.index[*][?(@.name=='private_twice_one_inline')].inner.items[*]" $bar_id $crate_use_id
diff --git a/src/test/rustdoc-json/reexport/private_two_names.rs b/src/test/rustdoc-json/reexport/private_two_names.rs
index 36d6a50d385..cd8212cf344 100644
--- a/src/test/rustdoc-json/reexport/private_two_names.rs
+++ b/src/test/rustdoc-json/reexport/private_two_names.rs
@@ -1,4 +1,6 @@
-// Test for the ICE in rust/83720
+// ignore-tidy-linelength
+
+// Test for the ICE in https://github.com/rust-lang/rust/issues/83720
 // A pub-in-private type re-exported under two different names shouldn't cause an error
 
 #![no_core]
@@ -7,11 +9,15 @@
 // @is private_two_names.json "$.index[*][?(@.name=='style')].kind" \"module\"
 // @is private_two_names.json "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
 mod style {
-    // @has - "$.index[*](?(@.name=='Color'))"
+    // @set color_struct_id = - "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
     pub struct Color;
 }
 
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')]"
+// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].inner.id" $color_struct_id
+// @set color_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].id"
 pub use style::Color;
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')]"
+// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].inner.id" $color_struct_id
+// @set colour_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].id"
 pub use style::Color as Colour;
+
+// @ismany - "$.index[*][?(@.name=='private_two_names')].inner.items[*]" $color_export_id $colour_export_id
diff --git a/src/test/rustdoc-json/reexport/rename_public.rs b/src/test/rustdoc-json/reexport/rename_public.rs
index 2dd438d2230..d41556974b4 100644
--- a/src/test/rustdoc-json/reexport/rename_public.rs
+++ b/src/test/rustdoc-json/reexport/rename_public.rs
@@ -4,14 +4,14 @@
 #![feature(no_core)]
 
 // @set inner_id = rename_public.json "$.index[*][?(@.name=='inner')].id"
-// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id
 pub mod inner {
     // @set public_id = - "$.index[*][?(@.name=='Public')].id"
-    // @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+    // @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
     pub struct Public;
 }
 // @set import_id = - "$.index[*][?(@.inner.name=='NewName')].id"
 // @!has - "$.index[*][?(@.inner.name=='Public')]"
-// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $import_id
 // @is - "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
 pub use inner::Public as NewName;
+
+// @ismany - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id $import_id
diff --git a/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs b/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
index eedddd6a7bb..1d76c7e139b 100644
--- a/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
+++ b/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-linelength
+
 // Regression test for <https://github.com/rust-lang/rust/issues/97432>.
 
 #![feature(no_core)]
@@ -5,11 +7,17 @@
 #![no_core]
 
 // @has same_type_reexported_more_than_once.json
-// @has - "$.index[*][?(@.name=='Trait')]"
-pub use inner::Trait;
-// @has - "$.index[*].inner[?(@.name=='Reexport')].id"
-pub use inner::Trait as Reexport;
 
 mod inner {
+    // @set trait_id = - "$.index[*][?(@.name=='Trait')].id"
     pub trait Trait {}
 }
+
+// @set export_id = - "$.index[*][?(@.inner.name=='Trait')].id"
+// @is - "$.index[*][?(@.inner.name=='Trait')].inner.id" $trait_id
+pub use inner::Trait;
+// @set reexport_id = - "$.index[*][?(@.inner.name=='Reexport')].id"
+// @is - "$.index[*][?(@.inner.name=='Reexport')].inner.id" $trait_id
+pub use inner::Trait as Reexport;
+
+// @ismany - "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.items[*]" $reexport_id $export_id
diff --git a/src/test/rustdoc-json/reexport/simple_private.rs b/src/test/rustdoc-json/reexport/simple_private.rs
index 5ec13e403ae..55523bcd1de 100644
--- a/src/test/rustdoc-json/reexport/simple_private.rs
+++ b/src/test/rustdoc-json/reexport/simple_private.rs
@@ -10,6 +10,8 @@ mod inner {
 }
 
 // @is - "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
+// @set use_id = - "$.index[*][?(@.kind=='import')].id"
 pub use inner::Public;
 
-// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
+// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
+// @ismany - "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id
diff --git a/src/test/rustdoc-json/reexport/simple_public.rs b/src/test/rustdoc-json/reexport/simple_public.rs
index 2e4de301f6f..a3156a2b33a 100644
--- a/src/test/rustdoc-json/reexport/simple_public.rs
+++ b/src/test/rustdoc-json/reexport/simple_public.rs
@@ -4,15 +4,15 @@
 #![feature(no_core)]
 
 // @set inner_id = simple_public.json "$.index[*][?(@.name=='inner')].id"
-// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $inner_id
 pub mod inner {
 
     // @set public_id = - "$.index[*][?(@.name=='Public')].id"
-    // @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+    // @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
     pub struct Public;
 }
 
 // @set import_id = - "$.index[*][?(@.inner.name=='Public')].id"
-// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id
 // @is - "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
 pub use inner::Public;
+
+// @ismany - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id $inner_id
diff --git a/src/test/rustdoc-json/type/fn_lifetime.rs b/src/test/rustdoc-json/type/fn_lifetime.rs
index e0d1e9649a0..fd49a0890c0 100644
--- a/src/test/rustdoc-json/type/fn_lifetime.rs
+++ b/src/test/rustdoc-json/type/fn_lifetime.rs
@@ -2,8 +2,7 @@
 
 // @is fn_lifetime.json "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
 
-// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*]" 1
-// @is    - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
+// @ismany    - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
 // @has   - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
 // @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
 // @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0
diff --git a/src/test/rustdoc/issue-100679-sidebar-links-deref.rs b/src/test/rustdoc/issue-100679-sidebar-links-deref.rs
new file mode 100644
index 00000000000..f09d2320609
--- /dev/null
+++ b/src/test/rustdoc/issue-100679-sidebar-links-deref.rs
@@ -0,0 +1,30 @@
+#![crate_name="foo"]
+
+pub struct Vec;
+
+pub struct Slice;
+
+impl std::ops::Deref for Vec {
+    type Target = Slice;
+    fn deref(&self) -> &Slice {
+        &Slice
+    }
+}
+
+// @has foo/struct.Vec.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.is_empty"]' \
+//          "is_empty"
+impl Vec {
+    pub fn is_empty(&self) -> bool {
+        true
+    }
+}
+
+// @has foo/struct.Vec.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.is_empty-1"]' \
+//          "is_empty"
+// @has foo/struct.Slice.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.is_empty"]' \
+//          "is_empty"
+impl Slice {
+    pub fn is_empty(&self) -> bool {
+        true
+    }
+}
diff --git a/src/test/rustdoc/issue-32374.rs b/src/test/rustdoc/issue-32374.rs
index 9c585497d35..8d2c27cf3d7 100644
--- a/src/test/rustdoc/issue-32374.rs
+++ b/src/test/rustdoc/issue-32374.rs
@@ -8,20 +8,24 @@
 //      'Experimental'
 // @matches issue_32374/index.html '//*[@class="item-right docblock-short"]/text()' 'Docs'
 
-// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]' \
-//      '👎 Deprecated since 1.0.0: text'
+// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]/span' '👎'
+// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]/span' \
+//      'Deprecated since 1.0.0: text'
 // @hasraw - '<code>test</code>&nbsp;<a href="https://issue_url/32374">#32374</a>'
+// @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' '🔬'
 // @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' \
-//      '🔬 This is a nightly-only experimental API. \(test\s#32374\)$'
+//     'This is a nightly-only experimental API. \(test\s#32374\)$'
 /// Docs
 #[deprecated(since = "1.0.0", note = "text")]
 #[unstable(feature = "test", issue = "32374")]
 pub struct T;
 
+// @has issue_32374/struct.U.html '//*[@class="stab deprecated"]' '👎'
 // @has issue_32374/struct.U.html '//*[@class="stab deprecated"]' \
-//      '👎 Deprecated since 1.0.0: deprecated'
+//     'Deprecated since 1.0.0: deprecated'
+// @has issue_32374/struct.U.html '//*[@class="stab unstable"]' '🔬'
 // @has issue_32374/struct.U.html '//*[@class="stab unstable"]' \
-//      '🔬 This is a nightly-only experimental API. (test #32374)'
+//     'This is a nightly-only experimental API. (test #32374)'
 #[deprecated(since = "1.0.0", note = "deprecated")]
 #[unstable(feature = "test", issue = "32374", reason = "unstable")]
 pub struct U;
diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
index d6f63d44ba6..33192433bbf 100644
--- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
@@ -16,7 +16,7 @@ use rustc_session::{parse::ParseSess, SessionDiagnostic};
 use rustc_span::Span;
 
 #[derive(SessionDiagnostic)]
-#[error(parser::expect_path)]
+#[diag(parser::expect_path)]
 struct DeriveSessionDiagnostic {
     #[primary_span]
     span: Span,
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index 0a210cbdc94..aaa8caa64f3 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -28,15 +28,15 @@ use rustc_errors::{Applicability, MultiSpan};
 extern crate rustc_session;
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct Hello {}
 
 #[derive(SessionDiagnostic)]
-#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct HelloWarn {}
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 //~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs
 enum SessionDiagnosticOnEnum {
     Foo,
@@ -44,54 +44,54 @@ enum SessionDiagnosticOnEnum {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[error = "E0123"]
-//~^ ERROR `#[error = ...]` is not a valid attribute
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag = "E0123"]
+//~^ ERROR `#[diag = ...]` is not a valid attribute
 struct WrongStructAttrStyle {}
 
 #[derive(SessionDiagnostic)]
 #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
 //~^ ERROR `#[nonsense(...)]` is not a valid attribute
-//~^^ ERROR diagnostic kind not specified
+//~^^ ERROR diagnostic slug not specified
 //~^^^ ERROR cannot find attribute `nonsense` in this scope
 struct InvalidStructAttr {}
 
 #[derive(SessionDiagnostic)]
-#[error("E0123")]
-//~^ ERROR `#[error("...")]` is not a valid attribute
+#[diag("E0123")]
+//~^ ERROR `#[diag("...")]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 struct InvalidLitNestedAttr {}
 
 #[derive(SessionDiagnostic)]
-#[error(nonsense, code = "E0123")]
+#[diag(nonsense, code = "E0123")]
 //~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent`
 struct InvalidNestedStructAttr {}
 
 #[derive(SessionDiagnostic)]
-#[error(nonsense("foo"), code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(nonsense(...))]` is not a valid attribute
+#[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense(...))]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr1 {}
 
 #[derive(SessionDiagnostic)]
-#[error(nonsense = "...", code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute
+#[diag(nonsense = "...", code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr2 {}
 
 #[derive(SessionDiagnostic)]
-#[error(nonsense = 4, code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute
+#[diag(nonsense = 4, code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(nonsense = ...)]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr3 {}
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
-//~^ ERROR `#[error(slug = ...)]` is not a valid attribute
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
+//~^ ERROR `#[diag(slug = ...)]` is not a valid attribute
 struct InvalidNestedStructAttr4 {}
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct WrongPlaceField {
     #[suggestion = "bar"]
     //~^ ERROR `#[suggestion = ...]` is not a valid attribute
@@ -99,45 +99,36 @@ struct WrongPlaceField {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
 //~^ ERROR specified multiple times
 //~^^ ERROR specified multiple times
-//~^^^ ERROR specified multiple times
-struct ErrorSpecifiedTwice {}
+struct DiagSpecifiedTwice {}
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
-//~^ ERROR specified multiple times
-//~^^ ERROR specified multiple times
-//~^^^ ERROR specified multiple times
-struct WarnSpecifiedAfterError {}
-
-#[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
 //~^ ERROR specified multiple times
 struct CodeSpecifiedTwice {}
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
-//~^ ERROR `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
+#[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
+//~^ ERROR `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
 struct SlugSpecifiedTwice {}
 
 #[derive(SessionDiagnostic)]
-struct KindNotProvided {} //~ ERROR diagnostic kind not specified
+struct KindNotProvided {} //~ ERROR diagnostic slug not specified
 
 #[derive(SessionDiagnostic)]
-#[error(code = "E0456")]
+#[diag(code = "E0456")]
 //~^ ERROR diagnostic slug not specified
 struct SlugNotProvided {}
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound)]
+#[diag(typeck::ambiguous_lifetime_bound)]
 struct CodeNotProvided {}
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct MessageWrongType {
     #[primary_span]
     //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -145,7 +136,7 @@ struct MessageWrongType {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct InvalidPathFieldAttr {
     #[nonsense]
     //~^ ERROR `#[nonsense]` is not a valid attribute
@@ -154,7 +145,7 @@ struct InvalidPathFieldAttr {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithField {
     name: String,
     #[label(typeck::label)]
@@ -162,7 +153,7 @@ struct ErrorWithField {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithMessageAppliedToField {
     #[label(typeck::label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -170,7 +161,7 @@ struct ErrorWithMessageAppliedToField {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithNonexistentField {
     #[suggestion(typeck::suggestion, code = "{name}")]
     //~^ ERROR `name` doesn't refer to a field on this type
@@ -179,7 +170,7 @@ struct ErrorWithNonexistentField {
 
 #[derive(SessionDiagnostic)]
 //~^ ERROR invalid format string: expected `'}'`
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorMissingClosingBrace {
     #[suggestion(typeck::suggestion, code = "{name")]
     suggestion: (Span, Applicability),
@@ -189,7 +180,7 @@ struct ErrorMissingClosingBrace {
 
 #[derive(SessionDiagnostic)]
 //~^ ERROR invalid format string: unmatched `}`
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorMissingOpeningBrace {
     #[suggestion(typeck::suggestion, code = "name}")]
     suggestion: (Span, Applicability),
@@ -198,14 +189,14 @@ struct ErrorMissingOpeningBrace {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct LabelOnSpan {
     #[label(typeck::label)]
     sp: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct LabelOnNonSpan {
     #[label(typeck::label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -213,7 +204,7 @@ struct LabelOnNonSpan {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct Suggest {
     #[suggestion(typeck::suggestion, code = "This is the suggested code")]
     #[suggestion_short(typeck::suggestion, code = "This is the suggested code")]
@@ -223,14 +214,14 @@ struct Suggest {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithoutCode {
     #[suggestion(typeck::suggestion)]
     suggestion: (Span, Applicability),
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithBadKey {
     #[suggestion(nonsense = "bar")]
     //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute
@@ -238,7 +229,7 @@ struct SuggestWithBadKey {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithShorthandMsg {
     #[suggestion(msg = "bar")]
     //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute
@@ -246,21 +237,21 @@ struct SuggestWithShorthandMsg {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithoutMsg {
     #[suggestion(code = "bar")]
     suggestion: (Span, Applicability),
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithTypesSwapped {
     #[suggestion(typeck::suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Span),
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithWrongTypeApplicabilityOnly {
     #[suggestion(typeck::suggestion, code = "This is suggested code")]
     //~^ ERROR wrong field type for suggestion
@@ -268,14 +259,14 @@ struct SuggestWithWrongTypeApplicabilityOnly {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithSpanOnly {
     #[suggestion(typeck::suggestion, code = "This is suggested code")]
     suggestion: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithDuplicateSpanAndApplicability {
     #[suggestion(typeck::suggestion, code = "This is suggested code")]
     //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one `Span`
@@ -283,7 +274,7 @@ struct SuggestWithDuplicateSpanAndApplicability {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct SuggestWithDuplicateApplicabilityAndSpan {
     #[suggestion(typeck::suggestion, code = "This is suggested code")]
     //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one
@@ -291,7 +282,7 @@ struct SuggestWithDuplicateApplicabilityAndSpan {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct WrongKindOfAnnotation {
     #[label = "bar"]
     //~^ ERROR `#[label = ...]` is not a valid attribute
@@ -299,7 +290,7 @@ struct WrongKindOfAnnotation {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct OptionsInErrors {
     #[label(typeck::label)]
     label: Option<Span>,
@@ -308,7 +299,7 @@ struct OptionsInErrors {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
 struct MoveOutOfBorrowError<'tcx> {
     name: Ident,
     ty: Ty<'tcx>,
@@ -322,7 +313,7 @@ struct MoveOutOfBorrowError<'tcx> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithLifetime<'a> {
     #[label(typeck::label)]
     span: Span,
@@ -330,7 +321,7 @@ struct ErrorWithLifetime<'a> {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithDefaultLabelAttr<'a> {
     #[label]
     span: Span,
@@ -339,7 +330,7 @@ struct ErrorWithDefaultLabelAttr<'a> {
 
 #[derive(SessionDiagnostic)]
 //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ArgFieldWithoutSkip {
     #[primary_span]
     span: Span,
@@ -347,7 +338,7 @@ struct ArgFieldWithoutSkip {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ArgFieldWithSkip {
     #[primary_span]
     span: Span,
@@ -358,56 +349,56 @@ struct ArgFieldWithSkip {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithSpannedNote {
     #[note]
     span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithSpannedNoteCustom {
     #[note(typeck::note)]
     span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 #[note]
 struct ErrorWithNote {
     val: String,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 #[note(typeck::note)]
 struct ErrorWithNoteCustom {
     val: String,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithSpannedHelp {
     #[help]
     span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithSpannedHelpCustom {
     #[help(typeck::help)]
     span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 #[help]
 struct ErrorWithHelp {
     val: String,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 #[help(typeck::help)]
 struct ErrorWithHelpCustom {
     val: String,
@@ -415,34 +406,34 @@ struct ErrorWithHelpCustom {
 
 #[derive(SessionDiagnostic)]
 #[help]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithHelpWrongOrder {
     val: String,
 }
 
 #[derive(SessionDiagnostic)]
 #[help(typeck::help)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithHelpCustomWrongOrder {
     val: String,
 }
 
 #[derive(SessionDiagnostic)]
 #[note]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithNoteWrongOrder {
     val: String,
 }
 
 #[derive(SessionDiagnostic)]
 #[note(typeck::note)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithNoteCustomWrongOrder {
     val: String,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ApplicabilityInBoth {
     #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
     //~^ ERROR applicability cannot be set in both the field and attribute
@@ -450,7 +441,7 @@ struct ApplicabilityInBoth {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct InvalidApplicability {
     #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
     //~^ ERROR invalid applicability
@@ -458,14 +449,14 @@ struct InvalidApplicability {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ValidApplicability {
     #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
     suggestion: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct NoApplicability {
     #[suggestion(typeck::suggestion, code = "...")]
     suggestion: Span,
@@ -476,14 +467,14 @@ struct NoApplicability {
 struct Note;
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound)]
+#[diag(typeck::ambiguous_lifetime_bound)]
 struct Subdiagnostic {
     #[subdiagnostic]
     note: Note,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct VecField {
     #[primary_span]
     #[label]
@@ -491,7 +482,7 @@ struct VecField {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct UnitField {
     #[primary_span]
     spans: Span,
@@ -502,7 +493,7 @@ struct UnitField {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct OptUnitField {
     #[primary_span]
     spans: Span,
@@ -513,7 +504,7 @@ struct OptUnitField {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct LabelWithTrailingPath {
     #[label(typeck::label, foo)]
     //~^ ERROR `#[label(...)]` is not a valid attribute
@@ -521,7 +512,7 @@ struct LabelWithTrailingPath {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct LabelWithTrailingNameValue {
     #[label(typeck::label, foo = "...")]
     //~^ ERROR `#[label(...)]` is not a valid attribute
@@ -529,40 +520,64 @@ struct LabelWithTrailingNameValue {
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct LabelWithTrailingList {
     #[label(typeck::label, foo("..."))]
     //~^ ERROR `#[label(...)]` is not a valid attribute
     span: Span,
 }
 
-#[derive(SessionDiagnostic)]
-#[lint(typeck::ambiguous_lifetime_bound)]
-//~^ ERROR only `#[error(..)]` and `#[warning(..)]` are supported
-struct LintsBad {
-}
-
 #[derive(LintDiagnostic)]
-#[lint(typeck::ambiguous_lifetime_bound)]
+#[diag(typeck::ambiguous_lifetime_bound)]
 struct LintsGood {
 }
 
 #[derive(LintDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound)]
-//~^ ERROR only `#[lint(..)]` is supported
-struct ErrorsBad {
+#[diag(typeck::ambiguous_lifetime_bound)]
+struct PrimarySpanOnLint {
+    #[primary_span]
+    //~^ ERROR `#[primary_span]` is not a valid attribute
+    span: Span,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 struct ErrorWithMultiSpan {
     #[primary_span]
     span: MultiSpan,
 }
 
 #[derive(SessionDiagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 #[warn_]
 struct ErrorWithWarn {
     val: String,
 }
+
+#[derive(SessionDiagnostic)]
+#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[error(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `error` in this scope
+struct ErrorAttribute {}
+
+#[derive(SessionDiagnostic)]
+#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[warning(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `warning` in this scope
+struct WarningAttribute {}
+
+#[derive(SessionDiagnostic)]
+#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `lint` in this scope
+struct LintAttributeOnSessionDiag {}
+
+#[derive(LintDiagnostic)]
+#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+//~^ ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR diagnostic slug not specified
+//~| ERROR cannot find attribute `lint` in this scope
+struct LintAttributeOnLintDiag {}
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index c1080aa2452..866b1a1de99 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -1,7 +1,7 @@
 error: `#[derive(SessionDiagnostic)]` can only be used on structs
   --> $DIR/diagnostic-derive.rs:39:1
    |
-LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | / #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
 LL | |
 LL | | enum SessionDiagnosticOnEnum {
 LL | |     Foo,
@@ -9,11 +9,11 @@ LL | |     Bar,
 LL | | }
    | |_^
 
-error: `#[error = ...]` is not a valid attribute
+error: `#[diag = ...]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:48:1
    |
-LL | #[error = "E0123"]
-   | ^^^^^^^^^^^^^^^^^^
+LL | #[diag = "E0123"]
+   | ^^^^^^^^^^^^^^^^^
 
 error: `#[nonsense(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:53:1
@@ -21,9 +21,9 @@ error: `#[nonsense(...)]` is not a valid attribute
 LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: only `error`, `warning`, `help`, `note` and `warn_` are valid attributes
+   = help: only `diag`, `help`, `note` and `warn_` are valid attributes
 
-error: diagnostic kind not specified
+error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:53:1
    |
 LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
@@ -33,89 +33,89 @@ LL | |
 LL | | struct InvalidStructAttr {}
    | |___________________________^
    |
-   = help: use the `#[error(...)]` attribute to create an error
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
 
-error: `#[error("...")]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:60:9
+error: `#[diag("...")]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:60:8
    |
-LL | #[error("E0123")]
-   |         ^^^^^^^
+LL | #[diag("E0123")]
+   |        ^^^^^^^
    |
    = help: first argument of the attribute should be the diagnostic slug
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:60:1
    |
-LL | / #[error("E0123")]
+LL | / #[diag("E0123")]
 LL | |
 LL | |
 LL | | struct InvalidLitNestedAttr {}
    | |______________________________^
    |
-   = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
 
-error: `#[error(nonsense(...))]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:71:9
+error: `#[diag(nonsense(...))]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:71:8
    |
-LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")]
-   |         ^^^^^^^^^^^^^^^
+LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+   |        ^^^^^^^^^^^^^^^
    |
    = help: first argument of the attribute should be the diagnostic slug
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:71:1
    |
-LL | / #[error(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr1 {}
    | |__________________________________^
    |
-   = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
 
-error: `#[error(nonsense = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:77:9
+error: `#[diag(nonsense = ...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:77:8
    |
-LL | #[error(nonsense = "...", code = "E0123", slug = "foo")]
-   |         ^^^^^^^^^^^^^^^^
+LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: first argument of the attribute should be the diagnostic slug
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:77:1
    |
-LL | / #[error(nonsense = "...", code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr2 {}
    | |__________________________________^
    |
-   = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
 
-error: `#[error(nonsense = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:83:9
+error: `#[diag(nonsense = ...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:83:8
    |
-LL | #[error(nonsense = 4, code = "E0123", slug = "foo")]
-   |         ^^^^^^^^^^^^
+LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+   |        ^^^^^^^^^^^^
    |
    = help: first argument of the attribute should be the diagnostic slug
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:83:1
    |
-LL | / #[error(nonsense = 4, code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr3 {}
    | |__________________________________^
    |
-   = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
 
-error: `#[error(slug = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:89:59
+error: `#[diag(slug = ...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:89:58
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
-   |                                                           ^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
+   |                                                          ^^^^^^^^^^^^
    |
    = help: only `code` is a valid nested attributes following the slug
 
@@ -128,119 +128,71 @@ LL |     #[suggestion = "bar"]
 error: specified multiple times
   --> $DIR/diagnostic-derive.rs:103:1
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: previously specified here
   --> $DIR/diagnostic-derive.rs:102:1
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:103:1
+  --> $DIR/diagnostic-derive.rs:103:49
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
+   |                                                 ^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:102:1
+  --> $DIR/diagnostic-derive.rs:102:49
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   |                                                 ^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:103:50
+  --> $DIR/diagnostic-derive.rs:109:65
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")]
-   |                                                  ^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+   |                                                                 ^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:102:50
+  --> $DIR/diagnostic-derive.rs:109:49
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   |                                                  ^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+   |                                                 ^^^^^^^
 
-error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:111:1
+error: `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:114:42
    |
-LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: previously specified here
-  --> $DIR/diagnostic-derive.rs:110:1
-   |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:111:1
-   |
-LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: previously specified here
-  --> $DIR/diagnostic-derive.rs:110:1
-   |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:111:52
-   |
-LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")]
-   |                                                    ^^^^^^^
-   |
-note: previously specified here
-  --> $DIR/diagnostic-derive.rs:110:50
-   |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   |                                                  ^^^^^^^
-
-error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:118:66
-   |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
-   |                                                                  ^^^^^^^
-   |
-note: previously specified here
-  --> $DIR/diagnostic-derive.rs:118:50
-   |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
-   |                                                  ^^^^^^^
-
-error: `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:123:43
-   |
-LL | #[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: diagnostic kind not specified
-  --> $DIR/diagnostic-derive.rs:128:1
+error: diagnostic slug not specified
+  --> $DIR/diagnostic-derive.rs:119:1
    |
 LL | struct KindNotProvided {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: use the `#[error(...)]` attribute to create an error
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:131:1
+  --> $DIR/diagnostic-derive.rs:122:1
    |
-LL | / #[error(code = "E0456")]
+LL | / #[diag(code = "E0456")]
 LL | |
 LL | | struct SlugNotProvided {}
    | |_________________________^
    |
-   = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
 
 error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:142:5
+  --> $DIR/diagnostic-derive.rs:133:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
 
 error: `#[nonsense]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:150:5
+  --> $DIR/diagnostic-derive.rs:141:5
    |
 LL |     #[nonsense]
    |     ^^^^^^^^^^^
@@ -248,19 +200,19 @@ LL |     #[nonsense]
    = help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:167:5
+  --> $DIR/diagnostic-derive.rs:158:5
    |
 LL |     #[label(typeck::label)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `name` doesn't refer to a field on this type
-  --> $DIR/diagnostic-derive.rs:175:45
+  --> $DIR/diagnostic-derive.rs:166:45
    |
 LL |     #[suggestion(typeck::suggestion, code = "{name}")]
    |                                             ^^^^^^^^
 
 error: invalid format string: expected `'}'` but string was terminated
-  --> $DIR/diagnostic-derive.rs:180:16
+  --> $DIR/diagnostic-derive.rs:171:16
    |
 LL | #[derive(SessionDiagnostic)]
    |           -    ^ expected `'}'` in format string
@@ -271,7 +223,7 @@ LL | #[derive(SessionDiagnostic)]
    = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: invalid format string: unmatched `}` found
-  --> $DIR/diagnostic-derive.rs:190:15
+  --> $DIR/diagnostic-derive.rs:181:15
    |
 LL | #[derive(SessionDiagnostic)]
    |               ^ unmatched `}` in format string
@@ -280,13 +232,13 @@ LL | #[derive(SessionDiagnostic)]
    = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:210:5
+  --> $DIR/diagnostic-derive.rs:201:5
    |
 LL |     #[label(typeck::label)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion(nonsense = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:235:18
+  --> $DIR/diagnostic-derive.rs:226:18
    |
 LL |     #[suggestion(nonsense = "bar")]
    |                  ^^^^^^^^^^^^^^^^
@@ -294,7 +246,7 @@ LL |     #[suggestion(nonsense = "bar")]
    = help: only `message`, `code` and `applicability` are valid field attributes
 
 error: `#[suggestion(msg = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:243:18
+  --> $DIR/diagnostic-derive.rs:234:18
    |
 LL |     #[suggestion(msg = "bar")]
    |                  ^^^^^^^^^^^
@@ -302,7 +254,7 @@ LL |     #[suggestion(msg = "bar")]
    = help: only `message`, `code` and `applicability` are valid field attributes
 
 error: wrong field type for suggestion
-  --> $DIR/diagnostic-derive.rs:265:5
+  --> $DIR/diagnostic-derive.rs:256:5
    |
 LL | /     #[suggestion(typeck::suggestion, code = "This is suggested code")]
 LL | |
@@ -312,7 +264,7 @@ LL | |     suggestion: Applicability,
    = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
 
 error: type of field annotated with `#[suggestion(...)]` contains more than one `Span`
-  --> $DIR/diagnostic-derive.rs:280:5
+  --> $DIR/diagnostic-derive.rs:271:5
    |
 LL | /     #[suggestion(typeck::suggestion, code = "This is suggested code")]
 LL | |
@@ -320,7 +272,7 @@ LL | |     suggestion: (Span, Span, Applicability),
    | |___________________________________________^
 
 error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
-  --> $DIR/diagnostic-derive.rs:288:5
+  --> $DIR/diagnostic-derive.rs:279:5
    |
 LL | /     #[suggestion(typeck::suggestion, code = "This is suggested code")]
 LL | |
@@ -328,62 +280,128 @@ LL | |     suggestion: (Applicability, Applicability, Span),
    | |____________________________________________________^
 
 error: `#[label = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:296:5
+  --> $DIR/diagnostic-derive.rs:287:5
    |
 LL |     #[label = "bar"]
    |     ^^^^^^^^^^^^^^^^
 
 error: applicability cannot be set in both the field and attribute
-  --> $DIR/diagnostic-derive.rs:447:52
+  --> $DIR/diagnostic-derive.rs:438:52
    |
 LL |     #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
    |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/diagnostic-derive.rs:455:52
+  --> $DIR/diagnostic-derive.rs:446:52
    |
 LL |     #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
    |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[label(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:518:5
+  --> $DIR/diagnostic-derive.rs:509:5
    |
 LL |     #[label(typeck::label, foo)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[label(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:526:5
+  --> $DIR/diagnostic-derive.rs:517:5
    |
 LL |     #[label(typeck::label, foo = "...")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[label(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:534:5
+  --> $DIR/diagnostic-derive.rs:525:5
    |
 LL |     #[label(typeck::label, foo("..."))]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: only `#[error(..)]` and `#[warning(..)]` are supported
-  --> $DIR/diagnostic-derive.rs:540:1
+error: `#[primary_span]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:538:5
    |
-LL | / #[lint(typeck::ambiguous_lifetime_bound)]
+LL |     #[primary_span]
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: the `primary_span` field attribute is not valid for lint diagnostics
+
+error: `#[error(...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:558:1
+   |
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: `error`, `warning` and `lint` have been replaced by `diag`
+
+error: diagnostic slug not specified
+  --> $DIR/diagnostic-derive.rs:558:1
+   |
+LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
 LL | |
-LL | | struct LintsBad {
-LL | | }
-   | |_^
+LL | |
+LL | |
+LL | | struct ErrorAttribute {}
+   | |________________________^
+   |
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+
+error: `#[warning(...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:565:1
    |
-   = help: use the `#[error(...)]` attribute to create a error
+LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: `error`, `warning` and `lint` have been replaced by `diag`
 
-error: only `#[lint(..)]` is supported
-  --> $DIR/diagnostic-derive.rs:551:1
+error: diagnostic slug not specified
+  --> $DIR/diagnostic-derive.rs:565:1
    |
-LL | / #[error(typeck::ambiguous_lifetime_bound)]
+LL | / #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")]
 LL | |
-LL | | struct ErrorsBad {
-LL | | }
-   | |_^
+LL | |
+LL | |
+LL | | struct WarningAttribute {}
+   | |__________________________^
+   |
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+
+error: `#[lint(...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:572:1
+   |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: `error`, `warning` and `lint` have been replaced by `diag`
+
+error: diagnostic slug not specified
+  --> $DIR/diagnostic-derive.rs:572:1
+   |
+LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct LintAttributeOnSessionDiag {}
+   | |____________________________________^
+   |
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+
+error: `#[lint(...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:579:1
+   |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: `error`, `warning` and `lint` have been replaced by `diag`
+
+error: diagnostic slug not specified
+  --> $DIR/diagnostic-derive.rs:579:1
+   |
+LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | |
+LL | |
+LL | |
+LL | | struct LintAttributeOnLintDiag {}
+   | |_________________________________^
    |
-   = help: use the `#[lint(...)]` attribute to create a lint
+   = help: specify the slug as the first argument to the attribute, such as `#[diag(typeck::example_error)]`
 
 error: cannot find attribute `nonsense` in this scope
   --> $DIR/diagnostic-derive.rs:53:3
@@ -392,32 +410,56 @@ LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
    |   ^^^^^^^^
 
 error: cannot find attribute `nonsense` in this scope
-  --> $DIR/diagnostic-derive.rs:150:7
+  --> $DIR/diagnostic-derive.rs:141:7
    |
 LL |     #[nonsense]
    |       ^^^^^^^^
 
+error: cannot find attribute `error` in this scope
+  --> $DIR/diagnostic-derive.rs:558:3
+   |
+LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   |   ^^^^^
+
+error: cannot find attribute `warning` in this scope
+  --> $DIR/diagnostic-derive.rs:565:3
+   |
+LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   |   ^^^^^^^
+
+error: cannot find attribute `lint` in this scope
+  --> $DIR/diagnostic-derive.rs:572:3
+   |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   |   ^^^^ help: a built-in attribute with a similar name exists: `link`
+
+error: cannot find attribute `lint` in this scope
+  --> $DIR/diagnostic-derive.rs:579:3
+   |
+LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+   |   ^^^^ help: a built-in attribute with a similar name exists: `link`
+
 error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent`
-  --> $DIR/diagnostic-derive.rs:66:9
+  --> $DIR/diagnostic-derive.rs:66:8
    |
-LL | #[error(nonsense, code = "E0123")]
-   |         ^^^^^^^^ not found in `rustc_errors::fluent`
+LL | #[diag(nonsense, code = "E0123")]
+   |        ^^^^^^^^ not found in `rustc_errors::fluent`
 
 error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-  --> $DIR/diagnostic-derive.rs:340:10
+  --> $DIR/diagnostic-derive.rs:331:10
    |
 LL | #[derive(SessionDiagnostic)]
    |          ^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
    |
    = help: normalized in stderr
 note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
-  --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:539:19
+  --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:569:19
    |
 LL |         arg: impl IntoDiagnosticArg,
    |                   ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg`
    = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 48 previous errors
+error: aborting due to 55 previous errors
 
 Some errors have detailed explanations: E0277, E0425.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr
index c37d469890c..66f1ab72692 100644
--- a/src/test/ui/associated-types/associated-types-path-2.stderr
+++ b/src/test/ui/associated-types/associated-types-path-2.stderr
@@ -33,7 +33,9 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:29:14
    |
 LL |     f1(2u32, 4u32);
-   |              ^^^^ the trait `Foo` is not implemented for `u32`
+   |     --       ^^^^ the trait `Foo` is not implemented for `u32`
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Foo` is implemented for `i32`
 
diff --git a/src/test/ui/associated-types/defaults-suitability.stderr b/src/test/ui/associated-types/defaults-suitability.stderr
index 43541c5dfbc..eadad4cd572 100644
--- a/src/test/ui/associated-types/defaults-suitability.stderr
+++ b/src/test/ui/associated-types/defaults-suitability.stderr
@@ -39,7 +39,7 @@ error[E0277]: the trait bound `T: Clone` is not satisfied
 LL |     type Bar: Clone = Vec<T>;
    |                       ^^^^^^ the trait `Clone` is not implemented for `T`
    |
-   = note: required because of the requirements on the impl of `Clone` for `Vec<T>`
+   = note: required for `Vec<T>` to implement `Clone`
 note: required by a bound in `Foo::Bar`
   --> $DIR/defaults-suitability.rs:28:15
    |
@@ -83,7 +83,7 @@ error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
 LL |     type Bar: Clone = Vec<Self::Baz>;
    |                       ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`
    |
-   = note: required because of the requirements on the impl of `Clone` for `Vec<<Self as Foo2<T>>::Baz>`
+   = note: required for `Vec<<Self as Foo2<T>>::Baz>` to implement `Clone`
 note: required by a bound in `Foo2::Bar`
   --> $DIR/defaults-suitability.rs:65:15
    |
@@ -100,7 +100,7 @@ error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
 LL |     type Bar: Clone = Vec<Self::Baz>;
    |                       ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`
    |
-   = note: required because of the requirements on the impl of `Clone` for `Vec<<Self as Foo25<T>>::Baz>`
+   = note: required for `Vec<<Self as Foo25<T>>::Baz>` to implement `Clone`
 note: required by a bound in `Foo25::Bar`
   --> $DIR/defaults-suitability.rs:74:15
    |
diff --git a/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr b/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr
deleted file mode 100644
index 8b2b87223a5..00000000000
--- a/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-projection.rs:25:5
-   |
-LL |     foo(());
-   |     ^^^^^^^ one type is more general than the other
-   |
-   = note: expected reference `&'a ()`
-              found reference `&()`
-note: the lifetime requirement is introduced here
-  --> $DIR/higher-ranked-projection.rs:16:33
-   |
-LL |     where for<'a> &'a T: Mirror<Image=U>
-   |                                 ^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr b/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr
deleted file mode 100644
index 217392aa35b..00000000000
--- a/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown debugging option: `borrowck`
-
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-2.stderr b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
index e007f5a163b..a85edd7a08d 100644
--- a/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
+++ b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
@@ -5,13 +5,13 @@ LL | impl X<'_> for u32
    | ^^^^^^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`hr_associated_type_bound_2`)
-note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
+note: required for `u32` to implement `for<'b> X<'b>`
   --> $DIR/hr-associated-type-bound-2.rs:11:6
    |
 LL | impl X<'_> for u32
    |      ^^^^^     ^^^
    = note: 128 redundant requirements hidden
-   = note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
+   = note: required for `u32` to implement `for<'b> X<'b>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.stderr b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
index 939c9bbdb6b..6661347e4f8 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-1.stderr
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
@@ -4,13 +4,13 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
 LL | impl<T: Grault> Grault for (T,)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: required because of the requirements on the impl of `Grault` for `(T,)`
+note: required for `(T,)` to implement `Grault`
   --> $DIR/impl-wf-cycle-1.rs:15:17
    |
 LL | impl<T: Grault> Grault for (T,)
    |                 ^^^^^^     ^^^^
    = note: 1 redundant requirement hidden
-   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+   = note: required for `(T,)` to implement `Grault`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.stderr b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
index d02ed2cacdf..ec4ffe27c5f 100644
--- a/src/test/ui/associated-types/impl-wf-cycle-2.stderr
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
 LL | impl<T: Grault> Grault for (T,)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: required because of the requirements on the impl of `Grault` for `(T,)`
+note: required for `(T,)` to implement `Grault`
   --> $DIR/impl-wf-cycle-2.rs:7:17
    |
 LL | impl<T: Grault> Grault for (T,)
diff --git a/src/test/ui/associated-types/issue-44153.stderr b/src/test/ui/associated-types/issue-44153.stderr
index 200efbe02e6..9c92f19d8bf 100644
--- a/src/test/ui/associated-types/issue-44153.stderr
+++ b/src/test/ui/associated-types/issue-44153.stderr
@@ -9,7 +9,7 @@ note: expected this to be `&()`
    |
 LL |     type Element = ();
    |                    ^^
-note: required because of the requirements on the impl of `Visit` for `()`
+note: required for `()` to implement `Visit`
   --> $DIR/issue-44153.rs:13:10
    |
 LL | impl<'a> Visit for () where
diff --git a/src/test/ui/associated-types/issue-65774-1.stderr b/src/test/ui/associated-types/issue-65774-1.stderr
index 419de689c52..3b294d65d56 100644
--- a/src/test/ui/associated-types/issue-65774-1.stderr
+++ b/src/test/ui/associated-types/issue-65774-1.stderr
@@ -18,7 +18,7 @@ LL |         let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(
    |                                                                            ^^^^^^^ the trait `MyDisplay` is not implemented for `T`
    |
    = help: the trait `MyDisplay` is implemented for `&'a mut T`
-note: required because of the requirements on the impl of `MyDisplay` for `&mut T`
+note: required for `&mut T` to implement `MyDisplay`
   --> $DIR/issue-65774-1.rs:5:24
    |
 LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
diff --git a/src/test/ui/associated-types/substs-ppaux.normal.stderr b/src/test/ui/associated-types/substs-ppaux.normal.stderr
index 085c56870b3..501d2cfaa26 100644
--- a/src/test/ui/associated-types/substs-ppaux.normal.stderr
+++ b/src/test/ui/associated-types/substs-ppaux.normal.stderr
@@ -77,7 +77,7 @@ LL |     <str as Foo<u8>>::bar;
    |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-note: required because of the requirements on the impl of `Foo<'_, '_, u8>` for `str`
+note: required for `str` to implement `Foo<'_, '_, u8>`
   --> $DIR/substs-ppaux.rs:11:17
    |
 LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
diff --git a/src/test/ui/associated-types/substs-ppaux.verbose.stderr b/src/test/ui/associated-types/substs-ppaux.verbose.stderr
index b831f3b7a76..ae3e862dddd 100644
--- a/src/test/ui/associated-types/substs-ppaux.verbose.stderr
+++ b/src/test/ui/associated-types/substs-ppaux.verbose.stderr
@@ -77,7 +77,7 @@ LL |     <str as Foo<u8>>::bar;
    |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-note: required because of the requirements on the impl of `Foo<'_#0r, '_#1r, u8>` for `str`
+note: required for `str` to implement `Foo<'_#0r, '_#1r, u8>`
   --> $DIR/substs-ppaux.rs:11:17
    |
 LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr
index 4285fbbeceb..9c85eb87684 100644
--- a/src/test/ui/async-await/issue-68112.stderr
+++ b/src/test/ui/async-await/issue-68112.stderr
@@ -41,7 +41,7 @@ LL |     require_send(send_fut);
    |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
+   = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this `async fn` body
   --> $DIR/issue-68112.rs:47:31
    |
diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr
index a88bce6cc99..f6ff52a5fd2 100644
--- a/src/test/ui/async-await/issue-70594.stderr
+++ b/src/test/ui/async-await/issue-70594.stderr
@@ -26,7 +26,7 @@ LL |     [1; ().await];
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
-   = note: required because of the requirements on the impl of `IntoFuture` for `()`
+   = note: required for `()` to implement `IntoFuture`
 help: remove the `.await`
    |
 LL -     [1; ().await];
diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
index 2ce7309e1de..d2e388c78ca 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
+++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
@@ -5,7 +5,7 @@ LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
    |                                             ^^^^^^^^^^^^^^^^^^ `Sender<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Sender<i32>`
-   = note: required because of the requirements on the impl of `Send` for `&Sender<i32>`
+   = note: required for `&Sender<i32>` to implement `Send`
 note: required because it's used within this closure
   --> $DIR/issue-70935-complex-spans.rs:16:13
    |
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 5cbbf89a222..fb9dee11f2a 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -32,7 +32,7 @@ LL |     (|_| 2333).await;
    |
    = help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
    = note: [closure@$DIR/issue-62009-1.rs:12:6: 12:9] must be a future or must implement `IntoFuture` to be awaited
-   = note: required because of the requirements on the impl of `IntoFuture` for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
+   = note: required for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` to implement `IntoFuture`
 help: remove the `.await`
    |
 LL -     (|_| 2333).await;
diff --git a/src/test/ui/async-await/unnecessary-await.stderr b/src/test/ui/async-await/unnecessary-await.stderr
index e7e61c2baaf..dc308933697 100644
--- a/src/test/ui/async-await/unnecessary-await.stderr
+++ b/src/test/ui/async-await/unnecessary-await.stderr
@@ -8,7 +8,7 @@ LL |     boo().await;
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
-   = note: required because of the requirements on the impl of `IntoFuture` for `()`
+   = note: required for `()` to implement `IntoFuture`
 help: remove the `.await`
    |
 LL -     boo().await;
diff --git a/src/test/ui/attempted-access-non-fatal.rs b/src/test/ui/attempted-access-non-fatal.rs
index e50c1f23c51..15deb9e2f60 100644
--- a/src/test/ui/attempted-access-non-fatal.rs
+++ b/src/test/ui/attempted-access-non-fatal.rs
@@ -3,4 +3,8 @@ fn main() {
     let x = 0;
     let _ = x.foo; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
     let _ = x.bar; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+    let _ = 0.f; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+    let _ = 2.l; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+    let _ = 12.F; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+    let _ = 34.L; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
 }
diff --git a/src/test/ui/attempted-access-non-fatal.stderr b/src/test/ui/attempted-access-non-fatal.stderr
index 5b7db0e9d6f..bff669727a1 100644
--- a/src/test/ui/attempted-access-non-fatal.stderr
+++ b/src/test/ui/attempted-access-non-fatal.stderr
@@ -10,6 +10,50 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     let _ = x.bar;
    |               ^^^
 
-error: aborting due to 2 previous errors
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+  --> $DIR/attempted-access-non-fatal.rs:6:15
+   |
+LL |     let _ = 0.f;
+   |               ^
+   |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f32` suffix
+   |
+LL |     let _ = 0.0f32;
+   |               ~~~~
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+  --> $DIR/attempted-access-non-fatal.rs:7:15
+   |
+LL |     let _ = 2.l;
+   |               ^
+   |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix
+   |
+LL |     let _ = 2.0f64;
+   |               ~~~~
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+  --> $DIR/attempted-access-non-fatal.rs:8:16
+   |
+LL |     let _ = 12.F;
+   |                ^
+   |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f32` suffix
+   |
+LL |     let _ = 12.0f32;
+   |                ~~~~
+
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
+  --> $DIR/attempted-access-non-fatal.rs:9:16
+   |
+LL |     let _ = 34.L;
+   |                ^
+   |
+help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix
+   |
+LL |     let _ = 34.0f64;
+   |                ~~~~
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0610`.
diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
index 985cdce1224..5645e158502 100644
--- a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
+++ b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
@@ -5,7 +5,7 @@ LL |     is_defaulted::<&'static u32>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
    |
    = help: the trait `Signed` is implemented for `i32`
-note: required because of the requirements on the impl of `Defaulted` for `&'static u32`
+note: required for `&'static u32` to implement `Defaulted`
   --> $DIR/typeck-default-trait-impl-precedence.rs:10:19
    |
 LL | impl<'a,T:Signed> Defaulted for &'a T { }
diff --git a/src/test/ui/block-result/issue-22645.stderr b/src/test/ui/block-result/issue-22645.stderr
index 31663e8e84d..28debd60a99 100644
--- a/src/test/ui/block-result/issue-22645.stderr
+++ b/src/test/ui/block-result/issue-22645.stderr
@@ -5,7 +5,7 @@ LL |   b + 3
    |     ^ the trait `Scalar` is not implemented for `{integer}`
    |
    = help: the trait `Scalar` is implemented for `f64`
-note: required because of the requirements on the impl of `Add<{integer}>` for `Bob`
+note: required for `Bob` to implement `Add<{integer}>`
   --> $DIR/issue-22645.rs:8:19
    |
 LL | impl<RHS: Scalar> Add <RHS> for Bob {
diff --git a/src/test/ui/borrowck/issue-64453.stderr b/src/test/ui/borrowck/issue-64453.stderr
index 1f8a1acb89f..245c3a40e05 100644
--- a/src/test/ui/borrowck/issue-64453.stderr
+++ b/src/test/ui/borrowck/issue-64453.stderr
@@ -14,6 +14,7 @@ LL | static settings_dir: String = format!("");
    |                               ^^^^^^^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0507]: cannot move out of static item `settings_dir`
diff --git a/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
index af26169c806..b1af090aec2 100644
--- a/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
+++ b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
@@ -5,6 +5,7 @@ LL |     cb.map(|cb| cb());
    |     ^^^--------------
    |     |  |
    |     |  `*cb` moved due to this method call
+   |     help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
    |     move occurs because `*cb` has type `Option<&mut dyn FnMut()>`, which does not implement the `Copy` trait
    |
 note: this function takes ownership of the receiver `self`, which moves `*cb`
@@ -12,10 +13,6 @@ note: this function takes ownership of the receiver `self`, which moves `*cb`
    |
 LL |     pub const fn map<U, F>(self, f: F) -> Option<U>
    |                            ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
-   |
-LL |     cb.as_ref().map(|cb| cb());
-   |        +++++++++
 
 error[E0596]: cannot borrow `*cb` as mutable, as it is behind a `&` reference
   --> $DIR/suggest-as-ref-on-mut-closure.rs:12:26
diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr
index b28cf0d6bd0..3c193ca34ac 100644
--- a/src/test/ui/check-static-values-constraints.stderr
+++ b/src/test/ui/check-static-values-constraints.stderr
@@ -22,6 +22,7 @@ LL |     field2: SafeEnum::Variant4("str".to_string())
    |                                      ^^^^^^^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error[E0010]: allocations are not allowed in statics
   --> $DIR/check-static-values-constraints.rs:94:5
diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr
index 1086cfa2947..3e9b1c292dc 100644
--- a/src/test/ui/closures/closure-move-sync.stderr
+++ b/src/test/ui/closures/closure-move-sync.stderr
@@ -5,7 +5,7 @@ LL |     let t = thread::spawn(|| {
    |             ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
-   = note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>`
+   = note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send`
 note: required because it's used within this closure
   --> $DIR/closure-move-sync.rs:6:27
    |
@@ -24,7 +24,7 @@ LL |     thread::spawn(|| tx.send(()).unwrap());
    |     ^^^^^^^^^^^^^ `Sender<()>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Sender<()>`
-   = note: required because of the requirements on the impl of `Send` for `&Sender<()>`
+   = note: required for `&Sender<()>` to implement `Send`
 note: required because it's used within this closure
   --> $DIR/closure-move-sync.rs:18:19
    |
diff --git a/src/test/ui/coherence/issue-100191-2.stderr b/src/test/ui/coherence/issue-100191-2.stderr
index ea09fb15bdf..d50c220bcfd 100644
--- a/src/test/ui/coherence/issue-100191-2.stderr
+++ b/src/test/ui/coherence/issue-100191-2.stderr
@@ -1,13 +1,13 @@
 error[E0275]: overflow evaluating the requirement `T: Trait<_>`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_100191_2`)
-note: required because of the requirements on the impl of `Trait<_>` for `T`
+note: required for `T` to implement `Trait<_>`
   --> $DIR/issue-100191-2.rs:8:20
    |
 LL | default impl<T, U> Trait<T> for U {}
    |                    ^^^^^^^^     ^
    = note: 128 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Trait<_>` for `T`
+   = note: required for `T` to implement `Trait<_>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
index ababb27a869..a5f7bc0b26c 100644
--- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -5,7 +5,7 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
 LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
@@ -32,7 +32,7 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
 LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
@@ -77,7 +77,7 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
 LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
@@ -104,7 +104,7 @@ LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
-note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
   --> $DIR/abstract-const-as-cast-3.rs:8:22
    |
 LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
index 7a083733a2c..5ad457d547a 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr
@@ -2,7 +2,9 @@ error[E0423]: expected value, found type parameter `T`
   --> $DIR/issue-69654.rs:5:25
    |
 LL | impl<T> Bar<T> for [u8; T] {}
-   |                         ^ not a value
+   |      -                  ^ not a value
+   |      |
+   |      found this type pararmeter
 
 error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied
   --> $DIR/issue-69654.rs:17:10
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
index d45dfde9a79..808b305c680 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-85848.stderr
@@ -7,12 +7,12 @@ LL |     writes_to_specific_path(&cap);
    |     required by a bound introduced by this call
    |
    = help: the trait `Delegates<U>` is implemented for `T`
-note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+note: required for `&C` to implement `Contains<(), true>`
   --> $DIR/issue-85848.rs:21:12
    |
 LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     ^
-note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+note: required for `&C` to implement `Delegates<()>`
   --> $DIR/issue-85848.rs:12:12
    |
 LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
@@ -32,12 +32,12 @@ LL |     writes_to_specific_path(&cap);
    |     required by a bound introduced by this call
    |
    = help: try adding a `where` bound using this expression: `where [(); { contains::<T, U>() }]:`
-note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+note: required for `&C` to implement `Contains<(), true>`
   --> $DIR/issue-85848.rs:21:12
    |
 LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     ^
-note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+note: required for `&C` to implement `Delegates<()>`
   --> $DIR/issue-85848.rs:12:12
    |
 LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
diff --git a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
index 5306fed2251..ee352700c30 100644
--- a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
+++ b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
 LL |     let _: [Option<Bar>; 2] = [no_copy(); 2];
    |                                ^^^^^^^^^ the trait `Copy` is not implemented for `Bar`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: required for `Option<Bar>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
    = help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];`
    = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
diff --git a/src/test/ui/consts/const-blocks/migrate-fail.stderr b/src/test/ui/consts/const-blocks/migrate-fail.stderr
index 803281c0794..928ffd0839d 100644
--- a/src/test/ui/consts/const-blocks/migrate-fail.stderr
+++ b/src/test/ui/consts/const-blocks/migrate-fail.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
    |                                      ^ the trait `Copy` is not implemented for `Bar`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: required for `Option<Bar>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider annotating `Bar` with `#[derive(Copy)]`
    |
@@ -17,7 +17,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
    |                                      ^ the trait `Copy` is not implemented for `Bar`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: required for `Option<Bar>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider annotating `Bar` with `#[derive(Copy)]`
    |
diff --git a/src/test/ui/consts/const-blocks/nll-fail.stderr b/src/test/ui/consts/const-blocks/nll-fail.stderr
index 8841af15dc0..fede0084547 100644
--- a/src/test/ui/consts/const-blocks/nll-fail.stderr
+++ b/src/test/ui/consts/const-blocks/nll-fail.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
    |                                      ^ the trait `Copy` is not implemented for `Bar`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: required for `Option<Bar>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider annotating `Bar` with `#[derive(Copy)]`
    |
@@ -17,7 +17,7 @@ error[E0277]: the trait bound `Bar: Copy` is not satisfied
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
    |                                      ^ the trait `Copy` is not implemented for `Bar`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: required for `Option<Bar>` to implement `Copy`
    = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider annotating `Bar` with `#[derive(Copy)]`
    |
diff --git a/src/test/ui/consts/const-blocks/trait-error.stderr b/src/test/ui/consts/const-blocks/trait-error.stderr
index ece200ad10b..b11dd4b8087 100644
--- a/src/test/ui/consts/const-blocks/trait-error.stderr
+++ b/src/test/ui/consts/const-blocks/trait-error.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
 LL |     [Foo(String::new()); 4];
    |      ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
-note: required because of the requirements on the impl of `Copy` for `Foo<String>`
+note: required for `Foo<String>` to implement `Copy`
   --> $DIR/trait-error.rs:1:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
index 345ead48151..9431fb33c53 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
@@ -278,26 +278,36 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
                ╾allocN─╼ ╾allocN─╼                         │ ╾──╼╾──╼
            }
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ub-wide-ptr.rs:147:62
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:147:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
-   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 8, align: 4) {
+               ╾allocN─╼ 00 00 00 00                         │ ╾──╼....
+           }
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ub-wide-ptr.rs:150:65
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:149:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
-   |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 8, align: 4) {
+               ╾allocN─╼ ╾allocN─╼                         │ ╾──╼╾──╼
+           }
 
 error[E0080]: could not evaluate static initializer
-  --> $DIR/ub-wide-ptr.rs:157:5
+  --> $DIR/ub-wide-ptr.rs:155:5
    |
 LL |     mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
 
 error[E0080]: could not evaluate static initializer
-  --> $DIR/ub-wide-ptr.rs:161:5
+  --> $DIR/ub-wide-ptr.rs:159:5
    |
 LL |     mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
index 501932cb95c..15ef703024a 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
@@ -278,26 +278,36 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
                ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼
            }
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ub-wide-ptr.rs:147:62
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:147:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
-   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 16, align: 8) {
+               ╾──────allocN───────╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
+           }
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ub-wide-ptr.rs:150:65
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:149:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
-   |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the raw bytes of the constant (size: 16, align: 8) {
+               ╾──────allocN───────╼ ╾──────allocN───────╼ │ ╾──────╼╾──────╼
+           }
 
 error[E0080]: could not evaluate static initializer
-  --> $DIR/ub-wide-ptr.rs:157:5
+  --> $DIR/ub-wide-ptr.rs:155:5
    |
 LL |     mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
 
 error[E0080]: could not evaluate static initializer
-  --> $DIR/ub-wide-ptr.rs:161:5
+  --> $DIR/ub-wide-ptr.rs:159:5
    |
 LL |     mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index a0377ab1efd..2da694a8bc4 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -145,11 +145,9 @@ const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool
 
 // # raw trait object
 const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
-//~^ ERROR evaluation of constant value failed
-//~| null pointer
+//~^ ERROR it is undefined behavior to use this value
 const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
-//~^ ERROR evaluation of constant value failed
-//~| does not point to a vtable
+//~^ ERROR it is undefined behavior to use this value
 const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw
 
 // Const eval fails for these, so they need to be statics to error.
diff --git a/src/test/ui/consts/issue-32829-2.stderr b/src/test/ui/consts/issue-32829-2.stderr
index b94bdc0e3df..0fec3581873 100644
--- a/src/test/ui/consts/issue-32829-2.stderr
+++ b/src/test/ui/consts/issue-32829-2.stderr
@@ -13,6 +13,7 @@ LL |         invalid();
    |         ^^^^^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error[E0015]: cannot call non-const fn `invalid` in statics
   --> $DIR/issue-32829-2.rs:54:9
@@ -21,6 +22,7 @@ LL |         invalid();
    |         ^^^^^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/consts/mir_check_nonconst.stderr b/src/test/ui/consts/mir_check_nonconst.stderr
index 2bac995eebf..1e0652722ff 100644
--- a/src/test/ui/consts/mir_check_nonconst.stderr
+++ b/src/test/ui/consts/mir_check_nonconst.stderr
@@ -5,6 +5,7 @@ LL | static foo: Foo = bar();
    |                   ^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
index d66faa086de..67a27729db7 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
@@ -7,7 +7,6 @@ struct Error;
 enum Enum {
    A {
      x: Error //~ ERROR
-//~^ ERROR
    }
 }
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
index f655600b760..9953154fd4b 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
 LL | #[derive(PartialEq)]
    |
 
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
-   |
-LL | #[derive(PartialEq)]
-   |          --------- in this derive macro expansion
-...
-LL |      x: Error
-   |      ^^^^^^^^
-   |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:4:1
-   |
-LL | struct Error;
-   | ^^^^^^^^^^^^ must implement `PartialEq<_>`
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
-   |
-LL | #[derive(PartialEq)]
-   |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.rs b/src/test/ui/derives/derives-span-PartialEq-enum.rs
index 66edf460b31..0becc7e0d10 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.rs
@@ -7,8 +7,7 @@ struct Error;
 enum Enum {
    A(
      Error //~ ERROR
-//~^ ERROR
-     )
+   )
 }
 
 fn main() {}
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
index ce4b00bfbf5..7c130452301 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
 LL | #[derive(PartialEq)]
    |
 
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:9:6
-   |
-LL | #[derive(PartialEq)]
-   |          --------- in this derive macro expansion
-...
-LL |      Error
-   |      ^^^^^
-   |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:4:1
-   |
-LL | struct Error;
-   | ^^^^^^^^^^^^ must implement `PartialEq<_>`
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
-   |
-LL | #[derive(PartialEq)]
-   |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.rs b/src/test/ui/derives/derives-span-PartialEq-struct.rs
index ce5c67af77f..c92ef5fadf7 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.rs
@@ -6,7 +6,6 @@ struct Error;
 #[derive(PartialEq)]
 struct Struct {
     x: Error //~ ERROR
-//~^ ERROR
 }
 
 fn main() {}
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
index c5c8f255fb3..ba3d6ced3f4 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
 LL | #[derive(PartialEq)]
    |
 
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:8:5
-   |
-LL | #[derive(PartialEq)]
-   |          --------- in this derive macro expansion
-LL | struct Struct {
-LL |     x: Error
-   |     ^^^^^^^^
-   |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:4:1
-   |
-LL | struct Error;
-   | ^^^^^^^^^^^^ must implement `PartialEq<_>`
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
-   |
-LL | #[derive(PartialEq)]
-   |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
index eaa62831136..10ac347aa0b 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
@@ -6,7 +6,6 @@ struct Error;
 #[derive(PartialEq)]
 struct Struct(
     Error //~ ERROR
-//~^ ERROR
 );
 
 fn main() {}
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
index f5d609cb33f..ab0b56a9eef 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
@@ -18,26 +18,6 @@ help: consider annotating `Error` with `#[derive(PartialEq)]`
 LL | #[derive(PartialEq)]
    |
 
-error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
-   |
-LL | #[derive(PartialEq)]
-   |          --------- in this derive macro expansion
-LL | struct Struct(
-LL |     Error
-   |     ^^^^^
-   |
-note: an implementation of `PartialEq<_>` might be missing for `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:4:1
-   |
-LL | struct Error;
-   | ^^^^^^^^^^^^ must implement `PartialEq<_>`
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `Error` with `#[derive(PartialEq)]`
-   |
-LL | #[derive(PartialEq)]
-   |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr
index 13097edf0ad..da895098e4b 100644
--- a/src/test/ui/derives/deriving-copyclone.stderr
+++ b/src/test/ui/derives/deriving-copyclone.stderr
@@ -6,7 +6,7 @@ LL |     is_copy(B { a: 1, b: C });
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Copy` for `B<C>`
+note: required for `B<C>` to implement `Copy`
   --> $DIR/deriving-copyclone.rs:9:10
    |
 LL | #[derive(Copy, Clone)]
@@ -30,7 +30,7 @@ LL |     is_clone(B { a: 1, b: C });
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Clone` for `B<C>`
+note: required for `B<C>` to implement `Clone`
   --> $DIR/deriving-copyclone.rs:9:16
    |
 LL | #[derive(Copy, Clone)]
@@ -54,7 +54,7 @@ LL |     is_copy(B { a: 1, b: D });
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Copy` for `B<D>`
+note: required for `B<D>` to implement `Copy`
   --> $DIR/deriving-copyclone.rs:9:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/src/test/ui/derives/deriving-no-inner-impl-error-message.rs b/src/test/ui/derives/deriving-no-inner-impl-error-message.rs
index 39e41a59ef4..b3ce31bf0d3 100644
--- a/src/test/ui/derives/deriving-no-inner-impl-error-message.rs
+++ b/src/test/ui/derives/deriving-no-inner-impl-error-message.rs
@@ -3,7 +3,6 @@ struct NoCloneOrEq;
 #[derive(PartialEq)]
 struct E {
     x: NoCloneOrEq //~ ERROR binary operation `==` cannot be applied to type `NoCloneOrEq`
-         //~^ ERROR binary operation `!=` cannot be applied to type `NoCloneOrEq`
 }
 #[derive(Clone)]
 struct C {
diff --git a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr
index 7875f072356..ef8c44caacf 100644
--- a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr
+++ b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr
@@ -18,28 +18,8 @@ help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]`
 LL | #[derive(PartialEq)]
    |
 
-error[E0369]: binary operation `!=` cannot be applied to type `NoCloneOrEq`
-  --> $DIR/deriving-no-inner-impl-error-message.rs:5:5
-   |
-LL | #[derive(PartialEq)]
-   |          --------- in this derive macro expansion
-LL | struct E {
-LL |     x: NoCloneOrEq
-   |     ^^^^^^^^^^^^^^
-   |
-note: an implementation of `PartialEq<_>` might be missing for `NoCloneOrEq`
-  --> $DIR/deriving-no-inner-impl-error-message.rs:1:1
-   |
-LL | struct NoCloneOrEq;
-   | ^^^^^^^^^^^^^^^^^^ must implement `PartialEq<_>`
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]`
-   |
-LL | #[derive(PartialEq)]
-   |
-
 error[E0277]: the trait bound `NoCloneOrEq: Clone` is not satisfied
-  --> $DIR/deriving-no-inner-impl-error-message.rs:10:5
+  --> $DIR/deriving-no-inner-impl-error-message.rs:9:5
    |
 LL | #[derive(Clone)]
    |          ----- in this derive macro expansion
@@ -53,7 +33,7 @@ help: consider annotating `NoCloneOrEq` with `#[derive(Clone)]`
 LL | #[derive(Clone)]
    |
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0277, E0369.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout
index 21fe663f067..65f7dec8408 100644
--- a/src/test/ui/deriving/deriving-all-codegen.stdout
+++ b/src/test/ui/deriving/deriving-all-codegen.stdout
@@ -122,10 +122,6 @@ impl ::core::cmp::PartialEq for Point {
     fn eq(&self, other: &Point) -> bool {
         self.x == other.x && self.y == other.y
     }
-    #[inline]
-    fn ne(&self, other: &Point) -> bool {
-        self.x != other.x || self.y != other.y
-    }
 }
 impl ::core::marker::StructuralEq for Point {}
 #[automatically_derived]
@@ -239,13 +235,6 @@ impl ::core::cmp::PartialEq for Big {
                     self.b6 == other.b6 && self.b7 == other.b7 &&
             self.b8 == other.b8
     }
-    #[inline]
-    fn ne(&self, other: &Big) -> bool {
-        self.b1 != other.b1 || self.b2 != other.b2 || self.b3 != other.b3 ||
-                            self.b4 != other.b4 || self.b5 != other.b5 ||
-                    self.b6 != other.b6 || self.b7 != other.b7 ||
-            self.b8 != other.b8
-    }
 }
 impl ::core::marker::StructuralEq for Big {}
 #[automatically_derived]
@@ -361,8 +350,6 @@ impl ::core::marker::StructuralPartialEq for Unsized {}
 impl ::core::cmp::PartialEq for Unsized {
     #[inline]
     fn eq(&self, other: &Unsized) -> bool { self.0 == other.0 }
-    #[inline]
-    fn ne(&self, other: &Unsized) -> bool { self.0 != other.0 }
 }
 impl ::core::marker::StructuralEq for Unsized {}
 #[automatically_derived]
@@ -428,8 +415,6 @@ impl ::core::marker::StructuralPartialEq for PackedCopy {}
 impl ::core::cmp::PartialEq for PackedCopy {
     #[inline]
     fn eq(&self, other: &PackedCopy) -> bool { { self.0 } == { other.0 } }
-    #[inline]
-    fn ne(&self, other: &PackedCopy) -> bool { { self.0 } != { other.0 } }
 }
 impl ::core::marker::StructuralEq for PackedCopy {}
 #[automatically_derived]
@@ -503,12 +488,6 @@ impl ::core::cmp::PartialEq for PackedNonCopy {
         let Self(ref __self_1_0) = *other;
         *__self_0_0 == *__self_1_0
     }
-    #[inline]
-    fn ne(&self, other: &PackedNonCopy) -> bool {
-        let Self(ref __self_0_0) = *self;
-        let Self(ref __self_1_0) = *other;
-        *__self_0_0 != *__self_1_0
-    }
 }
 impl ::core::marker::StructuralEq for PackedNonCopy {}
 #[automatically_derived]
@@ -638,13 +617,6 @@ impl ::core::cmp::PartialEq for Enum1 {
                 *__self_0 == *__arg1_0,
         }
     }
-    #[inline]
-    fn ne(&self, other: &Enum1) -> bool {
-        match (self, other) {
-            (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
-                *__self_0 != *__arg1_0,
-        }
-    }
 }
 impl ::core::marker::StructuralEq for Enum1 {}
 #[automatically_derived]
@@ -883,20 +855,6 @@ impl ::core::cmp::PartialEq for Mixed {
                 _ => true,
             }
     }
-    #[inline]
-    fn ne(&self, other: &Mixed) -> bool {
-        let __self_tag = ::core::intrinsics::discriminant_value(self);
-        let __arg1_tag = ::core::intrinsics::discriminant_value(other);
-        __self_tag != __arg1_tag ||
-            match (self, other) {
-                (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
-                    *__self_0 != *__arg1_0,
-                (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
-                    d1: __arg1_0, d2: __arg1_1 }) =>
-                    *__self_0 != *__arg1_0 || *__self_1 != *__arg1_1,
-                _ => false,
-            }
-    }
 }
 impl ::core::marker::StructuralEq for Mixed {}
 #[automatically_derived]
@@ -1023,21 +981,6 @@ impl ::core::cmp::PartialEq for Fielded {
                 _ => unsafe { ::core::intrinsics::unreachable() }
             }
     }
-    #[inline]
-    fn ne(&self, other: &Fielded) -> bool {
-        let __self_tag = ::core::intrinsics::discriminant_value(self);
-        let __arg1_tag = ::core::intrinsics::discriminant_value(other);
-        __self_tag != __arg1_tag ||
-            match (self, other) {
-                (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
-                    *__self_0 != *__arg1_0,
-                (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
-                    *__self_0 != *__arg1_0,
-                (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
-                    *__self_0 != *__arg1_0,
-                _ => unsafe { ::core::intrinsics::unreachable() }
-            }
-    }
 }
 impl ::core::marker::StructuralEq for Fielded {}
 #[automatically_derived]
diff --git a/src/test/ui/drop/drop-foreign-fundamental.rs b/src/test/ui/drop/drop-foreign-fundamental.rs
new file mode 100644
index 00000000000..c43df40d6c2
--- /dev/null
+++ b/src/test/ui/drop/drop-foreign-fundamental.rs
@@ -0,0 +1,23 @@
+use std::ops::Deref;
+use std::pin::Pin;
+
+struct Whatever<T>(T);
+
+impl<T> Deref for Whatever<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+struct A;
+
+impl Drop for Pin<Whatever<A>> {
+    //~^ ERROR  the `Drop` trait may only be implemented for local structs, enums, and unions
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    let x = Pin::new(Whatever(1.0f32));
+}
diff --git a/src/test/ui/drop/drop-foreign-fundamental.stderr b/src/test/ui/drop/drop-foreign-fundamental.stderr
new file mode 100644
index 00000000000..fbd1ba08591
--- /dev/null
+++ b/src/test/ui/drop/drop-foreign-fundamental.stderr
@@ -0,0 +1,9 @@
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
+  --> $DIR/drop-foreign-fundamental.rs:16:15
+   |
+LL | impl Drop for Pin<Whatever<A>> {
+   |               ^^^^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0120`.
diff --git a/src/test/ui/dropck/drop-on-non-struct.rs b/src/test/ui/dropck/drop-on-non-struct.rs
index ef5e18126dc..145eab126c2 100644
--- a/src/test/ui/dropck/drop-on-non-struct.rs
+++ b/src/test/ui/dropck/drop-on-non-struct.rs
@@ -1,5 +1,5 @@
 impl<'a> Drop for &'a mut isize {
-    //~^ ERROR the `Drop` trait may only be implemented for structs, enums, and unions
+    //~^ ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
     //~^^ ERROR E0117
     fn drop(&mut self) {
         println!("kaboom");
@@ -8,8 +8,7 @@ impl<'a> Drop for &'a mut isize {
 
 impl Drop for Nonexistent {
     //~^ ERROR cannot find type `Nonexistent`
-    fn drop(&mut self) { }
+    fn drop(&mut self) {}
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/dropck/drop-on-non-struct.stderr b/src/test/ui/dropck/drop-on-non-struct.stderr
index e52728f3781..e8fbe5e9726 100644
--- a/src/test/ui/dropck/drop-on-non-struct.stderr
+++ b/src/test/ui/dropck/drop-on-non-struct.stderr
@@ -15,11 +15,11 @@ LL | impl<'a> Drop for &'a mut isize {
    |
    = note: define and implement a trait or new type instead
 
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
   --> $DIR/drop-on-non-struct.rs:1:19
    |
 LL | impl<'a> Drop for &'a mut isize {
-   |                   ^^^^^^^^^^^^^ must be a struct, enum, or union
+   |                   ^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/error-codes/E0117.rs b/src/test/ui/error-codes/E0117.rs
index 22b48657385..406d24e3666 100644
--- a/src/test/ui/error-codes/E0117.rs
+++ b/src/test/ui/error-codes/E0117.rs
@@ -1,4 +1,4 @@
 impl Drop for u32 {} //~ ERROR E0117
-//~| ERROR the `Drop` trait may only be implemented for structs, enums, and unions
+//~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr
index 76d9f5cc0e5..f144aa9f72c 100644
--- a/src/test/ui/error-codes/E0117.stderr
+++ b/src/test/ui/error-codes/E0117.stderr
@@ -9,11 +9,11 @@ LL | impl Drop for u32 {}
    |
    = note: define and implement a trait or new type instead
 
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
   --> $DIR/E0117.rs:1:15
    |
 LL | impl Drop for u32 {}
-   |               ^^^ must be a struct, enum, or union
+   |               ^^^ must be a struct, enum, or union in the current crate
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0120.stderr b/src/test/ui/error-codes/E0120.stderr
index 6c306455e42..75778f1f94a 100644
--- a/src/test/ui/error-codes/E0120.stderr
+++ b/src/test/ui/error-codes/E0120.stderr
@@ -1,8 +1,8 @@
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
   --> $DIR/E0120.rs:3:15
    |
 LL | impl Drop for dyn MyTrait {
-   |               ^^^^^^^^^^^ must be a struct, enum, or union
+   |               ^^^^^^^^^^^ must be a struct, enum, or union in the current crate
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr
index dfffbb182ad..87cfaa489c6 100644
--- a/src/test/ui/error-codes/E0275.stderr
+++ b/src/test/ui/error-codes/E0275.stderr
@@ -5,13 +5,13 @@ LL | impl<T> Foo for T where Bar<T>: Foo {}
    |                                 ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
-note: required because of the requirements on the impl of `Foo` for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
   --> $DIR/E0275.rs:5:9
    |
 LL | impl<T> Foo for T where Bar<T>: Foo {}
    |         ^^^     ^
    = note: 127 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Foo` for `Bar<T>`
+   = note: required for `Bar<T>` to implement `Foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr
index 0f7520ef7f8..0557340f792 100644
--- a/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unsized_fn_params.stderr
@@ -15,11 +15,16 @@ error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known
   --> $DIR/feature-gate-unsized_fn_params.rs:24:9
    |
 LL |     foo(*x);
-   |         ^^ doesn't have a size known at compile-time
+   |     --- ^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
-   = note: all function arguments must have a statically known size
    = help: unsized fn params are gated as an unstable feature
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL |     foo(&*x);
+   |         +
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs
new file mode 100644
index 00000000000..49f1cba7151
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.rs
@@ -0,0 +1,30 @@
+// check-fail
+// This file is used to test the behavior of the early-pass syntax warnings.
+// If macro syntax is stabilized, replace with a different unstable syntax.
+
+macro a() {}
+//~^ ERROR: `macro` is experimental
+
+#[cfg(FALSE)]
+macro b() {}
+
+macro_rules! identity {
+    ($($x:tt)*) => ($($x)*);
+}
+
+identity! {
+    macro c() {}
+    //~^ ERROR: `macro` is experimental
+}
+
+#[cfg(FALSE)]
+identity! {
+    macro d() {} // No error
+}
+
+identity! {
+    #[cfg(FALSE)]
+    macro e() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr
new file mode 100644
index 00000000000..49550d811ba
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-with-errors.stderr
@@ -0,0 +1,21 @@
+error[E0658]: `macro` is experimental
+  --> $DIR/soft-syntax-gates-with-errors.rs:5:1
+   |
+LL | macro a() {}
+   | ^^^^^^^^^^^^
+   |
+   = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+   = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+
+error[E0658]: `macro` is experimental
+  --> $DIR/soft-syntax-gates-with-errors.rs:16:5
+   |
+LL |     macro c() {}
+   |     ^^^^^^^^^^^^
+   |
+   = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+   = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs
new file mode 100644
index 00000000000..ca4ad2320f6
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.rs
@@ -0,0 +1,26 @@
+// check-pass
+// This file is used to test the behavior of the early-pass syntax warnings.
+// If macro syntax is stabilized, replace with a different unstable syntax.
+
+#[cfg(FALSE)]
+macro b() {}
+//~^ WARN: `macro` is experimental
+//~| WARN: unstable syntax
+
+macro_rules! identity {
+    ($($x:tt)*) => ($($x)*);
+}
+
+#[cfg(FALSE)]
+identity! {
+    macro d() {} // No error
+}
+
+identity! {
+    #[cfg(FALSE)]
+    macro e() {}
+    //~^ WARN: `macro` is experimental
+    //~| WARN: unstable syntax
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr
new file mode 100644
index 00000000000..3d9c22e5487
--- /dev/null
+++ b/src/test/ui/feature-gates/soft-syntax-gates-without-errors.stderr
@@ -0,0 +1,24 @@
+warning: `macro` is experimental
+  --> $DIR/soft-syntax-gates-without-errors.rs:6:1
+   |
+LL | macro b() {}
+   | ^^^^^^^^^^^^
+   |
+   = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+   = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+   = warning: unstable syntax can change at any point in the future, causing a hard error!
+   = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: `macro` is experimental
+  --> $DIR/soft-syntax-gates-without-errors.rs:21:5
+   |
+LL |     macro e() {}
+   |     ^^^^^^^^^^^^
+   |
+   = note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
+   = help: add `#![feature(decl_macro)]` to the crate attributes to enable
+   = warning: unstable syntax can change at any point in the future, causing a hard error!
+   = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/fmt/ifmt-unimpl.stderr b/src/test/ui/fmt/ifmt-unimpl.stderr
index dbcb2eb6693..0e34f913511 100644
--- a/src/test/ui/fmt/ifmt-unimpl.stderr
+++ b/src/test/ui/fmt/ifmt-unimpl.stderr
@@ -14,7 +14,7 @@ LL |     format!("{:X}", "3");
              NonZeroI8
              NonZeroIsize
            and 21 others
-   = note: required because of the requirements on the impl of `UpperHex` for `&str`
+   = note: required for `&str` to implement `UpperHex`
 note: required by a bound in `ArgumentV1::<'a>::new_upper_hex`
   --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
    |
diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr
index 7c7a3c8846b..726d3e35b10 100644
--- a/src/test/ui/fmt/send-sync.stderr
+++ b/src/test/ui/fmt/send-sync.stderr
@@ -8,7 +8,7 @@ LL |     send(format_args!("{:?}", c));
    = note: required because it appears within the type `&core::fmt::Opaque`
    = note: required because it appears within the type `ArgumentV1<'_>`
    = note: required because it appears within the type `[ArgumentV1<'_>]`
-   = note: required because of the requirements on the impl of `Send` for `&[ArgumentV1<'_>]`
+   = note: required for `&[ArgumentV1<'_>]` to implement `Send`
    = note: required because it appears within the type `Arguments<'_>`
 note: required by a bound in `send`
   --> $DIR/send-sync.rs:1:12
diff --git a/src/test/ui/for/for-c-in-str.rs b/src/test/ui/for/for-c-in-str.rs
index 86a1c1a34e9..b086128d28c 100644
--- a/src/test/ui/for/for-c-in-str.rs
+++ b/src/test/ui/for/for-c-in-str.rs
@@ -5,7 +5,7 @@ fn main() {
         //~^ ERROR `&str` is not an iterator
         //~| NOTE `&str` is not an iterator
         //~| HELP the trait `Iterator` is not implemented for `&str`
-        //~| NOTE required because of the requirements on the impl of `IntoIterator` for `&str`
+        //~| NOTE required for `&str` to implement `IntoIterator`
         //~| NOTE in this expansion of desugaring of `for` loop
         //~| NOTE in this expansion of desugaring of `for` loop
         //~| NOTE in this expansion of desugaring of `for` loop
diff --git a/src/test/ui/for/for-c-in-str.stderr b/src/test/ui/for/for-c-in-str.stderr
index 07ddc8ea78f..959a7c43fff 100644
--- a/src/test/ui/for/for-c-in-str.stderr
+++ b/src/test/ui/for/for-c-in-str.stderr
@@ -5,7 +5,7 @@ LL |     for c in "asdf" {
    |              ^^^^^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()`
    |
    = help: the trait `Iterator` is not implemented for `&str`
-   = note: required because of the requirements on the impl of `IntoIterator` for `&str`
+   = note: required for `&str` to implement `IntoIterator`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/for/for-loop-bogosity.stderr b/src/test/ui/for/for-loop-bogosity.stderr
index 0bdd75b3555..9bf8056e82e 100644
--- a/src/test/ui/for/for-loop-bogosity.stderr
+++ b/src/test/ui/for/for-loop-bogosity.stderr
@@ -5,7 +5,7 @@ LL |     for x in bogus {
    |              ^^^^^ `MyStruct` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `MyStruct`
-   = note: required because of the requirements on the impl of `IntoIterator` for `MyStruct`
+   = note: required for `MyStruct` to implement `IntoIterator`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs
index 3fcef773b68..03b21c5ebd3 100644
--- a/src/test/ui/generator/issue-68112.rs
+++ b/src/test/ui/generator/issue-68112.rs
@@ -63,7 +63,7 @@ fn test2() {
     require_send(send_gen);
     //~^ ERROR `RefCell<i32>` cannot be shared between threads safely
     //~| NOTE `RefCell<i32>` cannot be shared between threads safely
-    //~| NOTE requirements on the impl
+    //~| NOTE required for
     //~| NOTE captures the following types
 }
 
diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr
index 1d5b97e984f..b56f445872b 100644
--- a/src/test/ui/generator/issue-68112.stderr
+++ b/src/test/ui/generator/issue-68112.stderr
@@ -29,7 +29,7 @@ LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
+   = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this generator
   --> $DIR/issue-68112.rs:48:5
    |
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index 0b31bb4fdb1..b54b0f570c9 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -5,7 +5,7 @@ LL |     assert_send(|| {
    |     ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
-   = note: required because of the requirements on the impl of `Send` for `&Cell<i32>`
+   = note: required for `&Cell<i32>` to implement `Send`
 note: required because it's used within this generator
   --> $DIR/not-send-sync.rs:16:17
    |
diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr
index 5b61f1e8f2d..bbde8ea7892 100644
--- a/src/test/ui/generator/print/generator-print-verbose-1.stderr
+++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr
@@ -27,7 +27,7 @@ LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
+   = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this generator
   --> $DIR/generator-print-verbose-1.rs:42:5
    |
diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr
index eb79d2e6eed..92ca51b4e72 100644
--- a/src/test/ui/generator/print/generator-print-verbose-2.stderr
+++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr
@@ -5,7 +5,7 @@ LL |     assert_send(|| {
    |     ^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
-   = note: required because of the requirements on the impl of `Send` for `&'_#4r Cell<i32>`
+   = note: required for `&'_#4r Cell<i32>` to implement `Send`
 note: required because it's used within this generator
   --> $DIR/generator-print-verbose-2.rs:19:17
    |
diff --git a/src/test/ui/generator/yield-outside-generator-issue-78653.stderr b/src/test/ui/generator/yield-outside-generator-issue-78653.stderr
index ee1afbe5b58..dcfb211744c 100644
--- a/src/test/ui/generator/yield-outside-generator-issue-78653.stderr
+++ b/src/test/ui/generator/yield-outside-generator-issue-78653.stderr
@@ -12,7 +12,7 @@ LL |     yield || for i in 0 { }
    |
    = help: the trait `Iterator` is not implemented for `{integer}`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
+   = note: required for `{integer}` to implement `IntoIterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
index ce79c635add..4f8d673d1cf 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.stderr
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -42,7 +42,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL |     type C = String where Self: Copy;
    |                                 ^^^^ the trait `Copy` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+note: required for `Fooy<T>` to implement `Copy`
   --> $DIR/impl_bounds.rs:11:10
    |
 LL | #[derive(Copy, Clone)]
@@ -67,7 +67,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL |     fn d() where Self: Copy {}
    |                        ^^^^ the trait `Copy` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+note: required for `Fooy<T>` to implement `Copy`
   --> $DIR/impl_bounds.rs:11:10
    |
 LL | #[derive(Copy, Clone)]
diff --git a/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr
index 8517eb9fa21..eabc806c2b7 100644
--- a/src/test/ui/generic-associated-types/issue-74824.stderr
+++ b/src/test/ui/generic-associated-types/issue-74824.stderr
@@ -16,7 +16,7 @@ error[E0277]: the trait bound `T: Clone` is not satisfied
 LL |     type Copy<T>: Copy = Box<T>;
    |                          ^^^^^^ the trait `Clone` is not implemented for `T`
    |
-   = note: required because of the requirements on the impl of `Clone` for `Box<T>`
+   = note: required for `Box<T>` to implement `Clone`
 note: required by a bound in `UnsafeCopy::Copy`
   --> $DIR/issue-74824.rs:7:19
    |
diff --git a/src/test/ui/generic-associated-types/issue-76535.base.stderr b/src/test/ui/generic-associated-types/issue-76535.base.stderr
index 5decd58bbcd..fe5fe964e99 100644
--- a/src/test/ui/generic-associated-types/issue-76535.base.stderr
+++ b/src/test/ui/generic-associated-types/issue-76535.base.stderr
@@ -43,7 +43,7 @@ LL | pub trait SuperTrait {
 LL |     type SubType<'a>: SubTrait where Self: 'a;
    |          ^^^^^^^ ...because it contains the generic associated type `SubType`
    = help: consider moving `SubType` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
+   = note: required for `Box<SuperStruct>` to implement `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>`
    = note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/generic-associated-types/issue-79422.base.stderr b/src/test/ui/generic-associated-types/issue-79422.base.stderr
index 404c975d64a..0ed75ba1efc 100644
--- a/src/test/ui/generic-associated-types/issue-79422.base.stderr
+++ b/src/test/ui/generic-associated-types/issue-79422.base.stderr
@@ -43,7 +43,7 @@ LL | trait MapLike<K, V> {
 LL |     type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
    |          ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
    = help: consider moving `VRefCont` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>`
+   = note: required for `Box<BTreeMap<u8, u8>>` to implement `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>`
    = note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
index 51017ffbd41..ab5598e364f 100644
--- a/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
@@ -44,7 +44,7 @@ LL | |             },
 LL | |         },
    | |_________^ expected struct `Unit3`, found struct `Unit4`
    |
-note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>`
+note: required for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>` to implement `for<'r> T0<'r, (&'r u8,)>`
   --> $DIR/issue-62203-hrtb-ice.rs:17:16
    |
 LL | impl<'a, A, T> T0<'a, A> for L<T>
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
index a6858154dfb..14fe1803b73 100644
--- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
 LL |     C: StackContext,
    |        ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
    |
-note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
+note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>`
   --> $DIR/issue-89118.rs:5:23
    |
 LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
@@ -24,7 +24,7 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
 LL | impl<C> EthernetWorker<C> {}
    |         ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
    |
-note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
+note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>`
   --> $DIR/issue-89118.rs:5:23
    |
 LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
@@ -44,7 +44,7 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
 LL |     type Handler = Ctx<C::Dispatcher>;
    |                    ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
    |
-note: required because of the requirements on the impl of `for<'a> BufferUdpStateContext<&'a ()>` for `Ctx<()>`
+note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>`
   --> $DIR/issue-89118.rs:5:23
    |
 LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
diff --git a/src/test/ui/impl-trait/issues/issue-86800.rs b/src/test/ui/impl-trait/issues/issue-86800.rs
index 19edeaffc49..351243c6727 100644
--- a/src/test/ui/impl-trait/issues/issue-86800.rs
+++ b/src/test/ui/impl-trait/issues/issue-86800.rs
@@ -1,6 +1,14 @@
 #![feature(type_alias_impl_trait)]
 
 // edition:2021
+// unset-rustc-env:RUST_BACKTRACE
+// compile-flags:-Z treat-err-as-bug=1
+// error-pattern:stack backtrace:
+// failure-status:101
+// normalize-stderr-test "note: .*" -> ""
+// normalize-stderr-test "thread 'rustc' .*" -> ""
+// normalize-stderr-test " +[0-9]+:.*\n" -> ""
+// normalize-stderr-test " +at .*\n" -> ""
 
 use std::future::Future;
 
@@ -23,7 +31,6 @@ struct Context {
 type TransactionResult<O> = Result<O, ()>;
 
 type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
-//~^ ERROR unconstrained opaque type
 
 fn execute_transaction_fut<'f, F, O>(
     f: F,
diff --git a/src/test/ui/impl-trait/issues/issue-86800.stderr b/src/test/ui/impl-trait/issues/issue-86800.stderr
index 787aecc5b84..135d06d44ad 100644
--- a/src/test/ui/impl-trait/issues/issue-86800.stderr
+++ b/src/test/ui/impl-trait/issues/issue-86800.stderr
@@ -1,10 +1,19 @@
-error: unconstrained opaque type
-  --> $DIR/issue-86800.rs:25:34
-   |
-LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `TransactionFuture` must be used in combination with a concrete type within the same module
 
-error: aborting due to previous error
+stack backtrace:
 
+error: internal compiler error: unexpected panic
+
+
+
+
+
+
+
+
+
+query stack during panic:
+#0 [mir_borrowck] borrow-checking `execute_transaction_fut`
+#1 [type_of] computing type of `TransactionFuture::{opaque#0}`
+#2 [check_mod_item_types] checking item types in top-level module
+#3 [analysis] running analysis passes on this crate
+end of query stack
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.rs b/src/test/ui/impl-trait/nested-return-type2-tait.rs
index a2a49c5535d..42613d5ccd9 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait.rs
+++ b/src/test/ui/impl-trait/nested-return-type2-tait.rs
@@ -1,5 +1,7 @@
 #![feature(type_alias_impl_trait)]
 
+// check-pass
+
 trait Duh {}
 
 impl Duh for i32 {}
@@ -17,13 +19,13 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
 
 type Sendable = impl Send;
 
-// The `Sendable` here is then later compared against the inference var
-// created, causing the inference var to be set to `Sendable` instead of
+// The `Sendable` here is converted to an inference var and then later compared
+// against the inference var created, causing the inference var to be set to
+// the hidden type of `Sendable` instead of
 // the hidden type. We already have obligations registered on the inference
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
-// type does not implement `Duh`, even if its hidden type does. So we error out.
+// type does not implement `Duh`, but if its hidden type does.
 fn foo() -> impl Trait<Assoc = Sendable> {
-    //~^ ERROR `Sendable: Duh` is not satisfied
     || 42
 }
 
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.stderr b/src/test/ui/impl-trait/nested-return-type2-tait.stderr
deleted file mode 100644
index 1079a86ce9e..00000000000
--- a/src/test/ui/impl-trait/nested-return-type2-tait.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0277]: the trait bound `Sendable: Duh` is not satisfied
-  --> $DIR/nested-return-type2-tait.rs:25:13
-   |
-LL | fn foo() -> impl Trait<Assoc = Sendable> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Duh` is not implemented for `Sendable`
-   |
-   = help: the trait `Duh` is implemented for `i32`
-note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait.rs:27:5: 27:7]`
-  --> $DIR/nested-return-type2-tait.rs:14:31
-   |
-LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
-   |                               ^^^^^     ^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait2.rs b/src/test/ui/impl-trait/nested-return-type2-tait2.rs
index fcc077ec18e..af8e0663054 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait2.rs
+++ b/src/test/ui/impl-trait/nested-return-type2-tait2.rs
@@ -24,8 +24,8 @@ type Traitable = impl Trait<Assoc = Sendable>;
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
 // type does not implement `Duh`, even if its hidden type does. So we error out.
 fn foo() -> Traitable {
-    //~^ ERROR `Sendable: Duh` is not satisfied
     || 42
+    //~^ ERROR `Sendable: Duh` is not satisfied
 }
 
 fn main() {
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait2.stderr b/src/test/ui/impl-trait/nested-return-type2-tait2.stderr
index 847b9400085..348c737b0b1 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait2.stderr
+++ b/src/test/ui/impl-trait/nested-return-type2-tait2.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `Sendable: Duh` is not satisfied
-  --> $DIR/nested-return-type2-tait2.rs:26:13
+  --> $DIR/nested-return-type2-tait2.rs:27:5
    |
-LL | fn foo() -> Traitable {
-   |             ^^^^^^^^^ the trait `Duh` is not implemented for `Sendable`
+LL |     || 42
+   |     ^^^^^ the trait `Duh` is not implemented for `Sendable`
    |
    = help: the trait `Duh` is implemented for `i32`
-note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait2.rs:28:5: 28:7]`
+note: required for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]` to implement `Trait`
   --> $DIR/nested-return-type2-tait2.rs:14:31
    |
 LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait3.rs b/src/test/ui/impl-trait/nested-return-type2-tait3.rs
index 665c7a8cab9..74fd8a9dda0 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait3.rs
+++ b/src/test/ui/impl-trait/nested-return-type2-tait3.rs
@@ -23,8 +23,8 @@ type Traitable = impl Trait<Assoc = impl Send>;
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
 // type does not implement `Duh`, even if its hidden type does. So we error out.
 fn foo() -> Traitable {
-    //~^ ERROR `impl Send: Duh` is not satisfied
     || 42
+    //~^ ERROR `impl Send: Duh` is not satisfied
 }
 
 fn main() {
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait3.stderr b/src/test/ui/impl-trait/nested-return-type2-tait3.stderr
index 7b7f06b8e13..6ac67141557 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait3.stderr
+++ b/src/test/ui/impl-trait/nested-return-type2-tait3.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `impl Send: Duh` is not satisfied
-  --> $DIR/nested-return-type2-tait3.rs:25:13
+  --> $DIR/nested-return-type2-tait3.rs:26:5
    |
-LL | fn foo() -> Traitable {
-   |             ^^^^^^^^^ the trait `Duh` is not implemented for `impl Send`
+LL |     || 42
+   |     ^^^^^ the trait `Duh` is not implemented for `impl Send`
    |
    = help: the trait `Duh` is implemented for `i32`
-note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait3.rs:27:5: 27:7]`
+note: required for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]` to implement `Trait`
   --> $DIR/nested-return-type2-tait3.rs:14:31
    |
 LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
diff --git a/src/test/ui/impl-trait/nested-return-type2.rs b/src/test/ui/impl-trait/nested-return-type2.rs
index 279641a46c3..39928d543e1 100644
--- a/src/test/ui/impl-trait/nested-return-type2.rs
+++ b/src/test/ui/impl-trait/nested-return-type2.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 trait Duh {}
 
 impl Duh for i32 {}
@@ -18,9 +20,11 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
 // the hidden type. We already have obligations registered on the inference
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
 // type does not implement `Duh`, even if its hidden type does.
+// Lazy TAIT would error out, but we inserted a hack to make it work again,
+// keeping backwards compatibility.
 fn foo() -> impl Trait<Assoc = impl Send> {
-    //~^ ERROR `impl Send: Duh` is not satisfied
     || 42
 }
 
-fn main() {}
+fn main() {
+}
diff --git a/src/test/ui/impl-trait/nested-return-type2.stderr b/src/test/ui/impl-trait/nested-return-type2.stderr
deleted file mode 100644
index f28a084af89..00000000000
--- a/src/test/ui/impl-trait/nested-return-type2.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0277]: the trait bound `impl Send: Duh` is not satisfied
-  --> $DIR/nested-return-type2.rs:21:13
-   |
-LL | fn foo() -> impl Trait<Assoc = impl Send> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Duh` is not implemented for `impl Send`
-   |
-   = help: the trait `Duh` is implemented for `i32`
-note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2.rs:23:5: 23:7]`
-  --> $DIR/nested-return-type2.rs:12:31
-   |
-LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
-   |                               ^^^^^     ^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr
index bb4ae5e8282..3291cad6882 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.stderr
+++ b/src/test/ui/impl-trait/nested_impl_trait.stderr
@@ -53,7 +53,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                              ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
    |
    = help: the trait `Into<U>` is implemented for `T`
-   = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
+   = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
 
 error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
   --> $DIR/nested_impl_trait.rs:18:34
@@ -62,7 +62,7 @@ LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
    |
    = help: the trait `Into<U>` is implemented for `T`
-   = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
+   = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
index ade0dfa1bb3..cf2998bbf40 100644
--- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
+++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
@@ -9,7 +9,7 @@ note: expected this to be `u8`
    |
 LL |     type Assoc = u8;
    |                  ^^
-note: required because of the requirements on the impl of `Test` for `()`
+note: required for `()` to implement `Test`
   --> $DIR/projection-mismatch-in-impl-where-clause.rs:11:9
    |
 LL | impl<T> Test for T where T: Super<Assoc = ()> {}
diff --git a/src/test/ui/implied-bounds/issue-100690.rs b/src/test/ui/implied-bounds/issue-100690.rs
new file mode 100644
index 00000000000..5599cd410ba
--- /dev/null
+++ b/src/test/ui/implied-bounds/issue-100690.rs
@@ -0,0 +1,45 @@
+// This code (probably) _should_ compile, but it currently does not because we
+// are not smart enough about implied bounds.
+
+use std::io;
+
+fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
+//~^ NOTE required by a bound in this
+where
+    F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
+    //~^ NOTE required by this bound in `real_dispatch`
+    //~| NOTE required by a bound in `real_dispatch`
+{
+    todo!()
+}
+
+#[derive(Debug)]
+struct UIView<'a, T: 'a> {
+    _phantom: std::marker::PhantomData<&'a mut T>,
+}
+
+trait Handle<'a, T: 'a, V, R> {
+    fn dispatch<F>(&self, f: F) -> Result<(), io::Error>
+    where
+        F: FnOnce(&mut V) -> R + Send + 'static;
+}
+
+#[derive(Debug, Clone)]
+struct TUIHandle<T> {
+    _phantom: std::marker::PhantomData<T>,
+}
+
+impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandle<T> {
+    fn dispatch<F>(&self, f: F) -> Result<(), io::Error>
+    where
+        F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static,
+    {
+        real_dispatch(f)
+        //~^ ERROR expected a `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+        //~| NOTE expected an `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+        //~| NOTE expected a closure with arguments
+        //~| NOTE required by a bound introduced by this call
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/implied-bounds/issue-100690.stderr b/src/test/ui/implied-bounds/issue-100690.stderr
new file mode 100644
index 00000000000..3f6af70d8ed
--- /dev/null
+++ b/src/test/ui/implied-bounds/issue-100690.stderr
@@ -0,0 +1,22 @@
+error[E0277]: expected a `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+  --> $DIR/issue-100690.rs:37:23
+   |
+LL |         real_dispatch(f)
+   |         ------------- ^ expected an `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
+   |         |
+   |         required by a bound introduced by this call
+   |
+   = note: expected a closure with arguments `(&mut UIView<'a, T>,)`
+              found a closure with arguments `(&mut UIView<'_, T>,)`
+note: required by a bound in `real_dispatch`
+  --> $DIR/issue-100690.rs:9:8
+   |
+LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
+   |    ------------- required by a bound in this
+...
+LL |     F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr
index b36f4dab829..e020d029875 100644
--- a/src/test/ui/index-help.stderr
+++ b/src/test/ui/index-help.stderr
@@ -6,7 +6,7 @@ LL |     x[0i32];
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<i32>` for `Vec<{integer}>`
+   = note: required for `Vec<{integer}>` to implement `Index<i32>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr
index fbff20f8dee..7a741cfc7de 100644
--- a/src/test/ui/indexing-requires-a-uint.stderr
+++ b/src/test/ui/indexing-requires-a-uint.stderr
@@ -6,7 +6,7 @@ LL |     [0][0u8];
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<u8>` for `[{integer}]`
+   = note: required for `[{integer}]` to implement `Index<u8>`
 
 error[E0308]: mismatched types
   --> $DIR/indexing-requires-a-uint.rs:12:18
diff --git a/src/test/ui/integral-indexing.stderr b/src/test/ui/integral-indexing.stderr
index 3f9094d124e..bbbb2a86a22 100644
--- a/src/test/ui/integral-indexing.stderr
+++ b/src/test/ui/integral-indexing.stderr
@@ -6,7 +6,7 @@ LL |     v[3u8];
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<u8>` for `Vec<isize>`
+   = note: required for `Vec<isize>` to implement `Index<u8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i8`
   --> $DIR/integral-indexing.rs:7:7
@@ -16,7 +16,7 @@ LL |     v[3i8];
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<i8>` for `Vec<isize>`
+   = note: required for `Vec<isize>` to implement `Index<i8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `u32`
   --> $DIR/integral-indexing.rs:8:7
@@ -26,7 +26,7 @@ LL |     v[3u32];
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<u32>` for `Vec<isize>`
+   = note: required for `Vec<isize>` to implement `Index<u32>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i32`
   --> $DIR/integral-indexing.rs:9:7
@@ -36,7 +36,7 @@ LL |     v[3i32];
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<i32>` for `Vec<isize>`
+   = note: required for `Vec<isize>` to implement `Index<i32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u8`
   --> $DIR/integral-indexing.rs:12:18
@@ -46,7 +46,7 @@ LL |     s.as_bytes()[3u8];
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<u8>` for `[u8]`
+   = note: required for `[u8]` to implement `Index<u8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i8`
   --> $DIR/integral-indexing.rs:13:18
@@ -56,7 +56,7 @@ LL |     s.as_bytes()[3i8];
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<i8>` for `[u8]`
+   = note: required for `[u8]` to implement `Index<i8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u32`
   --> $DIR/integral-indexing.rs:14:18
@@ -66,7 +66,7 @@ LL |     s.as_bytes()[3u32];
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<u32>` for `[u8]`
+   = note: required for `[u8]` to implement `Index<u32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i32`
   --> $DIR/integral-indexing.rs:15:18
@@ -76,7 +76,7 @@ LL |     s.as_bytes()[3i32];
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<i32>` for `[u8]`
+   = note: required for `[u8]` to implement `Index<i32>`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr
index 349fb6dafa3..7955fecda06 100644
--- a/src/test/ui/interior-mutability/interior-mutability.stderr
+++ b/src/test/ui/interior-mutability/interior-mutability.stderr
@@ -6,7 +6,7 @@ LL |     catch_unwind(|| { x.set(23); });
    |
    = help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
    = note: required because it appears within the type `Cell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `&Cell<i32>`
+   = note: required for `&Cell<i32>` to implement `UnwindSafe`
 note: required because it's used within this closure
   --> $DIR/interior-mutability.rs:5:18
    |
diff --git a/src/test/ui/issues/issue-100605.rs b/src/test/ui/issues/issue-100605.rs
new file mode 100644
index 00000000000..917a45c15bb
--- /dev/null
+++ b/src/test/ui/issues/issue-100605.rs
@@ -0,0 +1,9 @@
+fn takes_option(_arg: Option<&String>) {}
+
+fn main() {
+    takes_option(&None); //~ ERROR 4:18: 4:23: mismatched types [E0308]
+
+    let x = String::from("x");
+    let res = Some(x);
+    takes_option(&res); //~ ERROR 8:18: 8:22: mismatched types [E0308]
+}
diff --git a/src/test/ui/issues/issue-100605.stderr b/src/test/ui/issues/issue-100605.stderr
new file mode 100644
index 00000000000..886e3cd6bb7
--- /dev/null
+++ b/src/test/ui/issues/issue-100605.stderr
@@ -0,0 +1,46 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-100605.rs:4:18
+   |
+LL |     takes_option(&None);
+   |     ------------ ^^^^^ expected enum `Option`, found `&Option<_>`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note:   expected enum `Option<&String>`
+           found reference `&Option<_>`
+note: function defined here
+  --> $DIR/issue-100605.rs:1:4
+   |
+LL | fn takes_option(_arg: Option<&String>) {}
+   |    ^^^^^^^^^^^^ ---------------------
+help: you can convert from `&Option<T>` to `Option<&T>` using `.as_ref()`
+   |
+LL |     takes_option(None.as_ref());
+   |                  ~~~~~~~~~~~~~
+help: consider removing the borrow
+   |
+LL -     takes_option(&None);
+LL +     takes_option(None);
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/issue-100605.rs:8:18
+   |
+LL |     takes_option(&res);
+   |     ------------ ^^^^
+   |     |            |
+   |     |            expected enum `Option`, found `&Option<String>`
+   |     |            help: you can convert from `&Option<T>` to `Option<&T>` using `.as_ref()`: `res.as_ref()`
+   |     arguments to this function are incorrect
+   |
+   = note:   expected enum `Option<&String>`
+           found reference `&Option<String>`
+note: function defined here
+  --> $DIR/issue-100605.rs:1:4
+   |
+LL | fn takes_option(_arg: Option<&String>) {}
+   |    ^^^^^^^^^^^^ ---------------------
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-16538.mir.stderr b/src/test/ui/issues/issue-16538.mir.stderr
index 7dab7de7619..e320df4b7ad 100644
--- a/src/test/ui/issues/issue-16538.mir.stderr
+++ b/src/test/ui/issues/issue-16538.mir.stderr
@@ -5,6 +5,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
   --> $DIR/issue-16538.rs:14:30
diff --git a/src/test/ui/issues/issue-16538.thir.stderr b/src/test/ui/issues/issue-16538.thir.stderr
index a18b0197d87..4a862869274 100644
--- a/src/test/ui/issues/issue-16538.thir.stderr
+++ b/src/test/ui/issues/issue-16538.thir.stderr
@@ -21,6 +21,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr
index ea493c58a33..2db60b641ee 100644
--- a/src/test/ui/issues/issue-20413.stderr
+++ b/src/test/ui/issues/issue-20413.stderr
@@ -14,13 +14,13 @@ LL | impl<T> Foo for T where NoData<T>: Foo {
    |                                    ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Foo` for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
   --> $DIR/issue-20413.rs:8:9
    |
 LL | impl<T> Foo for T where NoData<T>: Foo {
    |         ^^^     ^
    = note: 127 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Foo` for `NoData<T>`
+   = note: required for `NoData<T>` to implement `Foo`
 
 error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz`
   --> $DIR/issue-20413.rs:27:42
@@ -29,18 +29,18 @@ LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |                                          ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
   --> $DIR/issue-20413.rs:27:9
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |         ^^^     ^
-note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
   --> $DIR/issue-20413.rs:34:9
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |         ^^^     ^
    = note: 126 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Baz` for `EvenLessData<T>`
+   = note: required for `EvenLessData<T>` to implement `Baz`
 
 error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar`
   --> $DIR/issue-20413.rs:34:42
@@ -49,18 +49,18 @@ LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |                                          ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required because of the requirements on the impl of `Baz` for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
   --> $DIR/issue-20413.rs:34:9
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |         ^^^     ^
-note: required because of the requirements on the impl of `Bar` for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
   --> $DIR/issue-20413.rs:27:9
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |         ^^^     ^
    = note: 126 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Bar` for `AlmostNoData<T>`
+   = note: required for `AlmostNoData<T>` to implement `Bar`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-20605.stderr b/src/test/ui/issues/issue-20605.stderr
index 41eefe3f8e9..b41b602a55b 100644
--- a/src/test/ui/issues/issue-20605.stderr
+++ b/src/test/ui/issues/issue-20605.stderr
@@ -5,7 +5,7 @@ LL |     for item in *things { *item = 0 }
    |                 ^^^^^^^ expected an implementor of trait `IntoIterator`
    |
    = note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
-   = note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator<Item = &'a mut u8>`
+   = note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
 help: consider mutably borrowing here
    |
 LL |     for item in &mut *things { *item = 0 }
diff --git a/src/test/ui/issues/issue-21763.stderr b/src/test/ui/issues/issue-21763.stderr
index b8b38c0a723..79068158924 100644
--- a/src/test/ui/issues/issue-21763.stderr
+++ b/src/test/ui/issues/issue-21763.stderr
@@ -6,7 +6,7 @@ LL |     foo::<HashMap<Rc<()>, Rc<()>>>();
    |
    = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>`
    = note: required because it appears within the type `(Rc<()>, Rc<()>)`
-   = note: required because of the requirements on the impl of `Send` for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>`
+   = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send`
    = note: required because it appears within the type `hashbrown::map::HashMap<Rc<()>, Rc<()>, RandomState>`
    = note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>`
 note: required by a bound in `foo`
diff --git a/src/test/ui/issues/issue-22872.stderr b/src/test/ui/issues/issue-22872.stderr
index a84cb7d8c59..7382d40c010 100644
--- a/src/test/ui/issues/issue-22872.stderr
+++ b/src/test/ui/issues/issue-22872.stderr
@@ -5,7 +5,7 @@ LL |     let _: Box<dyn for<'b> Wrap<'b>> = Box::new(Wrapper(process));
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^ `<P as Process<'_>>::Item` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `<P as Process<'_>>::Item`
-note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for `Wrapper<P>`
+note: required for `Wrapper<P>` to implement `for<'b> Wrap<'b>`
   --> $DIR/issue-22872.rs:7:13
    |
 LL | impl<'b, P> Wrap<'b> for Wrapper<P>
diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr
index 7519e632d54..3d8e7b96918 100644
--- a/src/test/ui/issues/issue-23122-2.stderr
+++ b/src/test/ui/issues/issue-23122-2.stderr
@@ -5,7 +5,7 @@ LL |     type Next = <GetNext<T::Next> as Next>::Next;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
-note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
+note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
   --> $DIR/issue-23122-2.rs:9:15
    |
 LL | impl<T: Next> Next for GetNext<T> {
diff --git a/src/test/ui/issues/issue-25901.stderr b/src/test/ui/issues/issue-25901.stderr
index e933745c44e..c6c80e41cf6 100644
--- a/src/test/ui/issues/issue-25901.stderr
+++ b/src/test/ui/issues/issue-25901.stderr
@@ -16,6 +16,7 @@ note: impl defined here, but it is not `const`
 LL | impl Deref for A {
    | ^^^^^^^^^^^^^^^^
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr
index e89105540df..0b8222088b8 100644
--- a/src/test/ui/issues/issue-31173.stderr
+++ b/src/test/ui/issues/issue-31173.stderr
@@ -18,16 +18,16 @@ error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std:
 LL |         .collect();
    |          ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>` due to unsatisfied trait bounds
    |
-  ::: $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
-   |
-LL | pub struct Cloned<I> {
-   | -------------------- doesn't satisfy `_: Iterator`
-   |
   ::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
    |
 LL | pub struct TakeWhile<I, P> {
    | -------------------------- doesn't satisfy `<_ as Iterator>::Item = &_`
    |
+  ::: $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
+   |
+LL | pub struct Cloned<I> {
+   | -------------------- doesn't satisfy `_: Iterator`
+   |
    = note: the following trait bounds were not satisfied:
            `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_`
            which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
diff --git a/src/test/ui/issues/issue-32709.stderr b/src/test/ui/issues/issue-32709.stderr
index 112cb335932..1d595ca5649 100644
--- a/src/test/ui/issues/issue-32709.stderr
+++ b/src/test/ui/issues/issue-32709.stderr
@@ -10,7 +10,7 @@ LL |     Err(5)?;
    = help: the following other types implement trait `FromResidual<R>`:
              <Result<T, F> as FromResidual<Result<Infallible, E>>>
              <Result<T, F> as FromResidual<Yeet<E>>>
-   = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>`
+   = note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-33941.stderr b/src/test/ui/issues/issue-33941.stderr
index 565a7fef379..caba0ad5268 100644
--- a/src/test/ui/issues/issue-33941.stderr
+++ b/src/test/ui/issues/issue-33941.stderr
@@ -20,8 +20,8 @@ LL |     for _ in HashMap::new().iter().cloned() {}
    |
    = note:  expected tuple `(&_, &_)`
            found reference `&_`
-   = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
-   = note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
+   = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
+   = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator`
 
 error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
   --> $DIR/issue-33941.rs:6:14
@@ -31,7 +31,7 @@ LL |     for _ in HashMap::new().iter().cloned() {}
    |
    = note:  expected tuple `(&_, &_)`
            found reference `&_`
-   = note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
+   = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-38821.stderr b/src/test/ui/issues/issue-38821.stderr
index cdf1f0dfc53..9abd2436b8a 100644
--- a/src/test/ui/issues/issue-38821.stderr
+++ b/src/test/ui/issues/issue-38821.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not sat
 LL | #[derive(Debug, Copy, Clone)]
    |                 ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`
    |
-note: required because of the requirements on the impl of `IntoNullable` for `<Col as Expression>::SqlType`
+note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
   --> $DIR/issue-38821.rs:9:18
    |
 LL | impl<T: NotNull> IntoNullable for T {
diff --git a/src/test/ui/issues/issue-39970.stderr b/src/test/ui/issues/issue-39970.stderr
index 1f64a90bc1c..774575d1d01 100644
--- a/src/test/ui/issues/issue-39970.stderr
+++ b/src/test/ui/issues/issue-39970.stderr
@@ -9,7 +9,7 @@ note: expected this to be `()`
    |
 LL |     type Element = &'a ();
    |                    ^^^^^^
-note: required because of the requirements on the impl of `Visit` for `()`
+note: required for `()` to implement `Visit`
   --> $DIR/issue-39970.rs:13:6
    |
 LL | impl Visit for () where
diff --git a/src/test/ui/issues/issue-40827.stderr b/src/test/ui/issues/issue-40827.stderr
index 11c23e5b659..7f5c578ae4f 100644
--- a/src/test/ui/issues/issue-40827.stderr
+++ b/src/test/ui/issues/issue-40827.stderr
@@ -12,7 +12,7 @@ note: required because it appears within the type `Bar`
    |
 LL | enum Bar {
    |      ^^^
-   = note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
+   = note: required for `Arc<Bar>` to implement `Send`
 note: required because it appears within the type `Foo`
   --> $DIR/issue-40827.rs:4:8
    |
@@ -38,7 +38,7 @@ note: required because it appears within the type `Bar`
    |
 LL | enum Bar {
    |      ^^^
-   = note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
+   = note: required for `Arc<Bar>` to implement `Send`
 note: required because it appears within the type `Foo`
   --> $DIR/issue-40827.rs:4:8
    |
diff --git a/src/test/ui/issues/issue-41974.stderr b/src/test/ui/issues/issue-41974.stderr
index fcbb4014025..e249db9df53 100644
--- a/src/test/ui/issues/issue-41974.stderr
+++ b/src/test/ui/issues/issue-41974.stderr
@@ -7,11 +7,11 @@ LL | impl<T> Drop for T where T: A {
    = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
    = note: only traits defined in the current crate can be implemented for a type parameter
 
-error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
+error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
   --> $DIR/issue-41974.rs:7:18
    |
 LL | impl<T> Drop for T where T: A {
-   |                  ^ must be a struct, enum, or union
+   |                  ^ must be a struct, enum, or union in the current crate
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
index 733456a1a8b..37e2c3bddc8 100644
--- a/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
+++ b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
@@ -6,7 +6,7 @@ LL |     let _ = Pin::new(Apple) == Rc::pin(Apple);
    |
    = note: expected struct `Apple`
               found struct `Rc<Apple>`
-   = note: required because of the requirements on the impl of `PartialEq<Pin<Rc<Apple>>>` for `Pin<Apple>`
+   = note: required for `Pin<Apple>` to implement `PartialEq<Pin<Rc<Apple>>>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-7364.stderr b/src/test/ui/issues/issue-7364.stderr
index 1018a92f64d..5dc8c2b607e 100644
--- a/src/test/ui/issues/issue-7364.stderr
+++ b/src/test/ui/issues/issue-7364.stderr
@@ -5,7 +5,7 @@ LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
    |               ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<isize>`
-   = note: required because of the requirements on the impl of `Sync` for `Unique<RefCell<isize>>`
+   = note: required for `Unique<RefCell<isize>>` to implement `Sync`
    = note: required because it appears within the type `Box<RefCell<isize>>`
    = note: shared static variables must have a type that implements `Sync`
 
diff --git a/src/test/ui/iterators/integral.stderr b/src/test/ui/iterators/integral.stderr
index 5e2744bab95..047a71f98d9 100644
--- a/src/test/ui/iterators/integral.stderr
+++ b/src/test/ui/iterators/integral.stderr
@@ -6,7 +6,7 @@ LL |     for _ in 42 {}
    |
    = help: the trait `Iterator` is not implemented for `{integer}`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
+   = note: required for `{integer}` to implement `IntoIterator`
 
 error[E0277]: `u8` is not an iterator
   --> $DIR/integral.rs:4:14
@@ -16,7 +16,7 @@ LL |     for _ in 42 as u8 {}
    |
    = help: the trait `Iterator` is not implemented for `u8`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `u8`
+   = note: required for `u8` to implement `IntoIterator`
 
 error[E0277]: `i8` is not an iterator
   --> $DIR/integral.rs:6:14
@@ -26,7 +26,7 @@ LL |     for _ in 42 as i8 {}
    |
    = help: the trait `Iterator` is not implemented for `i8`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `i8`
+   = note: required for `i8` to implement `IntoIterator`
 
 error[E0277]: `u16` is not an iterator
   --> $DIR/integral.rs:8:14
@@ -36,7 +36,7 @@ LL |     for _ in 42 as u16 {}
    |
    = help: the trait `Iterator` is not implemented for `u16`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `u16`
+   = note: required for `u16` to implement `IntoIterator`
 
 error[E0277]: `i16` is not an iterator
   --> $DIR/integral.rs:10:14
@@ -46,7 +46,7 @@ LL |     for _ in 42 as i16 {}
    |
    = help: the trait `Iterator` is not implemented for `i16`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `i16`
+   = note: required for `i16` to implement `IntoIterator`
 
 error[E0277]: `u32` is not an iterator
   --> $DIR/integral.rs:12:14
@@ -56,7 +56,7 @@ LL |     for _ in 42 as u32 {}
    |
    = help: the trait `Iterator` is not implemented for `u32`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `u32`
+   = note: required for `u32` to implement `IntoIterator`
 
 error[E0277]: `i32` is not an iterator
   --> $DIR/integral.rs:14:14
@@ -66,7 +66,7 @@ LL |     for _ in 42 as i32 {}
    |
    = help: the trait `Iterator` is not implemented for `i32`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `i32`
+   = note: required for `i32` to implement `IntoIterator`
 
 error[E0277]: `u64` is not an iterator
   --> $DIR/integral.rs:16:14
@@ -76,7 +76,7 @@ LL |     for _ in 42 as u64 {}
    |
    = help: the trait `Iterator` is not implemented for `u64`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `u64`
+   = note: required for `u64` to implement `IntoIterator`
 
 error[E0277]: `i64` is not an iterator
   --> $DIR/integral.rs:18:14
@@ -86,7 +86,7 @@ LL |     for _ in 42 as i64 {}
    |
    = help: the trait `Iterator` is not implemented for `i64`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `i64`
+   = note: required for `i64` to implement `IntoIterator`
 
 error[E0277]: `usize` is not an iterator
   --> $DIR/integral.rs:20:14
@@ -96,7 +96,7 @@ LL |     for _ in 42 as usize {}
    |
    = help: the trait `Iterator` is not implemented for `usize`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `usize`
+   = note: required for `usize` to implement `IntoIterator`
 
 error[E0277]: `isize` is not an iterator
   --> $DIR/integral.rs:22:14
@@ -106,7 +106,7 @@ LL |     for _ in 42 as isize {}
    |
    = help: the trait `Iterator` is not implemented for `isize`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `isize`
+   = note: required for `isize` to implement `IntoIterator`
 
 error[E0277]: `{float}` is not an iterator
   --> $DIR/integral.rs:24:14
@@ -115,7 +115,7 @@ LL |     for _ in 42.0 {}
    |              ^^^^ `{float}` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `{float}`
-   = note: required because of the requirements on the impl of `IntoIterator` for `{float}`
+   = note: required for `{float}` to implement `IntoIterator`
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/iterators/issue-28098.rs b/src/test/ui/iterators/issue-28098.rs
index 62a90d90d12..c4addaccefc 100644
--- a/src/test/ui/iterators/issue-28098.rs
+++ b/src/test/ui/iterators/issue-28098.rs
@@ -1,7 +1,6 @@
 fn main() {
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
-    //~| ERROR `()` is not an iterator
 
     for _ in false {}
     //~^ ERROR `bool` is not an iterator
@@ -17,7 +16,6 @@ pub fn other() {
 
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
-    //~| ERROR `()` is not an iterator
 
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
diff --git a/src/test/ui/iterators/issue-28098.stderr b/src/test/ui/iterators/issue-28098.stderr
index 3beb9929244..53b610c1723 100644
--- a/src/test/ui/iterators/issue-28098.stderr
+++ b/src/test/ui/iterators/issue-28098.stderr
@@ -9,16 +9,16 @@ LL |     let _ = Iterator::next(&mut ());
    = help: the trait `Iterator` is not implemented for `()`
 
 error[E0277]: `bool` is not an iterator
-  --> $DIR/issue-28098.rs:6:14
+  --> $DIR/issue-28098.rs:5:14
    |
 LL |     for _ in false {}
    |              ^^^^^ `bool` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `bool`
-   = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+   = note: required for `bool` to implement `IntoIterator`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:9:28
+  --> $DIR/issue-28098.rs:8:28
    |
 LL |     let _ = Iterator::next(&mut ());
    |             -------------- ^^^^^^^ `()` is not an iterator
@@ -28,15 +28,7 @@ LL |     let _ = Iterator::next(&mut ());
    = help: the trait `Iterator` is not implemented for `()`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:2:13
-   |
-LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
-
-error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:18:28
+  --> $DIR/issue-28098.rs:17:28
    |
 LL |     let _ = Iterator::next(&mut ());
    |             -------------- ^^^^^^^ `()` is not an iterator
@@ -46,7 +38,7 @@ LL |     let _ = Iterator::next(&mut ());
    = help: the trait `Iterator` is not implemented for `()`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:22:28
+  --> $DIR/issue-28098.rs:20:28
    |
 LL |     let _ = Iterator::next(&mut ());
    |             -------------- ^^^^^^^ `()` is not an iterator
@@ -56,22 +48,14 @@ LL |     let _ = Iterator::next(&mut ());
    = help: the trait `Iterator` is not implemented for `()`
 
 error[E0277]: `bool` is not an iterator
-  --> $DIR/issue-28098.rs:25:14
+  --> $DIR/issue-28098.rs:23:14
    |
 LL |     for _ in false {}
    |              ^^^^^ `bool` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `bool`
-   = note: required because of the requirements on the impl of `IntoIterator` for `bool`
-
-error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:18:13
-   |
-LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
+   = note: required for `bool` to implement `IntoIterator`
 
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/iterators/ranges.stderr b/src/test/ui/iterators/ranges.stderr
index 440a8960a4c..b9fbcd5304b 100644
--- a/src/test/ui/iterators/ranges.stderr
+++ b/src/test/ui/iterators/ranges.stderr
@@ -6,7 +6,7 @@ LL |     for _ in ..10 {}
    |
    = help: the trait `Iterator` is not implemented for `RangeTo<{integer}>`
    = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>`
+   = note: required for `RangeTo<{integer}>` to implement `IntoIterator`
 
 error[E0277]: `RangeToInclusive<{integer}>` is not an iterator
   --> $DIR/ranges.rs:4:14
@@ -16,7 +16,7 @@ LL |     for _ in ..=10 {}
    |
    = help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>`
    = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end`
-   = note: required because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>`
+   = note: required for `RangeToInclusive<{integer}>` to implement `IntoIterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/iterators/string.stderr b/src/test/ui/iterators/string.stderr
index d9c40fe1ba6..ddfe0169b84 100644
--- a/src/test/ui/iterators/string.stderr
+++ b/src/test/ui/iterators/string.stderr
@@ -5,7 +5,7 @@ LL |     for _ in "".to_owned() {}
    |              ^^^^^^^^^^^^^ `String` is not an iterator; try calling `.chars()` or `.bytes()`
    |
    = help: the trait `Iterator` is not implemented for `String`
-   = note: required because of the requirements on the impl of `IntoIterator` for `String`
+   = note: required for `String` to implement `IntoIterator`
 
 error[E0277]: `&str` is not an iterator
   --> $DIR/string.rs:4:14
@@ -14,7 +14,7 @@ LL |     for _ in "" {}
    |              ^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()`
    |
    = help: the trait `Iterator` is not implemented for `&str`
-   = note: required because of the requirements on the impl of `IntoIterator` for `&str`
+   = note: required for `&str` to implement `IntoIterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.stderr b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
index 89975e9683d..06d48ff1f0f 100644
--- a/src/test/ui/kindck/kindck-impl-type-params-2.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
@@ -6,7 +6,7 @@ LL |     take_param(&x);
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
+note: required for `Box<{integer}>` to implement `Foo`
   --> $DIR/kindck-impl-type-params-2.rs:6:14
    |
 LL | impl<T:Copy> Foo for T {
diff --git a/src/test/ui/kindck/kindck-impl-type-params.stderr b/src/test/ui/kindck/kindck-impl-type-params.stderr
index 902349135c5..8dbe0c38c1e 100644
--- a/src/test/ui/kindck/kindck-impl-type-params.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL |     let a = &t as &dyn Gettable<T>;
    |             ^^ `T` cannot be sent between threads safely
    |
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -21,7 +21,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL |     let a = &t as &dyn Gettable<T>;
    |             ^^ the trait `Copy` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -38,7 +38,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL |     let a: &dyn Gettable<T> = &t;
    |                               ^^ `T` cannot be sent between threads safely
    |
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -55,7 +55,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
 LL |     let a: &dyn Gettable<T> = &t;
    |                               ^^ the trait `Copy` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+note: required for `S<T>` to implement `Gettable<T>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -73,7 +73,7 @@ LL |     let a = t as Box<dyn Gettable<String>>;
    |             ^ the trait `Copy` is not implemented for `String`
    |
    = help: the trait `Gettable<T>` is implemented for `S<T>`
-note: required because of the requirements on the impl of `Gettable<String>` for `S<String>`
+note: required for `S<String>` to implement `Gettable<String>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
@@ -87,7 +87,7 @@ LL |     let a: Box<dyn Gettable<Foo>> = t;
    |                                     ^ the trait `Copy` is not implemented for `Foo`
    |
    = help: the trait `Gettable<T>` is implemented for `S<T>`
-note: required because of the requirements on the impl of `Gettable<Foo>` for `S<Foo>`
+note: required for `S<Foo>` to implement `Gettable<Foo>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
index 016cd393c85..09661289a9b 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
@@ -6,7 +6,7 @@ LL |     take_param(&x);
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
+note: required for `Box<{integer}>` to implement `Foo`
   --> $DIR/kindck-inherited-copy-bound.rs:14:14
    |
 LL | impl<T:Copy> Foo for T {
@@ -44,7 +44,7 @@ LL | trait Foo : Copy {
    |       ---   ^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box<{integer}>`
+   = note: required for `&Box<{integer}>` to implement `CoerceUnsized<&dyn Foo>`
    = note: required by cast to type `&dyn Foo`
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
index eaf34dff41b..299600eb6bf 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
@@ -6,7 +6,7 @@ LL |     take_param(&x);
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Foo` for `Box<{integer}>`
+note: required for `Box<{integer}>` to implement `Foo`
   --> $DIR/kindck-inherited-copy-bound.rs:14:14
    |
 LL | impl<T:Copy> Foo for T {
@@ -30,7 +30,7 @@ LL | trait Foo : Copy {
    |       ---   ^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box<i32>`
+   = note: required for `&Box<i32>` to implement `CoerceUnsized<&dyn Foo>`
    = note: required by cast to type `&dyn Foo`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/kindck/kindck-send-object.stderr b/src/test/ui/kindck/kindck-send-object.stderr
index f14983a5189..47b7462a6a1 100644
--- a/src/test/ui/kindck/kindck-send-object.stderr
+++ b/src/test/ui/kindck/kindck-send-object.stderr
@@ -5,7 +5,7 @@ LL |     assert_send::<&'static (dyn Dummy + 'static)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
-   = note: required because of the requirements on the impl of `Send` for `&'static (dyn Dummy + 'static)`
+   = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object.rs:5:18
    |
@@ -19,7 +19,7 @@ LL |     assert_send::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `dyn Dummy`
-   = note: required because of the requirements on the impl of `Send` for `Unique<dyn Dummy>`
+   = note: required for `Unique<dyn Dummy>` to implement `Send`
    = note: required because it appears within the type `Box<dyn Dummy>`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object.rs:5:18
diff --git a/src/test/ui/kindck/kindck-send-object1.stderr b/src/test/ui/kindck/kindck-send-object1.stderr
index 1f5e21cbf97..24428266cc7 100644
--- a/src/test/ui/kindck/kindck-send-object1.stderr
+++ b/src/test/ui/kindck/kindck-send-object1.stderr
@@ -5,7 +5,7 @@ LL |     assert_send::<&'a dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`
-   = note: required because of the requirements on the impl of `Send` for `&'a (dyn Dummy + 'a)`
+   = note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object1.rs:5:18
    |
@@ -19,7 +19,7 @@ LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)`
-   = note: required because of the requirements on the impl of `Send` for `Unique<(dyn Dummy + 'a)>`
+   = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send`
    = note: required because it appears within the type `Box<(dyn Dummy + 'a)>`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object1.rs:5:18
diff --git a/src/test/ui/kindck/kindck-send-object2.stderr b/src/test/ui/kindck/kindck-send-object2.stderr
index 527127e95a2..81ec65950d8 100644
--- a/src/test/ui/kindck/kindck-send-object2.stderr
+++ b/src/test/ui/kindck/kindck-send-object2.stderr
@@ -5,7 +5,7 @@ LL |     assert_send::<&'static dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
-   = note: required because of the requirements on the impl of `Send` for `&'static (dyn Dummy + 'static)`
+   = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object2.rs:3:18
    |
@@ -19,7 +19,7 @@ LL |     assert_send::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `dyn Dummy`
-   = note: required because of the requirements on the impl of `Send` for `Unique<dyn Dummy>`
+   = note: required for `Unique<dyn Dummy>` to implement `Send`
    = note: required because it appears within the type `Box<dyn Dummy>`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object2.rs:3:18
diff --git a/src/test/ui/kindck/kindck-send-owned.stderr b/src/test/ui/kindck/kindck-send-owned.stderr
index 454291aa95b..076c4295982 100644
--- a/src/test/ui/kindck/kindck-send-owned.stderr
+++ b/src/test/ui/kindck/kindck-send-owned.stderr
@@ -5,7 +5,7 @@ LL |     assert_send::<Box<*mut u8>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `*mut u8`
-   = note: required because of the requirements on the impl of `Send` for `Unique<*mut u8>`
+   = note: required for `Unique<*mut u8>` to implement `Send`
    = note: required because it appears within the type `Box<*mut u8>`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-owned.rs:3:18
diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr
index 3b2a062c1c2..ad11f72a31d 100644
--- a/src/test/ui/lexical-scopes.stderr
+++ b/src/test/ui/lexical-scopes.stderr
@@ -1,6 +1,8 @@
 error[E0574]: expected struct, variant or union type, found type parameter `T`
   --> $DIR/lexical-scopes.rs:3:13
    |
+LL | fn f<T>() {
+   |      - found this type pararmeter
 LL |     let t = T { i: 0 };
    |             ^ not a struct, variant or union type
 
diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs
new file mode 100644
index 00000000000..1bc4a381257
--- /dev/null
+++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs
@@ -0,0 +1,30 @@
+// edition:2018
+// compile-flags: -Zdrop-tracking
+#![feature(must_not_suspend)]
+#![deny(must_not_suspend)]
+
+#[must_not_suspend = "You gotta use Umm's, ya know?"]
+struct Umm {
+    i: i64
+}
+
+struct Bar {
+    u: Umm,
+}
+
+async fn other() {}
+
+impl Bar {
+    async fn uhoh(&mut self) {
+        let guard = &mut self.u; //~ ERROR `Umm` held across
+
+        other().await;
+
+        *guard = Umm {
+            i: 2
+        }
+    }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr
new file mode 100644
index 00000000000..c49d2712853
--- /dev/null
+++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr
@@ -0,0 +1,27 @@
+error: reference to `Umm` held across a suspend point, but should not be
+  --> $DIR/ref-drop-tracking.rs:19:13
+   |
+LL |         let guard = &mut self.u;
+   |             ^^^^^
+LL |
+LL |         other().await;
+   |                ------ the value is held across this suspend point
+   |
+note: the lint level is defined here
+  --> $DIR/ref-drop-tracking.rs:4:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
+note: You gotta use Umm's, ya know?
+  --> $DIR/ref-drop-tracking.rs:19:13
+   |
+LL |         let guard = &mut self.u;
+   |             ^^^^^
+help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
+  --> $DIR/ref-drop-tracking.rs:19:13
+   |
+LL |         let guard = &mut self.u;
+   |             ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr
deleted file mode 100644
index 217392aa35b..00000000000
--- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllleak.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown debugging option: `borrowck`
-
diff --git a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr b/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr
deleted file mode 100644
index 217392aa35b..00000000000
--- a/src/test/ui/lub-glb/old-lub-glb-hr-noteq1.nllnoleak.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown debugging option: `borrowck`
-
diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs
index 8e71ed7c112..082c1abb8f2 100644
--- a/src/test/ui/macros/stringify.rs
+++ b/src/test/ui/macros/stringify.rs
@@ -3,11 +3,18 @@
 // compile-flags: --test
 
 #![feature(async_closure)]
+#![feature(box_patterns)]
+#![feature(box_syntax)]
 #![feature(const_trait_impl)]
+#![feature(decl_macro)]
 #![feature(generators)]
 #![feature(half_open_range_patterns)]
+#![feature(label_break_value)]
 #![feature(more_qualified_paths)]
 #![feature(raw_ref_op)]
+#![feature(trait_alias)]
+#![feature(try_blocks)]
+#![feature(type_ascription)]
 #![deny(unused_macros)]
 
 macro_rules! stringify_block {
diff --git a/src/test/ui/mismatched_types/E0631.rs b/src/test/ui/mismatched_types/E0631.rs
index a2939465830..83dbdb77abe 100644
--- a/src/test/ui/mismatched_types/E0631.rs
+++ b/src/test/ui/mismatched_types/E0631.rs
@@ -1,7 +1,7 @@
 #![feature(unboxed_closures)]
 
 fn foo<F: Fn(usize)>(_: F) {}
-fn bar<F: Fn<usize>>(_: F) {}
+fn bar<F: Fn<(usize,)>>(_: F) {}
 fn main() {
     fn f(_: u64) {}
     foo(|_: isize| {}); //~ ERROR type mismatch
diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr
index 4d673d45559..410ea4b0b34 100644
--- a/src/test/ui/mismatched_types/E0631.stderr
+++ b/src/test/ui/mismatched_types/E0631.stderr
@@ -27,8 +27,8 @@ LL |     bar(|_: isize| {});
 note: required by a bound in `bar`
   --> $DIR/E0631.rs:4:11
    |
-LL | fn bar<F: Fn<usize>>(_: F) {}
-   |           ^^^^^^^^^ required by this bound in `bar`
+LL | fn bar<F: Fn<(usize,)>>(_: F) {}
+   |           ^^^^^^^^^^^^ required by this bound in `bar`
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:9:9
@@ -65,8 +65,8 @@ LL |     bar(f);
 note: required by a bound in `bar`
   --> $DIR/E0631.rs:4:11
    |
-LL | fn bar<F: Fn<usize>>(_: F) {}
-   |           ^^^^^^^^^ required by this bound in `bar`
+LL | fn bar<F: Fn<(usize,)>>(_: F) {}
+   |           ^^^^^^^^^^^^ required by this bound in `bar`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs
index e817631ad5d..65c8d6a7e93 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.rs
+++ b/src/test/ui/mismatched_types/closure-arg-count.rs
@@ -1,6 +1,6 @@
 #![feature(unboxed_closures)]
 
-fn f<F: Fn<usize>>(_: F) {}
+fn f<F: Fn<(usize,)>>(_: F) {}
 fn main() {
     [1, 2, 3].sort_by(|| panic!());
     //~^ ERROR closure is expected to take
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index 3968774e357..a02ec819838 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -56,8 +56,8 @@ LL |     f(|| panic!());
 note: required by a bound in `f`
   --> $DIR/closure-arg-count.rs:3:9
    |
-LL | fn f<F: Fn<usize>>(_: F) {}
-   |         ^^^^^^^^^ required by this bound in `f`
+LL | fn f<F: Fn<(usize,)>>(_: F) {}
+   |         ^^^^^^^^^^^^ required by this bound in `f`
 help: consider changing the closure to take and ignore the expected argument
    |
 LL |     f(|_| panic!());
@@ -74,8 +74,8 @@ LL |     f(  move    || panic!());
 note: required by a bound in `f`
   --> $DIR/closure-arg-count.rs:3:9
    |
-LL | fn f<F: Fn<usize>>(_: F) {}
-   |         ^^^^^^^^^ required by this bound in `f`
+LL | fn f<F: Fn<(usize,)>>(_: F) {}
+   |         ^^^^^^^^^^^^ required by this bound in `f`
 help: consider changing the closure to take and ignore the expected argument
    |
 LL |     f(  move    |_| panic!());
diff --git a/src/test/ui/mutexguard-sync.stderr b/src/test/ui/mutexguard-sync.stderr
index b3c77b13eaf..3fbb2ddf183 100644
--- a/src/test/ui/mutexguard-sync.stderr
+++ b/src/test/ui/mutexguard-sync.stderr
@@ -7,7 +7,7 @@ LL |     test_sync(guard);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
-   = note: required because of the requirements on the impl of `Sync` for `MutexGuard<'_, Cell<i32>>`
+   = note: required for `MutexGuard<'_, Cell<i32>>` to implement `Sync`
 note: required by a bound in `test_sync`
   --> $DIR/mutexguard-sync.rs:5:17
    |
diff --git a/src/test/ui/not-panic/not-panic-safe-2.stderr b/src/test/ui/not-panic/not-panic-safe-2.stderr
index 65594702bc4..43bb31afa6f 100644
--- a/src/test/ui/not-panic/not-panic-safe-2.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-2.stderr
@@ -6,7 +6,7 @@ LL |     assert::<Rc<RefCell<i32>>>();
    |
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `Rc<RefCell<i32>>`
+   = note: required for `Rc<RefCell<i32>>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-2.rs:7:14
    |
@@ -22,7 +22,7 @@ LL |     assert::<Rc<RefCell<i32>>>();
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
    = note: required because it appears within the type `Cell<isize>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `Rc<RefCell<i32>>`
+   = note: required for `Rc<RefCell<i32>>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-2.rs:7:14
    |
diff --git a/src/test/ui/not-panic/not-panic-safe-3.stderr b/src/test/ui/not-panic/not-panic-safe-3.stderr
index db3fdb25345..ef1d1baf58b 100644
--- a/src/test/ui/not-panic/not-panic-safe-3.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-3.stderr
@@ -6,7 +6,7 @@ LL |     assert::<Arc<RefCell<i32>>>();
    |
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `Arc<RefCell<i32>>`
+   = note: required for `Arc<RefCell<i32>>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-3.rs:7:14
    |
@@ -22,7 +22,7 @@ LL |     assert::<Arc<RefCell<i32>>>();
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
    = note: required because it appears within the type `Cell<isize>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `Arc<RefCell<i32>>`
+   = note: required for `Arc<RefCell<i32>>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-3.rs:7:14
    |
diff --git a/src/test/ui/not-panic/not-panic-safe-4.stderr b/src/test/ui/not-panic/not-panic-safe-4.stderr
index 079601b39c0..a398b44d339 100644
--- a/src/test/ui/not-panic/not-panic-safe-4.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-4.stderr
@@ -6,7 +6,7 @@ LL |     assert::<&RefCell<i32>>();
    |
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `&RefCell<i32>`
+   = note: required for `&RefCell<i32>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-4.rs:6:14
    |
@@ -22,7 +22,7 @@ LL |     assert::<&RefCell<i32>>();
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
    = note: required because it appears within the type `Cell<isize>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `&RefCell<i32>`
+   = note: required for `&RefCell<i32>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-4.rs:6:14
    |
diff --git a/src/test/ui/not-panic/not-panic-safe-5.stderr b/src/test/ui/not-panic/not-panic-safe-5.stderr
index edd0f72dd3b..9617d5dfde4 100644
--- a/src/test/ui/not-panic/not-panic-safe-5.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-5.stderr
@@ -5,7 +5,7 @@ LL |     assert::<*const UnsafeCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
    = help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `*const UnsafeCell<i32>`
+   = note: required for `*const UnsafeCell<i32>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-5.rs:6:14
    |
diff --git a/src/test/ui/not-panic/not-panic-safe-6.stderr b/src/test/ui/not-panic/not-panic-safe-6.stderr
index f3b784a2956..09204d942d2 100644
--- a/src/test/ui/not-panic/not-panic-safe-6.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-6.stderr
@@ -6,7 +6,7 @@ LL |     assert::<*mut RefCell<i32>>();
    |
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `*mut RefCell<i32>`
+   = note: required for `*mut RefCell<i32>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-6.rs:6:14
    |
@@ -22,7 +22,7 @@ LL |     assert::<*mut RefCell<i32>>();
    = help: within `RefCell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<isize>`
    = note: required because it appears within the type `Cell<isize>`
    = note: required because it appears within the type `RefCell<i32>`
-   = note: required because of the requirements on the impl of `UnwindSafe` for `*mut RefCell<i32>`
+   = note: required for `*mut RefCell<i32>` to implement `UnwindSafe`
 note: required by a bound in `assert`
   --> $DIR/not-panic-safe-6.rs:6:14
    |
diff --git a/src/test/ui/object-safety/issue-19538.stderr b/src/test/ui/object-safety/issue-19538.stderr
index 7b37e1f95dc..8420637b3de 100644
--- a/src/test/ui/object-safety/issue-19538.stderr
+++ b/src/test/ui/object-safety/issue-19538.stderr
@@ -29,7 +29,7 @@ LL |     fn foo<T>(&self, val: T);
 LL | trait Bar: Foo { }
    |       --- this trait cannot be made into an object...
    = help: consider moving `foo` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
+   = note: required for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>`
    = note: required by cast to type `&mut dyn Bar`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
index 9ba3b251e66..f44de07d5da 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
@@ -12,7 +12,7 @@ LL | trait Bar {
 LL |     const X: usize;
    |           ^ ...because it contains this associated `const`
    = help: consider moving `X` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
    = note: required by cast to type `&dyn Bar`
 
 error: aborting due to previous error
diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
index 86355627c79..9a2d472d5e7 100644
--- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
@@ -12,7 +12,7 @@ LL | trait Bar {
 LL |     fn bar<T>(&self, t: T);
    |        ^^^ ...because method `bar` has generic type parameters
    = help: consider moving `bar` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
    = note: required by cast to type `&dyn Bar`
 
 error[E0038]: the trait `Bar` cannot be made into an object
@@ -29,7 +29,7 @@ LL | trait Bar {
 LL |     fn bar<T>(&self, t: T);
    |        ^^^ ...because method `bar` has generic type parameters
    = help: consider moving `bar` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
    = note: required by cast to type `&dyn Bar`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
index f48628c9d11..40a298bd1a7 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
@@ -12,7 +12,7 @@ LL | trait Bar {
 LL |     fn bar(&self, x: &Self);
    |                      ^^^^^ ...because method `bar` references the `Self` type in this parameter
    = help: consider moving `bar` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
    = note: required by cast to type `&dyn Bar`
 
 error[E0038]: the trait `Baz` cannot be made into an object
@@ -29,7 +29,7 @@ LL | trait Baz {
 LL |     fn baz(&self) -> Self;
    |                      ^^^^ ...because method `baz` references the `Self` type in its return type
    = help: consider moving `baz` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Baz>`
    = note: required by cast to type `&dyn Baz`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
index ea1c575ff8c..da87b58c9e2 100644
--- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
@@ -11,7 +11,7 @@ LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn foo() {}
    |        ^^^ ...because associated function `foo` has no `self` parameter
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<Bar>`
+   = note: required for `Box<Bar>` to implement `CoerceUnsized<Box<dyn Foo>>`
    = note: required by cast to type `Box<dyn Foo>`
 help: consider turning `foo` into a method by giving it a `&self` argument
    |
diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
index b6e4903b079..6c29c8d5f7c 100644
--- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
@@ -11,7 +11,7 @@ LL | trait Bar
    |       --- this trait cannot be made into an object...
 LL |     where Self : Sized
    |                  ^^^^^ ...because it requires `Self: Sized`
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
    = note: required by cast to type `&dyn Bar`
 
 error: aborting due to previous error
diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
index 645852c7e71..70a44ed6101 100644
--- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
+++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
@@ -11,7 +11,7 @@ LL | trait Bar : Sized {
    |       ---   ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
    = note: required by cast to type `&dyn Bar`
 
 error: aborting due to previous error
diff --git a/src/test/ui/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs
index b74957ebcd4..79c40f650db 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.rs
+++ b/src/test/ui/on-unimplemented/multiple-impls.rs
@@ -32,11 +32,8 @@ impl Index<Bar<usize>> for [i32] {
 fn main() {
     Index::index(&[] as &[i32], 2u32);
     //~^ ERROR E0277
-    //~| ERROR E0277
     Index::index(&[] as &[i32], Foo(2u32));
     //~^ ERROR E0277
-    //~| ERROR E0277
     Index::index(&[] as &[i32], Bar(2u32));
     //~^ ERROR E0277
-    //~| ERROR E0277
 }
diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr
index 06e1a222af8..6e3601d7bf4 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.stderr
+++ b/src/test/ui/on-unimplemented/multiple-impls.stderr
@@ -12,7 +12,7 @@ LL |     Index::index(&[] as &[i32], 2u32);
              <[i32] as Index<Foo<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:36:18
+  --> $DIR/multiple-impls.rs:35:18
    |
 LL |     Index::index(&[] as &[i32], Foo(2u32));
    |     ------------ ^^^^^^^^^^^^^ on impl for Foo
@@ -25,7 +25,7 @@ LL |     Index::index(&[] as &[i32], Foo(2u32));
              <[i32] as Index<Foo<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:39:18
+  --> $DIR/multiple-impls.rs:37:18
    |
 LL |     Index::index(&[] as &[i32], Bar(2u32));
    |     ------------ ^^^^^^^^^^^^^ on impl for Bar
@@ -37,39 +37,6 @@ LL |     Index::index(&[] as &[i32], Bar(2u32));
              <[i32] as Index<Bar<usize>>>
              <[i32] as Index<Foo<usize>>>
 
-error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
-  --> $DIR/multiple-impls.rs:33:5
-   |
-LL |     Index::index(&[] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^ trait message
-   |
-   = help: the trait `Index<u32>` is not implemented for `[i32]`
-   = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
-             <[i32] as Index<Foo<usize>>>
-
-error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:36:5
-   |
-LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |     ^^^^^^^^^^^^ on impl for Foo
-   |
-   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
-   = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
-             <[i32] as Index<Foo<usize>>>
-
-error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:39:5
-   |
-LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |     ^^^^^^^^^^^^ on impl for Bar
-   |
-   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
-   = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Bar<usize>>>
-             <[i32] as Index<Foo<usize>>>
-
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs
index ab3e67d01fe..b03e1f7c6a8 100644
--- a/src/test/ui/on-unimplemented/on-impl.rs
+++ b/src/test/ui/on-unimplemented/on-impl.rs
@@ -21,5 +21,4 @@ impl Index<usize> for [i32] {
 fn main() {
     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
     //~^ ERROR E0277
-    //~| ERROR E0277
 }
diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr
index 769a3d77a57..396c062cfe2 100644
--- a/src/test/ui/on-unimplemented/on-impl.stderr
+++ b/src/test/ui/on-unimplemented/on-impl.stderr
@@ -9,15 +9,6 @@ LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the trait `Index<usize>` is implemented for `[i32]`
 
-error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
-  --> $DIR/on-impl.rs:22:5
-   |
-LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
-   |
-   = help: the trait `Index<u32>` is not implemented for `[i32]`
-   = help: the trait `Index<usize>` is implemented for `[i32]`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr
index 72f67a68515..a7ec3bda85e 100644
--- a/src/test/ui/on-unimplemented/slice-index.stderr
+++ b/src/test/ui/on-unimplemented/slice-index.stderr
@@ -6,7 +6,7 @@ LL |     x[1i32];
    |
    = help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<i32>` for `[i32]`
+   = note: required for `[i32]` to implement `Index<i32>`
 
 error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
   --> $DIR/slice-index.rs:9:7
@@ -18,7 +18,7 @@ LL |     x[..1i32];
    = help: the following other types implement trait `SliceIndex<T>`:
              <RangeTo<usize> as SliceIndex<[T]>>
              <RangeTo<usize> as SliceIndex<str>>
-   = note: required because of the requirements on the impl of `Index<RangeTo<i32>>` for `[i32]`
+   = note: required for `[i32]` to implement `Index<RangeTo<i32>>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
index 6f9a631b092..dda5c0bb59d 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
@@ -7,7 +7,7 @@ fn main() {}
 
 // Test the `pat` macro fragment parser:
 macro_rules! accept_pat {
-    ($p:pat) => {}
+    ($p:pat) => {};
 }
 
 accept_pat!((p | q));
@@ -21,28 +21,28 @@ accept_pat!([p | q]);
 #[cfg(FALSE)]
 fn or_patterns() {
     // Top level of `let`:
-    let (| A | B);
+    let (A | B);
     let (A | B);
     let (A | B): u8;
     let (A | B) = 0;
     let (A | B): u8 = 0;
 
     // Top level of `for`:
-    for | A | B in 0 {}
+    for A | B in 0 {}
     for A | B in 0 {}
 
     // Top level of `while`:
-    while let | A | B = 0 {}
+    while let A | B = 0 {}
     while let A | B = 0 {}
 
     // Top level of `if`:
-    if let | A | B = 0 {}
+    if let A | B = 0 {}
     if let A | B = 0 {}
 
     // Top level of `match` arms:
     match 0 {
-        | A | B => {},
-        A | B => {},
+        A | B => {}
+        A | B => {}
     }
 
     // Functions:
@@ -68,6 +68,8 @@ fn or_patterns() {
 
     // These bind as `(prefix p) | q` as opposed to `prefix (p | q)`:
     let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
+                     //~^ WARN box pattern syntax is experimental
+                     //~| WARN unstable syntax
     let (&0 | 1);
     let (&mut 0 | 1);
     let (x @ 0 | 1);
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr
new file mode 100644
index 00000000000..c43fe192a73
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr
@@ -0,0 +1,13 @@
+warning: box pattern syntax is experimental
+  --> $DIR/or-patterns-syntactic-pass.rs:70:10
+   |
+LL |     let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
+   |          ^^^^^
+   |
+   = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information
+   = help: add `#![feature(box_patterns)]` to the crate attributes to enable
+   = warning: unstable syntax can change at any point in the future, causing a hard error!
+   = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
index afbd13e6fd9..d8346653c25 100644
--- a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
+++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.rs
@@ -3,7 +3,11 @@
 #[cfg(FALSE)]
 fn syntax() {
     foo::<T = u8, T: Ord, String>();
+    //~^ WARN associated type bounds are unstable
+    //~| WARN unstable syntax
     foo::<T = u8, 'a, T: Ord>();
+    //~^ WARN associated type bounds are unstable
+    //~| WARN unstable syntax
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr
new file mode 100644
index 00000000000..7e843c7f4d0
--- /dev/null
+++ b/src/test/ui/parser/constraints-before-generic-args-syntactic-pass.stderr
@@ -0,0 +1,24 @@
+warning: associated type bounds are unstable
+  --> $DIR/constraints-before-generic-args-syntactic-pass.rs:5:19
+   |
+LL |     foo::<T = u8, T: Ord, String>();
+   |                   ^^^^^^
+   |
+   = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
+   = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
+   = warning: unstable syntax can change at any point in the future, causing a hard error!
+   = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: associated type bounds are unstable
+  --> $DIR/constraints-before-generic-args-syntactic-pass.rs:8:23
+   |
+LL |     foo::<T = u8, 'a, T: Ord>();
+   |                       ^^^^^^
+   |
+   = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
+   = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
+   = warning: unstable syntax can change at any point in the future, causing a hard error!
+   = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/parser/fn-defined-using-def.rs b/src/test/ui/parser/fn-defined-using-def.rs
new file mode 100644
index 00000000000..21da34c47c9
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-def.rs
@@ -0,0 +1,10 @@
+// Check what happens when `def` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+def foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `def` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-def.stderr b/src/test/ui/parser/fn-defined-using-def.stderr
new file mode 100644
index 00000000000..f34329012a0
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-def.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+  --> $DIR/fn-defined-using-def.rs:6:5
+   |
+LL | def foo() {}
+   | --- ^^^ expected one of `!` or `::`
+   | |
+   | help: write `fn` instead of `def` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-defined-using-fun.rs b/src/test/ui/parser/fn-defined-using-fun.rs
new file mode 100644
index 00000000000..4f74605043e
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-fun.rs
@@ -0,0 +1,10 @@
+// Check what happens when `fun` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+fun foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `fun` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-fun.stderr b/src/test/ui/parser/fn-defined-using-fun.stderr
new file mode 100644
index 00000000000..2f6cfff350c
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-fun.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+  --> $DIR/fn-defined-using-fun.rs:6:5
+   |
+LL | fun foo() {}
+   | --- ^^^ expected one of `!` or `::`
+   | |
+   | help: write `fn` instead of `fun` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-defined-using-func.rs b/src/test/ui/parser/fn-defined-using-func.rs
new file mode 100644
index 00000000000..2dce96fdce0
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-func.rs
@@ -0,0 +1,10 @@
+// Check what happens when `func` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+func foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `func` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-func.stderr b/src/test/ui/parser/fn-defined-using-func.stderr
new file mode 100644
index 00000000000..355741e8949
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-func.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+  --> $DIR/fn-defined-using-func.rs:6:6
+   |
+LL | func foo() {}
+   | ---- ^^^ expected one of `!` or `::`
+   | |
+   | help: write `fn` instead of `func` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/fn-defined-using-function.rs b/src/test/ui/parser/fn-defined-using-function.rs
new file mode 100644
index 00000000000..fd8782728e2
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-function.rs
@@ -0,0 +1,10 @@
+// Check what happens when `function` is used to define a function, instead of `fn`
+// edition:2021
+
+#![allow(dead_code)]
+
+function foo() {}
+//~^ ERROR expected one of `!` or `::`, found `foo`
+//~^^ HELP write `fn` instead of `function` to declare a function
+
+fn main() {}
diff --git a/src/test/ui/parser/fn-defined-using-function.stderr b/src/test/ui/parser/fn-defined-using-function.stderr
new file mode 100644
index 00000000000..43c33a2cdd7
--- /dev/null
+++ b/src/test/ui/parser/fn-defined-using-function.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!` or `::`, found `foo`
+  --> $DIR/fn-defined-using-function.rs:6:10
+   |
+LL | function foo() {}
+   | -------- ^^^ expected one of `!` or `::`
+   | |
+   | help: write `fn` instead of `function` to declare a function
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr
index 4b191710c39..1c91eba68e3 100644
--- a/src/test/ui/parser/struct-literal-in-for.stderr
+++ b/src/test/ui/parser/struct-literal-in-for.stderr
@@ -24,7 +24,7 @@ LL | |     }.hi() {
    | |__________^ `bool` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `bool`
-   = note: required because of the requirements on the impl of `IntoIterator` for `bool`
+   = note: required for `bool` to implement `IntoIterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/rest-pat-syntactic.rs b/src/test/ui/pattern/rest-pat-syntactic.rs
index 9656a0b5de9..4da5a2db767 100644
--- a/src/test/ui/pattern/rest-pat-syntactic.rs
+++ b/src/test/ui/pattern/rest-pat-syntactic.rs
@@ -19,6 +19,8 @@ fn rest_patterns() {
 
     // Box patterns:
     let box ..;
+    //~^ WARN box pattern syntax is experimental
+    //~| WARN unstable syntax
 
     // In or-patterns:
     match x {
@@ -57,7 +59,7 @@ fn rest_patterns() {
         .. |
         [
             (
-                box ..,
+                box .., //~ WARN box pattern syntax is experimental
                 &(..),
                 &mut ..,
                 x @ ..
@@ -67,4 +69,5 @@ fn rest_patterns() {
         ref mut x @ ..
         => {}
     }
+    //~| WARN unstable syntax
 }
diff --git a/src/test/ui/pattern/rest-pat-syntactic.stderr b/src/test/ui/pattern/rest-pat-syntactic.stderr
new file mode 100644
index 00000000000..37019b7d5ba
--- /dev/null
+++ b/src/test/ui/pattern/rest-pat-syntactic.stderr
@@ -0,0 +1,24 @@
+warning: box pattern syntax is experimental
+  --> $DIR/rest-pat-syntactic.rs:21:9
+   |
+LL |     let box ..;
+   |         ^^^^^^
+   |
+   = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information
+   = help: add `#![feature(box_patterns)]` to the crate attributes to enable
+   = warning: unstable syntax can change at any point in the future, causing a hard error!
+   = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: box pattern syntax is experimental
+  --> $DIR/rest-pat-syntactic.rs:62:17
+   |
+LL |                 box ..,
+   |                 ^^^^^^
+   |
+   = note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information
+   = help: add `#![feature(box_patterns)]` to the crate attributes to enable
+   = warning: unstable syntax can change at any point in the future, causing a hard error!
+   = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/phantom-auto-trait.stderr b/src/test/ui/phantom-auto-trait.stderr
index 1cc653c51cf..015c8fa4cd1 100644
--- a/src/test/ui/phantom-auto-trait.stderr
+++ b/src/test/ui/phantom-auto-trait.stderr
@@ -6,7 +6,7 @@ LL |     is_zen(x)
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Zen` for `&T`
+note: required for `&T` to implement `Zen`
   --> $DIR/phantom-auto-trait.rs:10:24
    |
 LL | unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
@@ -35,7 +35,7 @@ LL |     is_zen(x)
    |     |
    |     required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Zen` for `&T`
+note: required for `&T` to implement `Zen`
   --> $DIR/phantom-auto-trait.rs:10:24
    |
 LL | unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
diff --git a/src/test/ui/range/range-1.stderr b/src/test/ui/range/range-1.stderr
index 0bbed870424..0e3bb66ab61 100644
--- a/src/test/ui/range/range-1.stderr
+++ b/src/test/ui/range/range-1.stderr
@@ -20,8 +20,8 @@ LL |     for i in false..true {}
              isize
              u128
            and 5 others
-   = note: required because of the requirements on the impl of `Iterator` for `std::ops::Range<bool>`
-   = note: required because of the requirements on the impl of `IntoIterator` for `std::ops::Range<bool>`
+   = note: required for `std::ops::Range<bool>` to implement `Iterator`
+   = note: required for `std::ops::Range<bool>` to implement `IntoIterator`
 
 error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
   --> $DIR/range-1.rs:14:17
diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr
index 89a83298471..07f82847568 100644
--- a/src/test/ui/recursion/issue-83150.stderr
+++ b/src/test/ui/recursion/issue-83150.stderr
@@ -12,7 +12,7 @@ LL |     func(&mut iter.map(|x| x + 1))
 error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>: Iterator`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
-   = note: required because of the requirements on the impl of `Iterator` for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>`
+   = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/regions/outlives-with-missing.rs b/src/test/ui/regions/outlives-with-missing.rs
new file mode 100644
index 00000000000..29d89718b58
--- /dev/null
+++ b/src/test/ui/regions/outlives-with-missing.rs
@@ -0,0 +1,16 @@
+trait HandlerFamily {
+    type Target;
+}
+
+struct HandlerWrapper<H: HandlerFamily>(H);
+
+impl<H: HandlerFamily> HandlerWrapper<H> {
+    pub fn set_handler(&self, handler: &H::Target)
+    where
+        T: Send + Sync + 'static,
+        //~^ ERROR cannot find type `T` in this scope
+    {
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/outlives-with-missing.stderr b/src/test/ui/regions/outlives-with-missing.stderr
new file mode 100644
index 00000000000..e204c918724
--- /dev/null
+++ b/src/test/ui/regions/outlives-with-missing.stderr
@@ -0,0 +1,12 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/outlives-with-missing.rs:10:9
+   |
+LL | impl<H: HandlerFamily> HandlerWrapper<H> {
+   |      - similarly named type parameter `H` defined here
+...
+LL |         T: Send + Sync + 'static,
+   |         ^ help: a type parameter with a similar name exists: `H`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs
new file mode 100644
index 00000000000..bd496875e80
--- /dev/null
+++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs
@@ -0,0 +1,21 @@
+trait Foo<T> {
+    fn foo(&self, name: T) -> usize;
+}
+
+struct Bar {
+    baz: Baz,
+}
+
+struct Baz {
+    num: usize,
+}
+
+impl<Baz> Foo<Baz> for Bar {
+    fn foo(&self, _name: Baz) -> usize {
+        match self.baz {
+            Baz { num } => num, //~ ERROR expected struct, variant or union type, found type parameter `Baz`
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
new file mode 100644
index 00000000000..d9c404e94ac
--- /dev/null
+++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
@@ -0,0 +1,12 @@
+error[E0574]: expected struct, variant or union type, found type parameter `Baz`
+  --> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
+   |
+LL | impl<Baz> Foo<Baz> for Bar {
+   |      --- found this type pararmeter
+...
+LL |             Baz { num } => num,
+   |             ^^^ not a struct, variant or union type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 6086723b5c4..7d81de43854 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -9,7 +9,7 @@ LL | | }
    | |_^ `main` can only return types that implement `Termination`
    |
    = help: the trait `Termination` is not implemented for `f32`
-   = note: required because of the requirements on the impl of `Termination` for `Result<f32, ParseFloatError>`
+   = note: required for `Result<f32, ParseFloatError>` to implement `Termination`
 note: required by a bound in `assert_test_result`
   --> $SRC_DIR/test/src/lib.rs:LL:COL
    |
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
index 9dbaffd4c15..ac61c327921 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
@@ -54,13 +54,13 @@ LL |         const _: () = check($exp);
 LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
    |
-note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
   --> $DIR/const-drop-fail.rs:28:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
    |                         ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: 1 redundant requirement hidden
-   = note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+   = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
 note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:34:19
    |
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
index 9dbaffd4c15..ac61c327921 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
@@ -54,13 +54,13 @@ LL |         const _: () = check($exp);
 LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `~const Destruct`
    |
-note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
   --> $DIR/const-drop-fail.rs:28:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
    |                         ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: 1 redundant requirement hidden
-   = note: required because of the requirements on the impl of `~const Destruct` for `ConstDropImplWithBounds<NonTrivialDrop>`
+   = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
 note: required by a bound in `check`
   --> $DIR/const-drop-fail.rs:34:19
    |
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
index 35a65facb57..0ec0d4be5f2 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
@@ -31,7 +31,7 @@ LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn foo(self: &Rc<Self>) -> usize;
    |                  ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
-   = note: required because of the requirements on the impl of `CoerceUnsized<Rc<dyn Foo>>` for `Rc<usize>`
+   = note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
    = note: required by cast to type `Rc<dyn Foo>`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
index a74752cf840..b494b448e2e 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
@@ -14,7 +14,7 @@ LL | trait Foo {
    |       --- this trait cannot be made into an object...
 LL |     fn foo(self: &Rc<Self>) -> usize;
    |                  ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
-   = note: required because of the requirements on the impl of `CoerceUnsized<Rc<dyn Foo>>` for `Rc<usize>`
+   = note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
    = note: required by cast to type `Rc<dyn Foo>`
 
 error: aborting due to previous error
diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr
index 2bc3ff4c3b6..ea9c4c82c36 100644
--- a/src/test/ui/span/issue-35987.stderr
+++ b/src/test/ui/span/issue-35987.stderr
@@ -2,7 +2,9 @@ error[E0404]: expected trait, found type parameter `Add`
   --> $DIR/issue-35987.rs:5:21
    |
 LL | impl<T: Clone, Add> Add for Foo<T> {
-   |                     ^^^ not a trait
+   |                ---  ^^^ not a trait
+   |                |
+   |                found this type pararmeter
    |
 help: consider importing this trait instead
    |
diff --git a/src/test/ui/span/lint-unused-unsafe-thir.rs b/src/test/ui/span/lint-unused-unsafe-thir.rs
index 95a537ed282..adb72c26bba 100644
--- a/src/test/ui/span/lint-unused-unsafe-thir.rs
+++ b/src/test/ui/span/lint-unused-unsafe-thir.rs
@@ -22,7 +22,7 @@ fn bad1() { unsafe {} }                  //~ ERROR: unnecessary `unsafe` block
 fn bad2() { unsafe { bad1() } }          //~ ERROR: unnecessary `unsafe` block
 unsafe fn bad3() { unsafe {} }           //~ ERROR: unnecessary `unsafe` block
 fn bad4() { unsafe { callback(||{}) } }  //~ ERROR: unnecessary `unsafe` block
-unsafe fn bad5() { unsafe { unsf() } }   //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad5() { unsafe { unsf() } }
 fn bad6() {
     unsafe {                             // don't put the warning here
         unsafe {                         //~ ERROR: unnecessary `unsafe` block
@@ -31,7 +31,7 @@ fn bad6() {
     }
 }
 unsafe fn bad7() {
-    unsafe {                             //~ ERROR: unnecessary `unsafe` block
+    unsafe {
         unsafe {                         //~ ERROR: unnecessary `unsafe` block
             unsf()
         }
diff --git a/src/test/ui/span/lint-unused-unsafe-thir.stderr b/src/test/ui/span/lint-unused-unsafe-thir.stderr
index 6654910c5cd..3bcbb759775 100644
--- a/src/test/ui/span/lint-unused-unsafe-thir.stderr
+++ b/src/test/ui/span/lint-unused-unsafe-thir.stderr
@@ -31,14 +31,6 @@ LL | fn bad4() { unsafe { callback(||{}) } }
    |             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe-thir.rs:25:20
-   |
-LL | unsafe fn bad5() { unsafe { unsf() } }
-   | ----------------   ^^^^^^ unnecessary `unsafe` block
-   | |
-   | because it's nested under this `unsafe` fn
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe-thir.rs:28:9
    |
 LL |     unsafe {                             // don't put the warning here
@@ -54,13 +46,5 @@ LL |     unsafe {
 LL |         unsafe {
    |         ^^^^^^ unnecessary `unsafe` block
 
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe-thir.rs:34:5
-   |
-LL | unsafe fn bad7() {
-   | ---------------- because it's nested under this `unsafe` fn
-LL |     unsafe {
-   |     ^^^^^^ unnecessary `unsafe` block
-
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/span/lint-unused-unsafe.mir.stderr b/src/test/ui/span/lint-unused-unsafe.mir.stderr
index 850550a1d8f..d8412908c73 100644
--- a/src/test/ui/span/lint-unused-unsafe.mir.stderr
+++ b/src/test/ui/span/lint-unused-unsafe.mir.stderr
@@ -29,17 +29,6 @@ LL | fn bad4() { unsafe { callback(||{}) } }
    |             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:30:20
-   |
-LL | unsafe fn bad5() { unsafe { unsf() } }
-   | ----------------   ^^^^^^ unnecessary `unsafe` block
-   | |
-   | because it's nested under this `unsafe` fn
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-   = note: `#[allow(unsafe_op_in_unsafe_fn)]` on by default
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:32:5
    |
 LL |     unsafe {
@@ -52,17 +41,6 @@ LL |     unsafe {
    |     ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:40:9
-   |
-LL | unsafe fn bad7() {
-   | ---------------- because it's nested under this `unsafe` fn
-LL |     unsafe {
-LL |         unsafe {
-   |         ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:74:9
    |
 LL |         unsafe {
@@ -273,90 +251,31 @@ LL |         unsafe {
    |         ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:197:13
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-LL |         unsafe {
-LL |             unsafe { unsf() }
-   |             ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:194:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:198:13
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-...
-LL |             unsafe { unsf() }
-   |             ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:199:13
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-...
-LL |             unsafe { unsf() }
-   |             ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:205:9
-   |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
-LL |         unsafe {
-   |         ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:203:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:207:13
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
-...
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
+LL |             unsf();
 LL |             unsafe { unsf() }
    |             ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:208:13
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
 ...
 LL |             unsafe { unsf() }
    |             ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:209:13
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         unsafe {
+   |         ------ because it's nested under this `unsafe` block
 ...
 LL |             unsafe { unsf() }
    |             ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:220:17
@@ -398,19 +317,12 @@ LL |         unsafe {
    |         ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:254:9
+  --> $DIR/lint-unused-unsafe.rs:255:13
    |
-LL |     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-   |     ----------------------------------------------- because it's nested under this `unsafe` fn
 LL |         unsafe {
-   |         ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:252:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |         ------ because it's nested under this `unsafe` block
+LL |             unsafe {
+   |             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:268:13
@@ -631,90 +543,31 @@ LL |         let _ = || unsafe {
    |                    ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:409:24
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-LL |         let _ = || unsafe {
-LL |             let _ = || unsafe { unsf() };
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:406:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:410:24
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-...
-LL |             let _ = || unsafe { unsf() };
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:411:24
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-...
-LL |             let _ = || unsafe { unsf() };
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:417:20
-   |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
-LL |         let _ = || unsafe {
-   |                    ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:415:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:419:24
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
-...
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             unsf();
 LL |             let _ = || unsafe { unsf() };
    |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:420:24
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
 ...
 LL |             let _ = || unsafe { unsf() };
    |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:421:24
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
 ...
 LL |             let _ = || unsafe { unsf() };
    |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:432:28
@@ -756,19 +609,12 @@ LL |         let _ = || unsafe {
    |                    ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:466:20
+  --> $DIR/lint-unused-unsafe.rs:467:24
    |
-LL |     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-   |     ----------------------------------------------- because it's nested under this `unsafe` fn
 LL |         let _ = || unsafe {
-   |                    ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:464:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |                    ------ because it's nested under this `unsafe` block
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:480:24
@@ -989,90 +835,31 @@ LL |         let _ = || unsafe {
    |                    ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:622:24
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-LL |         let _ = || unsafe {
-LL |             let _ = || unsafe { let _ = || unsf(); };
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:619:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:623:24
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-...
-LL |             let _ = || unsafe { let _ = || unsf(); };
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:624:24
-   |
-LL |     unsafe fn granularity_2() {
-   |     ------------------------- because it's nested under this `unsafe` fn
-...
-LL |             let _ = || unsafe { let _ = || unsf(); };
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:630:20
-   |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
-LL |         let _ = || unsafe {
-   |                    ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:628:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:632:24
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
-...
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
+LL |             let _ = || unsf();
 LL |             let _ = || unsafe { let _ = || unsf(); };
    |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:633:24
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
 ...
 LL |             let _ = || unsafe { let _ = || unsf(); };
    |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:634:24
    |
-LL |     unsafe fn top_level_used_2() {
-   |     ---------------------------- because it's nested under this `unsafe` fn
+LL |         let _ = || unsafe {
+   |                    ------ because it's nested under this `unsafe` block
 ...
 LL |             let _ = || unsafe { let _ = || unsf(); };
    |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:645:28
@@ -1114,19 +901,12 @@ LL |         let _ = || unsafe {
    |                    ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:679:20
+  --> $DIR/lint-unused-unsafe.rs:680:24
    |
-LL |     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-   |     ----------------------------------------------- because it's nested under this `unsafe` fn
 LL |         let _ = || unsafe {
-   |                    ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:677:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |                    ------ because it's nested under this `unsafe` block
+LL |             let _ = || unsafe {
+   |                        ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:693:24
@@ -1257,90 +1037,31 @@ LL |             let _ = || unsafe {
    |                        ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:784:28
-   |
-LL |         unsafe fn granularity_2() {
-   |         ------------------------- because it's nested under this `unsafe` fn
-LL |             let _ = || unsafe {
-LL |                 let _ = || unsafe { unsf() };
-   |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:781:17
-   |
-LL |         #[allow(unsafe_op_in_unsafe_fn)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:785:28
-   |
-LL |         unsafe fn granularity_2() {
-   |         ------------------------- because it's nested under this `unsafe` fn
-...
-LL |                 let _ = || unsafe { unsf() };
-   |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:786:28
-   |
-LL |         unsafe fn granularity_2() {
-   |         ------------------------- because it's nested under this `unsafe` fn
-...
-LL |                 let _ = || unsafe { unsf() };
-   |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:792:24
-   |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
-LL |             let _ = || unsafe {
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:790:17
-   |
-LL |         #[allow(unsafe_op_in_unsafe_fn)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:794:28
    |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
-...
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 unsf();
 LL |                 let _ = || unsafe { unsf() };
    |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:795:28
    |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
 ...
 LL |                 let _ = || unsafe { unsf() };
    |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:796:28
    |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
 ...
 LL |                 let _ = || unsafe { unsf() };
    |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:807:32
@@ -1382,19 +1103,12 @@ LL |             let _ = || unsafe {
    |                        ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:841:24
+  --> $DIR/lint-unused-unsafe.rs:842:28
    |
-LL |         unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-   |         ----------------------------------------------- because it's nested under this `unsafe` fn
 LL |             let _ = || unsafe {
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:839:17
-   |
-LL |         #[allow(unsafe_op_in_unsafe_fn)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 let _ = || unsafe {
+   |                            ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:855:28
@@ -1525,90 +1239,31 @@ LL |             let _ = || unsafe {
    |                        ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:942:28
-   |
-LL |         unsafe fn granularity_2() {
-   |         ------------------------- because it's nested under this `unsafe` fn
-LL |             let _ = || unsafe {
-LL |                 let _ = || unsafe { unsf() };
-   |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:939:17
-   |
-LL |         #[allow(unsafe_op_in_unsafe_fn)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:943:28
-   |
-LL |         unsafe fn granularity_2() {
-   |         ------------------------- because it's nested under this `unsafe` fn
-...
-LL |                 let _ = || unsafe { unsf() };
-   |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:944:28
-   |
-LL |         unsafe fn granularity_2() {
-   |         ------------------------- because it's nested under this `unsafe` fn
-...
-LL |                 let _ = || unsafe { unsf() };
-   |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:950:24
-   |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
-LL |             let _ = || unsafe {
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:948:17
-   |
-LL |         #[allow(unsafe_op_in_unsafe_fn)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:952:28
    |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
-...
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 unsf();
 LL |                 let _ = || unsafe { unsf() };
    |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:953:28
    |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
 ...
 LL |                 let _ = || unsafe { unsf() };
    |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:954:28
    |
-LL |         unsafe fn top_level_used_2() {
-   |         ---------------------------- because it's nested under this `unsafe` fn
+LL |             let _ = || unsafe {
+   |                        ------ because it's nested under this `unsafe` block
 ...
 LL |                 let _ = || unsafe { unsf() };
    |                            ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:965:32
@@ -1650,19 +1305,12 @@ LL |             let _ = || unsafe {
    |                        ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:999:24
+  --> $DIR/lint-unused-unsafe.rs:1000:28
    |
-LL |         unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-   |         ----------------------------------------------- because it's nested under this `unsafe` fn
 LL |             let _ = || unsafe {
-   |                        ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:997:17
-   |
-LL |         #[allow(unsafe_op_in_unsafe_fn)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^
+   |                        ------ because it's nested under this `unsafe` block
+LL |                 let _ = || unsafe {
+   |                            ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:1013:28
@@ -1673,21 +1321,6 @@ LL |                 let _ = || unsafe {
    |                            ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:1044:9
-   |
-LL |     unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
-   |     -------------------------------------------------- because it's nested under this `unsafe` fn
-LL |         unsafe {
-   |         ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:1045:21
-   |
-LL |             #[allow(unsafe_op_in_unsafe_fn)]
-   |                     ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:1059:29
    |
 LL |             let _ = async { unsafe {
@@ -1727,86 +1360,31 @@ LL |             let _ = async { unsafe {
    |                             ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:1074:33
-   |
-LL |     async unsafe fn async_blocks() {
-   |     ------------------------------ because it's nested under this `unsafe` fn
-...
-LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
-   |                                 ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/lint-unused-unsafe.rs:1071:17
-   |
-LL |         #[allow(unsafe_op_in_unsafe_fn)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:1075:33
-   |
-LL |     async unsafe fn async_blocks() {
-   |     ------------------------------ because it's nested under this `unsafe` fn
-...
-LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
-   |                                 ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:1076:33
-   |
-LL |     async unsafe fn async_blocks() {
-   |     ------------------------------ because it's nested under this `unsafe` fn
-...
-LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
-   |                                 ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
-  --> $DIR/lint-unused-unsafe.rs:1078:29
-   |
-LL |     async unsafe fn async_blocks() {
-   |     ------------------------------ because it's nested under this `unsafe` fn
-...
-LL |             let _ = async { unsafe {
-   |                             ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-
-error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:1080:33
    |
-LL |     async unsafe fn async_blocks() {
-   |     ------------------------------ because it's nested under this `unsafe` fn
-...
+LL |             let _ = async { unsafe {
+   |                             ------ because it's nested under this `unsafe` block
+LL |                 let _ = async { unsf() };
 LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
    |                                 ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:1081:33
    |
-LL |     async unsafe fn async_blocks() {
-   |     ------------------------------ because it's nested under this `unsafe` fn
+LL |             let _ = async { unsafe {
+   |                             ------ because it's nested under this `unsafe` block
 ...
 LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
    |                                 ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:1082:33
    |
-LL |     async unsafe fn async_blocks() {
-   |     ------------------------------ because it's nested under this `unsafe` fn
+LL |             let _ = async { unsafe {
+   |                             ------ because it's nested under this `unsafe` block
 ...
 LL |                 let _ = async { unsafe { let _ = async { unsf() }; }};
    |                                 ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
 
 error: unnecessary `unsafe` block
   --> $DIR/lint-unused-unsafe.rs:1092:22
@@ -1820,5 +1398,5 @@ error: unnecessary `unsafe` block
 LL |         let _x: [(); unsafe { unsafe { size() } }] = [];
    |                      ^^^^^^ unnecessary `unsafe` block
 
-error: aborting due to 201 previous errors
+error: aborting due to 174 previous errors
 
diff --git a/src/test/ui/span/lint-unused-unsafe.rs b/src/test/ui/span/lint-unused-unsafe.rs
index f8d1dff3572..5d042768be0 100644
--- a/src/test/ui/span/lint-unused-unsafe.rs
+++ b/src/test/ui/span/lint-unused-unsafe.rs
@@ -27,7 +27,7 @@ fn bad1() { unsafe {} }                  //~ ERROR: unnecessary `unsafe` block
 fn bad2() { unsafe { bad1() } }          //~ ERROR: unnecessary `unsafe` block
 unsafe fn bad3() { unsafe {} }           //~ ERROR: unnecessary `unsafe` block
 fn bad4() { unsafe { callback(||{}) } }  //~ ERROR: unnecessary `unsafe` block
-unsafe fn bad5() { unsafe { unsf() } }   //~ ERROR: unnecessary `unsafe` block
+unsafe fn bad5() { unsafe { unsf() } }
 fn bad6() {
     unsafe {                             //~ ERROR: unnecessary `unsafe` block
         unsafe {                         // don't put the warning here
@@ -37,7 +37,7 @@ fn bad6() {
 }
 unsafe fn bad7() {
     unsafe {                             //~ ERROR: unnecessary `unsafe` block
-        unsafe {                         //~ ERROR: unnecessary `unsafe` block
+        unsafe {
             unsf()
         }
     }
@@ -194,15 +194,15 @@ mod additional_tests {
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn granularity_2() {
         unsafe { //~ ERROR: unnecessary `unsafe` block
-            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
-            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
-            unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
+            unsafe { unsf() }
+            unsafe { unsf() }
+            unsafe { unsf() }
         }
     }
 
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn top_level_used_2() {
-        unsafe { //~ ERROR: unnecessary `unsafe` block
+        unsafe {
             unsf();
             unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
             unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block
@@ -251,8 +251,8 @@ mod additional_tests {
 
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-        unsafe { //~ ERROR: unnecessary `unsafe` block
-            unsafe {
+        unsafe {
+            unsafe { //~ ERROR: unnecessary `unsafe` block
                 #[deny(unsafe_op_in_unsafe_fn)]
                 {
                     unsf();
@@ -406,15 +406,15 @@ mod additional_tests_closures {
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn granularity_2() {
         let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { unsf() };
+            let _ = || unsafe { unsf() };
+            let _ = || unsafe { unsf() };
         };
     }
 
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn top_level_used_2() {
-        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+        let _ = || unsafe {
             unsf();
             let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
             let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
@@ -463,8 +463,8 @@ mod additional_tests_closures {
 
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe {
+        let _ = || unsafe {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
                 #[deny(unsafe_op_in_unsafe_fn)]
                 {
                     unsf();
@@ -619,15 +619,15 @@ mod additional_tests_even_more_closures {
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn granularity_2() {
         let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe { let _ = || unsf(); };
+            let _ = || unsafe { let _ = || unsf(); };
+            let _ = || unsafe { let _ = || unsf(); };
         };
     }
 
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn top_level_used_2() {
-        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+        let _ = || unsafe {
             let _ = || unsf();
             let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
             let _ = || unsafe { let _ = || unsf(); }; //~ ERROR: unnecessary `unsafe` block
@@ -676,8 +676,8 @@ mod additional_tests_even_more_closures {
 
     #[allow(unsafe_op_in_unsafe_fn)]
     unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-        let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-            let _ = || unsafe {
+        let _ = || unsafe {
+            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
                 #[deny(unsafe_op_in_unsafe_fn)]
                 {
                     let _ = || unsf();
@@ -781,15 +781,15 @@ mod item_likes {
         #[allow(unsafe_op_in_unsafe_fn)]
         unsafe fn granularity_2() {
             let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
             };
         }
 
         #[allow(unsafe_op_in_unsafe_fn)]
         unsafe fn top_level_used_2() {
-            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {
                 unsf();
                 let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
                 let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
@@ -838,8 +838,8 @@ mod item_likes {
 
         #[allow(unsafe_op_in_unsafe_fn)]
         unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe {
+            let _ = || unsafe {
+                let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
                     #[deny(unsafe_op_in_unsafe_fn)]
                     {
                         unsf();
@@ -939,15 +939,15 @@ mod item_likes {
         #[allow(unsafe_op_in_unsafe_fn)]
         unsafe fn granularity_2() {
             let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
+                let _ = || unsafe { unsf() };
             };
         }
 
         #[allow(unsafe_op_in_unsafe_fn)]
         unsafe fn top_level_used_2() {
-            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = || unsafe {
                 unsf();
                 let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
                 let _ = || unsafe { unsf() }; //~ ERROR: unnecessary `unsafe` block
@@ -996,8 +996,8 @@ mod item_likes {
 
         #[allow(unsafe_op_in_unsafe_fn)]
         unsafe fn granular_disallow_op_in_unsafe_fn_3() {
-            let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
-                let _ = || unsafe {
+            let _ = || unsafe {
+                let _ = || unsafe { //~ ERROR: unnecessary `unsafe` block
                     #[deny(unsafe_op_in_unsafe_fn)]
                     {
                         unsf();
@@ -1041,7 +1041,7 @@ mod additional_tests_extra {
 
     #[warn(unsafe_op_in_unsafe_fn)]
     unsafe fn multiple_unsafe_op_in_unsafe_fn_allows() {
-        unsafe { //~ ERROR: unnecessary `unsafe` block
+        unsafe {
             #[allow(unsafe_op_in_unsafe_fn)]
             {
                 unsf();
@@ -1071,11 +1071,11 @@ mod additional_tests_extra {
         #[allow(unsafe_op_in_unsafe_fn)]
         {
             let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
-                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
-                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
-                let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
+                let _ = async { unsafe { let _ = async { unsf() }; }};
+                let _ = async { unsafe { let _ = async { unsf() }; }};
+                let _ = async { unsafe { let _ = async { unsf() }; }};
             }};
-            let _ = async { unsafe { //~ ERROR: unnecessary `unsafe` block
+            let _ = async { unsafe {
                 let _ = async { unsf() };
                 let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
                 let _ = async { unsafe { let _ = async { unsf() }; }}; //~ ERROR: unnecessary `unsafe` block
diff --git a/src/test/ui/specialization/default-generic-associated-type-bound.stderr b/src/test/ui/specialization/default-generic-associated-type-bound.stderr
index 58c6667c8c7..6d98763a572 100644
--- a/src/test/ui/specialization/default-generic-associated-type-bound.stderr
+++ b/src/test/ui/specialization/default-generic-associated-type-bound.stderr
@@ -14,7 +14,7 @@ error[E0277]: can't compare `T` with `T`
 LL |     default type U<'a> = &'a T;
    |                          ^^^^^ no implementation for `T == T`
    |
-   = note: required because of the requirements on the impl of `PartialEq` for `&'a T`
+   = note: required for `&'a T` to implement `PartialEq`
 note: required by a bound in `X::U`
   --> $DIR/default-generic-associated-type-bound.rs:8:17
    |
diff --git a/src/test/ui/specialization/issue-38091-2.stderr b/src/test/ui/specialization/issue-38091-2.stderr
index a93f27ff051..146a56358be 100644
--- a/src/test/ui/specialization/issue-38091-2.stderr
+++ b/src/test/ui/specialization/issue-38091-2.stderr
@@ -10,7 +10,7 @@ LL | #![feature(specialization)]
 
 error[E0275]: overflow evaluating the requirement `i32: Check`
    |
-note: required because of the requirements on the impl of `Iterate` for `i32`
+note: required for `i32` to implement `Iterate`
   --> $DIR/issue-38091-2.rs:11:13
    |
 LL | impl<'a, T> Iterate<'a> for T
diff --git a/src/test/ui/specialization/issue-39448.stderr b/src/test/ui/specialization/issue-39448.stderr
index c4fc44c737e..9b74f684b8f 100644
--- a/src/test/ui/specialization/issue-39448.stderr
+++ b/src/test/ui/specialization/issue-39448.stderr
@@ -14,12 +14,12 @@ error[E0275]: overflow evaluating the requirement `T: FromA<U>`
 LL |     x.foo(y.to()).to()
    |             ^^
    |
-note: required because of the requirements on the impl of `FromA<U>` for `T`
+note: required for `T` to implement `FromA<U>`
   --> $DIR/issue-39448.rs:24:29
    |
 LL | impl<T: A, U: A + FromA<T>> FromA<T> for U {
    |                             ^^^^^^^^     ^
-note: required because of the requirements on the impl of `ToA<T>` for `U`
+note: required for `U` to implement `ToA<T>`
   --> $DIR/issue-39448.rs:34:12
    |
 LL | impl<T, U> ToA<U> for T
diff --git a/src/test/ui/specialization/issue-45814.stderr b/src/test/ui/specialization/issue-45814.stderr
index ab6adf477c9..419345addc2 100644
--- a/src/test/ui/specialization/issue-45814.stderr
+++ b/src/test/ui/specialization/issue-45814.stderr
@@ -1,13 +1,13 @@
 error[E0275]: overflow evaluating the requirement `T: Trait<_>`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
-note: required because of the requirements on the impl of `Trait<_>` for `T`
+note: required for `T` to implement `Trait<_>`
   --> $DIR/issue-45814.rs:8:20
    |
 LL | default impl<T, U> Trait<T> for U {}
    |                    ^^^^^^^^     ^
    = note: 128 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Trait<_>` for `T`
+   = note: required for `T` to implement `Trait<_>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr
index cfb9007c7a2..34da1dd12df 100644
--- a/src/test/ui/specialization/min_specialization/issue-79224.stderr
+++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `B: Clone` is not satisfied
 LL | impl<B: ?Sized> Display for Cow<'_, B> {
    |                 ^^^^^^^ the trait `Clone` is not implemented for `B`
    |
-   = note: required because of the requirements on the impl of `ToOwned` for `B`
+   = note: required for `B` to implement `ToOwned`
 help: consider further restricting this bound
    |
 LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
@@ -16,7 +16,7 @@ error[E0277]: the trait bound `B: Clone` is not satisfied
 LL |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    |            ^^^^^ the trait `Clone` is not implemented for `B`
    |
-   = note: required because of the requirements on the impl of `ToOwned` for `B`
+   = note: required for `B` to implement `ToOwned`
 help: consider further restricting this bound
    |
 LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
diff --git a/src/test/ui/static/static-vec-repeat-not-constant.stderr b/src/test/ui/static/static-vec-repeat-not-constant.stderr
index 84fc638a973..dec0123184d 100644
--- a/src/test/ui/static/static-vec-repeat-not-constant.stderr
+++ b/src/test/ui/static/static-vec-repeat-not-constant.stderr
@@ -5,6 +5,7 @@ LL | static a: [isize; 2] = [foo(); 2];
    |                         ^^^^^
    |
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr
index 9ea32e8d64e..61cb7b25e49 100644
--- a/src/test/ui/stats/hir-stats.stderr
+++ b/src/test/ui/stats/hir-stats.stderr
@@ -3,7 +3,7 @@ PRE EXPANSION AST STATS
 
 Name                Accumulated Size         Count     Item Size
 ----------------------------------------------------------------
-ExprField                 48 ( 0.5%)             1            48
+ExprField                 48 ( 0.6%)             1            48
 Attribute                 64 ( 0.7%)             2            32
 - Normal                    32 ( 0.4%)             1
 - DocComment                32 ( 0.4%)             1
@@ -14,48 +14,48 @@ WherePredicate            72 ( 0.8%)             1            72
 - BoundPredicate            72 ( 0.8%)             1
 Crate                     72 ( 0.8%)             1            72
 Arm                       96 ( 1.1%)             2            48
+ForeignItem              112 ( 1.3%)             1           112
+- Fn                       112 ( 1.3%)             1
 FieldDef                 160 ( 1.8%)             2            80
-ForeignItem              160 ( 1.8%)             1           160
-- Fn                       160 ( 1.8%)             1
 Stmt                     160 ( 1.8%)             5            32
 - Local                     32 ( 0.4%)             1
 - MacCall                   32 ( 0.4%)             1
 - Expr                      96 ( 1.1%)             3
 Param                    160 ( 1.8%)             4            40
-FnDecl                   200 ( 2.2%)             5            40
-Variant                  240 ( 2.7%)             2           120
-Block                    288 ( 3.2%)             6            48
+FnDecl                   200 ( 2.3%)             5            40
+Variant                  240 ( 2.8%)             2           120
+Block                    288 ( 3.3%)             6            48
 GenericBound             352 ( 4.0%)             4            88
 - Trait                    352 ( 4.0%)             4
-GenericParam             520 ( 5.8%)             5           104
-AssocItem                640 ( 7.2%)             4           160
-- TyAlias                  320 ( 3.6%)             2
-- Fn                       320 ( 3.6%)             2
-PathSegment              720 ( 8.1%)            30            24
-Expr                     832 ( 9.3%)             8           104
+AssocItem                480 ( 5.5%)             4           120
+- TyAlias                  240 ( 2.8%)             2
+- Fn                       240 ( 2.8%)             2
+GenericParam             520 ( 6.0%)             5           104
+PathSegment              720 ( 8.3%)            30            24
+Expr                     832 ( 9.6%)             8           104
 - Path                     104 ( 1.2%)             1
 - Match                    104 ( 1.2%)             1
 - Struct                   104 ( 1.2%)             1
-- Lit                      208 ( 2.3%)             2
-- Block                    312 ( 3.5%)             3
-Pat                      840 ( 9.4%)             7           120
-- Struct                   120 ( 1.3%)             1
-- Wild                     120 ( 1.3%)             1
-- Ident                    600 ( 6.7%)             5
-Ty                     1_344 (15.1%)            14            96
+- Lit                      208 ( 2.4%)             2
+- Block                    312 ( 3.6%)             3
+Pat                      840 ( 9.7%)             7           120
+- Struct                   120 ( 1.4%)             1
+- Wild                     120 ( 1.4%)             1
+- Ident                    600 ( 6.9%)             5
+Ty                     1_344 (15.5%)            14            96
 - Rptr                      96 ( 1.1%)             1
 - Ptr                       96 ( 1.1%)             1
 - ImplicitSelf             192 ( 2.2%)             2
-- Path                     960 (10.8%)            10
-Item                   1_800 (20.2%)             9           200
-- Trait                    200 ( 2.2%)             1
-- Enum                     200 ( 2.2%)             1
-- ForeignMod               200 ( 2.2%)             1
-- Impl                     200 ( 2.2%)             1
-- Fn                       400 ( 4.5%)             2
-- Use                      600 ( 6.7%)             3
+- Path                     960 (11.0%)            10
+Item                   1_800 (20.7%)             9           200
+- Trait                    200 ( 2.3%)             1
+- Enum                     200 ( 2.3%)             1
+- ForeignMod               200 ( 2.3%)             1
+- Impl                     200 ( 2.3%)             1
+- Fn                       400 ( 4.6%)             2
+- Use                      600 ( 6.9%)             3
 ----------------------------------------------------------------
-Total                  8_904
+Total                  8_696
 
 
 POST EXPANSION AST STATS
@@ -65,18 +65,18 @@ Name                Accumulated Size         Count     Item Size
 ExprField                 48 ( 0.5%)             1            48
 GenericArgs               64 ( 0.7%)             1            64
 - AngleBracketed            64 ( 0.7%)             1
-Local                     72 ( 0.7%)             1            72
-WherePredicate            72 ( 0.7%)             1            72
-- BoundPredicate            72 ( 0.7%)             1
-Crate                     72 ( 0.7%)             1            72
+Local                     72 ( 0.8%)             1            72
+WherePredicate            72 ( 0.8%)             1            72
+- BoundPredicate            72 ( 0.8%)             1
+Crate                     72 ( 0.8%)             1            72
 Arm                       96 ( 1.0%)             2            48
-InlineAsm                120 ( 1.2%)             1           120
-Attribute                128 ( 1.3%)             4            32
+ForeignItem              112 ( 1.2%)             1           112
+- Fn                       112 ( 1.2%)             1
+InlineAsm                120 ( 1.3%)             1           120
+Attribute                128 ( 1.4%)             4            32
 - DocComment                32 ( 0.3%)             1
 - Normal                    96 ( 1.0%)             3
 FieldDef                 160 ( 1.7%)             2            80
-ForeignItem              160 ( 1.7%)             1           160
-- Fn                       160 ( 1.7%)             1
 Stmt                     160 ( 1.7%)             5            32
 - Local                     32 ( 0.3%)             1
 - Semi                      32 ( 0.3%)             1
@@ -85,39 +85,39 @@ Param                    160 ( 1.7%)             4            40
 FnDecl                   200 ( 2.1%)             5            40
 Variant                  240 ( 2.5%)             2           120
 Block                    288 ( 3.0%)             6            48
-GenericBound             352 ( 3.6%)             4            88
-- Trait                    352 ( 3.6%)             4
-GenericParam             520 ( 5.4%)             5           104
-AssocItem                640 ( 6.6%)             4           160
-- TyAlias                  320 ( 3.3%)             2
-- Fn                       320 ( 3.3%)             2
-PathSegment              792 ( 8.2%)            33            24
-Pat                      840 ( 8.7%)             7           120
-- Struct                   120 ( 1.2%)             1
-- Wild                     120 ( 1.2%)             1
-- Ident                    600 ( 6.2%)             5
-Expr                     936 ( 9.7%)             9           104
+GenericBound             352 ( 3.7%)             4            88
+- Trait                    352 ( 3.7%)             4
+AssocItem                480 ( 5.1%)             4           120
+- TyAlias                  240 ( 2.5%)             2
+- Fn                       240 ( 2.5%)             2
+GenericParam             520 ( 5.5%)             5           104
+PathSegment              792 ( 8.4%)            33            24
+Pat                      840 ( 8.9%)             7           120
+- Struct                   120 ( 1.3%)             1
+- Wild                     120 ( 1.3%)             1
+- Ident                    600 ( 6.3%)             5
+Expr                     936 ( 9.9%)             9           104
 - Path                     104 ( 1.1%)             1
 - Match                    104 ( 1.1%)             1
 - Struct                   104 ( 1.1%)             1
 - InlineAsm                104 ( 1.1%)             1
 - Lit                      208 ( 2.2%)             2
-- Block                    312 ( 3.2%)             3
-Ty                     1_344 (13.9%)            14            96
+- Block                    312 ( 3.3%)             3
+Ty                     1_344 (14.2%)            14            96
 - Rptr                      96 ( 1.0%)             1
 - Ptr                       96 ( 1.0%)             1
 - ImplicitSelf             192 ( 2.0%)             2
-- Path                     960 ( 9.9%)            10
-Item                   2_200 (22.8%)            11           200
+- Path                     960 (10.2%)            10
+Item                   2_200 (23.3%)            11           200
 - Trait                    200 ( 2.1%)             1
 - Enum                     200 ( 2.1%)             1
 - ExternCrate              200 ( 2.1%)             1
 - ForeignMod               200 ( 2.1%)             1
 - Impl                     200 ( 2.1%)             1
-- Fn                       400 ( 4.1%)             2
-- Use                      800 ( 8.3%)             4
+- Fn                       400 ( 4.2%)             2
+- Use                      800 ( 8.5%)             4
 ----------------------------------------------------------------
-Total                  9_664
+Total                  9_456
 
 
 HIR STATS
diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr
index 9079a18d6a6..019305def29 100644
--- a/src/test/ui/str/str-idx.stderr
+++ b/src/test/ui/str/str-idx.stderr
@@ -8,7 +8,7 @@ LL |     let _: u8 = s[4];
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<{integer}>` for `str`
+   = note: required for `str` to implement `Index<{integer}>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-idx.rs:4:19
@@ -53,7 +53,7 @@ LL |     let _: u8 = s['c'];
    |                   ^^^ string indices are ranges of `usize`
    |
    = help: the trait `SliceIndex<str>` is not implemented for `char`
-   = note: required because of the requirements on the impl of `Index<char>` for `str`
+   = note: required for `str` to implement `Index<char>`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr
index 2d062e56a9b..b165c482590 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -32,7 +32,7 @@ LL |     s[1usize] = bot();
    |
    = help: the trait `SliceIndex<str>` is not implemented for `usize`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<usize>` for `str`
+   = note: required for `str` to implement `Index<usize>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-mut-idx.rs:9:15
@@ -77,7 +77,7 @@ LL |     s['c'];
    |       ^^^ string indices are ranges of `usize`
    |
    = help: the trait `SliceIndex<str>` is not implemented for `char`
-   = note: required because of the requirements on the impl of `Index<char>` for `str`
+   = note: required for `str` to implement `Index<char>`
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/suggestions/as-ref-2.fixed b/src/test/ui/suggestions/as-ref-2.fixed
deleted file mode 100644
index 13bbb233f39..00000000000
--- a/src/test/ui/suggestions/as-ref-2.fixed
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-rustfix
-
-struct Struct;
-
-fn bar(_: &Struct) -> Struct {
-    Struct
-}
-
-fn main() {
-    let foo = Some(Struct);
-    let _x: Option<Struct> = foo.as_ref().map(|s| bar(&s));
-    let _y = foo; //~ERROR use of moved value: `foo`
-}
diff --git a/src/test/ui/suggestions/as-ref-2.rs b/src/test/ui/suggestions/as-ref-2.rs
index 74d61cdd95f..b22f409b44a 100644
--- a/src/test/ui/suggestions/as-ref-2.rs
+++ b/src/test/ui/suggestions/as-ref-2.rs
@@ -1,5 +1,3 @@
-// run-rustfix
-
 struct Struct;
 
 fn bar(_: &Struct) -> Struct {
diff --git a/src/test/ui/suggestions/as-ref-2.stderr b/src/test/ui/suggestions/as-ref-2.stderr
index 3c9d0f72abe..e15e45d86b9 100644
--- a/src/test/ui/suggestions/as-ref-2.stderr
+++ b/src/test/ui/suggestions/as-ref-2.stderr
@@ -1,10 +1,12 @@
 error[E0382]: use of moved value: `foo`
-  --> $DIR/as-ref-2.rs:12:14
+  --> $DIR/as-ref-2.rs:10:14
    |
 LL |     let foo = Some(Struct);
    |         --- move occurs because `foo` has type `Option<Struct>`, which does not implement the `Copy` trait
 LL |     let _x: Option<Struct> = foo.map(|s| bar(&s));
-   |                                  ---------------- `foo` moved due to this method call
+   |                              --- ---------------- `foo` moved due to this method call
+   |                              |
+   |                              help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
 LL |     let _y = foo;
    |              ^^^ value used here after move
    |
@@ -13,10 +15,6 @@ note: this function takes ownership of the receiver `self`, which moves `foo`
    |
 LL |     pub const fn map<U, F>(self, f: F) -> Option<U>
    |                            ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
-   |
-LL |     let _x: Option<Struct> = foo.as_ref().map(|s| bar(&s));
-   |                                  +++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/derive-clone-for-eq.stderr b/src/test/ui/suggestions/derive-clone-for-eq.stderr
index 55a23c031d5..0645f0cdde7 100644
--- a/src/test/ui/suggestions/derive-clone-for-eq.stderr
+++ b/src/test/ui/suggestions/derive-clone-for-eq.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `T: Clone` is not satisfied
 LL | #[derive(Clone, Eq)]
    |                 ^^ the trait `Clone` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `PartialEq` for `Struct<T>`
+note: required for `Struct<T>` to implement `PartialEq`
   --> $DIR/derive-clone-for-eq.rs:9:19
    |
 LL | impl<T: Clone, U> PartialEq<U> for Struct<T>
diff --git a/src/test/ui/suggestions/derive-macro-missing-bounds.stderr b/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
index 4186dc7cb35..b9f7739654a 100644
--- a/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
+++ b/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
@@ -26,13 +26,13 @@ LL |     #[derive(Debug)]
 LL |     struct Outer<T>(Inner<T>);
    |                     ^^^^^^^^ the trait `c::Trait` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Debug` for `c::Inner<T>`
+note: required for `c::Inner<T>` to implement `Debug`
   --> $DIR/derive-macro-missing-bounds.rs:34:28
    |
 LL |     impl<T: Debug + Trait> Debug for Inner<T> {
    |                            ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
-   = note: required because of the requirements on the impl of `Debug` for `&c::Inner<T>`
+   = note: required for `&c::Inner<T>` to implement `Debug`
    = note: required for the cast from `&c::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
@@ -48,13 +48,13 @@ LL |     #[derive(Debug)]
 LL |     struct Outer<T>(Inner<T>);
    |                     ^^^^^^^^ the trait `d::Trait` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Debug` for `d::Inner<T>`
+note: required for `d::Inner<T>` to implement `Debug`
   --> $DIR/derive-macro-missing-bounds.rs:49:13
    |
 LL |     impl<T> Debug for Inner<T> where T: Debug, T: Trait {
    |             ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
-   = note: required because of the requirements on the impl of `Debug` for `&d::Inner<T>`
+   = note: required for `&d::Inner<T>` to implement `Debug`
    = note: required for the cast from `&d::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
@@ -70,13 +70,13 @@ LL |     #[derive(Debug)]
 LL |     struct Outer<T>(Inner<T>);
    |                     ^^^^^^^^ the trait `e::Trait` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Debug` for `e::Inner<T>`
+note: required for `e::Inner<T>` to implement `Debug`
   --> $DIR/derive-macro-missing-bounds.rs:64:13
    |
 LL |     impl<T> Debug for Inner<T> where T: Debug + Trait {
    |             ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
-   = note: required because of the requirements on the impl of `Debug` for `&e::Inner<T>`
+   = note: required for `&e::Inner<T>` to implement `Debug`
    = note: required for the cast from `&e::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
@@ -92,13 +92,13 @@ LL |     #[derive(Debug)]
 LL |     struct Outer<T>(Inner<T>);
    |                     ^^^^^^^^ the trait `f::Trait` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `Debug` for `f::Inner<T>`
+note: required for `f::Inner<T>` to implement `Debug`
   --> $DIR/derive-macro-missing-bounds.rs:79:20
    |
 LL |     impl<T: Debug> Debug for Inner<T> where T: Trait {
    |                    ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
-   = note: required because of the requirements on the impl of `Debug` for `&f::Inner<T>`
+   = note: required for `&f::Inner<T>` to implement `Debug`
    = note: required for the cast from `&f::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr
index 8ae5c847947..a56a2a188cb 100644
--- a/src/test/ui/suggestions/into-str.stderr
+++ b/src/test/ui/suggestions/into-str.stderr
@@ -14,7 +14,7 @@ LL |     foo(String::new());
              <String as From<Box<str>>>
              <String as From<Cow<'a, str>>>
              <String as From<char>>
-   = note: required because of the requirements on the impl of `Into<&str>` for `String`
+   = note: required for `String` to implement `Into<&str>`
 note: required by a bound in `foo`
   --> $DIR/into-str.rs:1:31
    |
diff --git a/src/test/ui/suggestions/issue-62843.stderr b/src/test/ui/suggestions/issue-62843.stderr
index bc1c69406d1..607e7992b9f 100644
--- a/src/test/ui/suggestions/issue-62843.stderr
+++ b/src/test/ui/suggestions/issue-62843.stderr
@@ -7,7 +7,7 @@ LL |     println!("{:?}", line.find(pattern));
    |                           required by a bound introduced by this call
    |
    = note: the trait bound `String: Pattern<'_>` is not satisfied
-   = note: required because of the requirements on the impl of `Pattern<'_>` for `String`
+   = note: required for `String` to implement `Pattern<'_>`
 note: required by a bound in `core::str::<impl str>::find`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
    |
diff --git a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr
index 383f40d47fa..a5e6f5b5ffc 100644
--- a/src/test/ui/suggestions/issue-71394-no-from-impl.stderr
+++ b/src/test/ui/suggestions/issue-71394-no-from-impl.stderr
@@ -7,7 +7,7 @@ LL |     let _: &[i8] = data.into();
    = help: the following other types implement trait `From<T>`:
              <[T; LANES] as From<Simd<T, LANES>>>
              <[bool; LANES] as From<Mask<T, LANES>>>
-   = note: required because of the requirements on the impl of `Into<&[i8]>` for `&[u8]`
+   = note: required for `&[u8]` to implement `Into<&[i8]>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/issue-96223.stderr b/src/test/ui/suggestions/issue-96223.stderr
index 513725d9962..72a9a739a64 100644
--- a/src/test/ui/suggestions/issue-96223.stderr
+++ b/src/test/ui/suggestions/issue-96223.stderr
@@ -7,12 +7,12 @@ LL |     icey_bounds(&p);
    |     required by a bound introduced by this call
    |
    = help: the trait `Foo<'de>` is implemented for `Baz<T>`
-note: required because of the requirements on the impl of `for<'de> Foo<'de>` for `Baz<EmptyBis<'de>>`
+note: required for `Baz<EmptyBis<'de>>` to implement `for<'de> Foo<'de>`
   --> $DIR/issue-96223.rs:16:14
    |
 LL | impl<'de, T> Foo<'de> for Baz<T> where T: Foo<'de> {}
    |              ^^^^^^^^     ^^^^^^
-note: required because of the requirements on the impl of `Dummy<EmptyMarker>` for `Empty`
+note: required for `Empty` to implement `Dummy<EmptyMarker>`
   --> $DIR/issue-96223.rs:20:9
    |
 LL | impl<M> Dummy<M> for Empty
diff --git a/src/test/ui/suggestions/issue-96555.stderr b/src/test/ui/suggestions/issue-96555.stderr
index a1a603cf246..9a8a183dc2d 100644
--- a/src/test/ui/suggestions/issue-96555.stderr
+++ b/src/test/ui/suggestions/issue-96555.stderr
@@ -8,7 +8,7 @@ LL |     m::f1().await;
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
-   = note: required because of the requirements on the impl of `IntoFuture` for `()`
+   = note: required for `()` to implement `IntoFuture`
 help: remove the `.await`
    |
 LL -     m::f1().await;
@@ -29,7 +29,7 @@ LL |     m::f2().await;
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
-   = note: required because of the requirements on the impl of `IntoFuture` for `()`
+   = note: required for `()` to implement `IntoFuture`
 help: remove the `.await`
    |
 LL -     m::f2().await;
@@ -50,7 +50,7 @@ LL |     m::f3().await;
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
-   = note: required because of the requirements on the impl of `IntoFuture` for `()`
+   = note: required for `()` to implement `IntoFuture`
 help: remove the `.await`
    |
 LL -     m::f3().await;
diff --git a/src/test/ui/suggestions/many-type-ascription.rs b/src/test/ui/suggestions/many-type-ascription.rs
new file mode 100644
index 00000000000..31ac556b944
--- /dev/null
+++ b/src/test/ui/suggestions/many-type-ascription.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let _ = 0: i32; //~ ERROR: type ascription is experimental
+    let _ = 0: i32; // (error only emitted once)
+}
diff --git a/src/test/ui/suggestions/many-type-ascription.stderr b/src/test/ui/suggestions/many-type-ascription.stderr
new file mode 100644
index 00000000000..3706bbae9df
--- /dev/null
+++ b/src/test/ui/suggestions/many-type-ascription.stderr
@@ -0,0 +1,12 @@
+error[E0658]: type ascription is experimental
+  --> $DIR/many-type-ascription.rs:2:13
+   |
+LL |     let _ = 0: i32;
+   |             ^^^^^^
+   |
+   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+   = help: add `#![feature(type_ascription)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/suggestions/option-content-move.fixed b/src/test/ui/suggestions/option-content-move.fixed
deleted file mode 100644
index ba16bcc8a33..00000000000
--- a/src/test/ui/suggestions/option-content-move.fixed
+++ /dev/null
@@ -1,39 +0,0 @@
-//run-rustfix
-
-pub struct LipogramCorpora {
-    selections: Vec<(char, Option<String>)>,
-}
-
-impl LipogramCorpora {
-    pub fn validate_all(&mut self) -> Result<(), char> {
-        for selection in &self.selections {
-            if selection.1.is_some() {
-                if selection.1.as_ref().unwrap().contains(selection.0) {
-                //~^ ERROR cannot move out of `selection.1`
-                    return Err(selection.0);
-                }
-            }
-        }
-        Ok(())
-    }
-}
-
-pub struct LipogramCorpora2 {
-    selections: Vec<(char, Result<String, String>)>,
-}
-
-impl LipogramCorpora2 {
-    pub fn validate_all(&mut self) -> Result<(), char> {
-        for selection in &self.selections {
-            if selection.1.is_ok() {
-                if selection.1.as_ref().unwrap().contains(selection.0) {
-                //~^ ERROR cannot move out of `selection.1`
-                    return Err(selection.0);
-                }
-            }
-        }
-        Ok(())
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/suggestions/option-content-move.rs b/src/test/ui/suggestions/option-content-move.rs
index ef38f114eca..46c895b95f5 100644
--- a/src/test/ui/suggestions/option-content-move.rs
+++ b/src/test/ui/suggestions/option-content-move.rs
@@ -1,5 +1,3 @@
-//run-rustfix
-
 pub struct LipogramCorpora {
     selections: Vec<(char, Option<String>)>,
 }
diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr
index fccfbe1d744..a6f1ebc975f 100644
--- a/src/test/ui/suggestions/option-content-move.stderr
+++ b/src/test/ui/suggestions/option-content-move.stderr
@@ -1,9 +1,10 @@
 error[E0507]: cannot move out of `selection.1` which is behind a shared reference
-  --> $DIR/option-content-move.rs:11:20
+  --> $DIR/option-content-move.rs:9:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
    |                    ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
    |                    |
+   |                    help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
    |                    move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
    |
 note: this function takes ownership of the receiver `self`, which moves `selection.1`
@@ -11,17 +12,14 @@ note: this function takes ownership of the receiver `self`, which moves `selecti
    |
 LL |     pub const fn unwrap(self) -> T {
    |                         ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
-   |
-LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
-   |                                +++++++++
 
 error[E0507]: cannot move out of `selection.1` which is behind a shared reference
-  --> $DIR/option-content-move.rs:29:20
+  --> $DIR/option-content-move.rs:27:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
    |                    ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
    |                    |
+   |                    help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
    |                    move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
    |
 note: this function takes ownership of the receiver `self`, which moves `selection.1`
@@ -29,10 +27,6 @@ note: this function takes ownership of the receiver `self`, which moves `selecti
    |
 LL |     pub fn unwrap(self) -> T
    |                   ^^^^
-help: consider calling `.as_ref()` to borrow the type's contents
-   |
-LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
-   |                                +++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/return-cycle-2.rs b/src/test/ui/suggestions/return-cycle-2.rs
new file mode 100644
index 00000000000..d6d24be1b8d
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle-2.rs
@@ -0,0 +1,14 @@
+use std::marker::PhantomData;
+
+struct Token<T>(PhantomData<T>);
+
+impl<T> Token<T> {
+    fn as_ref(_: i32, _: i32) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+        //~| NOTE not allowed in type signatures
+        //~| HELP replace with the correct return type
+        Token(PhantomData::<&T>)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-cycle-2.stderr b/src/test/ui/suggestions/return-cycle-2.stderr
new file mode 100644
index 00000000000..3a1a0f7f4f5
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle-2.stderr
@@ -0,0 +1,12 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/return-cycle-2.rs:6:34
+   |
+LL |     fn as_ref(_: i32, _: i32) -> _ {
+   |                                  ^
+   |                                  |
+   |                                  not allowed in type signatures
+   |                                  help: replace with the correct return type: `Token<&'static T>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/suggestions/return-cycle.rs b/src/test/ui/suggestions/return-cycle.rs
new file mode 100644
index 00000000000..60b80e35a20
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle.rs
@@ -0,0 +1,14 @@
+use std::marker::PhantomData;
+
+struct Token<T>(PhantomData<T>);
+
+impl<T> Token<T> {
+    fn new() -> _ {
+        //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+        //~| NOTE not allowed in type signatures
+        //~| HELP replace with the correct return type
+        Token(PhantomData::<()>)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-cycle.stderr b/src/test/ui/suggestions/return-cycle.stderr
new file mode 100644
index 00000000000..63fa9e04087
--- /dev/null
+++ b/src/test/ui/suggestions/return-cycle.stderr
@@ -0,0 +1,12 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/return-cycle.rs:6:17
+   |
+LL |     fn new() -> _ {
+   |                 ^
+   |                 |
+   |                 not allowed in type signatures
+   |                 help: replace with the correct return type: `Token<()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/suggestions/slice-issue-87994.stderr b/src/test/ui/suggestions/slice-issue-87994.stderr
index fd2a44f9a82..44f0da27f13 100644
--- a/src/test/ui/suggestions/slice-issue-87994.stderr
+++ b/src/test/ui/suggestions/slice-issue-87994.stderr
@@ -5,7 +5,7 @@ LL |   for _ in v[1..] {
    |            ^^^^^^ expected an implementor of trait `IntoIterator`
    |
    = note: the trait bound `[i32]: IntoIterator` is not satisfied
-   = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+   = note: required for `[i32]` to implement `IntoIterator`
 help: consider borrowing here
    |
 LL |   for _ in &v[1..] {
@@ -20,7 +20,7 @@ LL |   for _ in v[1..] {
    |            ^^^^^^ expected an implementor of trait `IntoIterator`
    |
    = note: the trait bound `[i32]: IntoIterator` is not satisfied
-   = note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
+   = note: required for `[i32]` to implement `IntoIterator`
 help: consider borrowing here
    |
 LL |   for _ in &v[1..] {
@@ -35,7 +35,7 @@ LL |   for i2 in v2[1..] {
    |             ^^^^^^^ expected an implementor of trait `IntoIterator`
    |
    = note: the trait bound `[K]: IntoIterator` is not satisfied
-   = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+   = note: required for `[K]` to implement `IntoIterator`
 help: consider borrowing here
    |
 LL |   for i2 in &v2[1..] {
@@ -50,7 +50,7 @@ LL |   for i2 in v2[1..] {
    |             ^^^^^^^ expected an implementor of trait `IntoIterator`
    |
    = note: the trait bound `[K]: IntoIterator` is not satisfied
-   = note: required because of the requirements on the impl of `IntoIterator` for `[K]`
+   = note: required for `[K]` to implement `IntoIterator`
 help: consider borrowing here
    |
 LL |   for i2 in &v2[1..] {
diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed
new file mode 100644
index 00000000000..e9b8a9caa48
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused_variables)]
+
+fn foo(foo: &mut usize) {
+    todo!()
+}
+
+fn bar(bar: &usize) {
+    todo!()
+}
+
+fn main() {
+    foo(&mut Default::default()); //~ the trait bound `&mut usize: Default` is not satisfied
+    bar(&Default::default()); //~ the trait bound `&usize: Default` is not satisfied
+}
diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs
new file mode 100644
index 00000000000..5fae21cccef
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused_variables)]
+
+fn foo(foo: &mut usize) {
+    todo!()
+}
+
+fn bar(bar: &usize) {
+    todo!()
+}
+
+fn main() {
+    foo(Default::default()); //~ the trait bound `&mut usize: Default` is not satisfied
+    bar(Default::default()); //~ the trait bound `&usize: Default` is not satisfied
+}
diff --git a/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr
new file mode 100644
index 00000000000..b930d22a391
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr
@@ -0,0 +1,25 @@
+error[E0277]: the trait bound `&mut usize: Default` is not satisfied
+  --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9
+   |
+LL |     foo(Default::default());
+   |         ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default`
+   |
+help: consider mutably borrowing here
+   |
+LL |     foo(&mut Default::default());
+   |         ++++
+
+error[E0277]: the trait bound `&usize: Default` is not satisfied
+  --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9
+   |
+LL |     bar(Default::default());
+   |         ^^^^^^^^^^^^^^^^ expected an implementor of trait `Default`
+   |
+help: consider borrowing here
+   |
+LL |     bar(&Default::default());
+   |         +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.stderr b/src/test/ui/suggestions/suggest-dereferencing-index.stderr
index c8b87af7bd8..147dc9234c5 100644
--- a/src/test/ui/suggestions/suggest-dereferencing-index.stderr
+++ b/src/test/ui/suggestions/suggest-dereferencing-index.stderr
@@ -6,7 +6,7 @@ LL |     let one_item_please: i32 = [1, 2, 3][i];
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
    = help: the trait `SliceIndex<[T]>` is implemented for `usize`
-   = note: required because of the requirements on the impl of `Index<&usize>` for `[{integer}]`
+   = note: required for `[{integer}]` to implement `Index<&usize>`
 help: dereference this index
    |
 LL |     let one_item_please: i32 = [1, 2, 3][*i];
diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.stderr b/src/test/ui/suggestions/suggest-remove-refs-1.stderr
index 1083b2f9713..1a843f3f509 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-1.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-1.stderr
@@ -8,7 +8,7 @@ LL |     for (i, _) in &v.iter().enumerate() {
    |                   help: consider removing the leading `&`-reference
    |
    = help: the trait `Iterator` is not implemented for `&Enumerate<std::slice::Iter<'_, {integer}>>`
-   = note: required because of the requirements on the impl of `IntoIterator` for `&Enumerate<std::slice::Iter<'_, {integer}>>`
+   = note: required for `&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.stderr b/src/test/ui/suggestions/suggest-remove-refs-2.stderr
index 197b19a1bff..f39361d529f 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-2.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-2.stderr
@@ -8,7 +8,7 @@ LL |     for (i, _) in & & & & &v.iter().enumerate() {
    |                   help: consider removing 5 leading `&`-references
    |
    = help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
-   = note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
+   = note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.stderr b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
index bb0cceac1db..4d07324273c 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-3.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
@@ -12,7 +12,7 @@ LL | |          .enumerate() {
    | |_____________________^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
-   = note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
+   = note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/type-ascription-and-other-error.rs b/src/test/ui/suggestions/type-ascription-and-other-error.rs
new file mode 100644
index 00000000000..99ab2f3c858
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-and-other-error.rs
@@ -0,0 +1,6 @@
+fn main() {
+    not rust; //~ ERROR
+    let _ = 0: i32; // (error hidden by existing error)
+    #[cfg(FALSE)]
+    let _ = 0: i32; // (warning hidden by existing error)
+}
diff --git a/src/test/ui/suggestions/type-ascription-and-other-error.stderr b/src/test/ui/suggestions/type-ascription-and-other-error.stderr
new file mode 100644
index 00000000000..eadf634bb14
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-and-other-error.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `rust`
+  --> $DIR/type-ascription-and-other-error.rs:2:9
+   |
+LL |     not rust;
+   |         ^^^^ expected one of 8 possible tokens
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/traits/alias/cross-crate.stderr b/src/test/ui/traits/alias/cross-crate.stderr
index d0d00c97e83..ae9d7d0a9b4 100644
--- a/src/test/ui/traits/alias/cross-crate.stderr
+++ b/src/test/ui/traits/alias/cross-crate.stderr
@@ -5,7 +5,7 @@ LL |     use_alias::<Rc<u32>>();
    |                 ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `Rc<u32>`
-   = note: required because of the requirements on the impl of `SendSync` for `Rc<u32>`
+   = note: required for `Rc<u32>` to implement `SendSync`
 note: required by a bound in `use_alias`
   --> $DIR/cross-crate.rs:10:17
    |
@@ -19,7 +19,7 @@ LL |     use_alias::<Rc<u32>>();
    |                 ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Rc<u32>`
-   = note: required because of the requirements on the impl of `SendSync` for `Rc<u32>`
+   = note: required for `Rc<u32>` to implement `SendSync`
 note: required by a bound in `use_alias`
   --> $DIR/cross-crate.rs:10:17
    |
diff --git a/src/test/ui/traits/alias/self-in-const-generics.rs b/src/test/ui/traits/alias/self-in-const-generics.rs
new file mode 100644
index 00000000000..b0de8ccd678
--- /dev/null
+++ b/src/test/ui/traits/alias/self-in-const-generics.rs
@@ -0,0 +1,12 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+#![feature(trait_alias)]
+
+trait Bar<const N: usize> {}
+
+trait BB = Bar<{ 2 + 1 }>;
+
+fn foo(x: &dyn BB) {}
+//~^ ERROR the trait alias `BB` cannot be made into an object [E0038]
+
+fn main() {}
diff --git a/src/test/ui/traits/alias/self-in-const-generics.stderr b/src/test/ui/traits/alias/self-in-const-generics.stderr
new file mode 100644
index 00000000000..61cc217cfbc
--- /dev/null
+++ b/src/test/ui/traits/alias/self-in-const-generics.stderr
@@ -0,0 +1,11 @@
+error[E0038]: the trait alias `BB` cannot be made into an object
+  --> $DIR/self-in-const-generics.rs:9:16
+   |
+LL | fn foo(x: &dyn BB) {}
+   |                ^^
+   |
+   = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/traits/alias/self-in-generics.rs b/src/test/ui/traits/alias/self-in-generics.rs
index 6b99431f5bb..0bb6335f91e 100644
--- a/src/test/ui/traits/alias/self-in-generics.rs
+++ b/src/test/ui/traits/alias/self-in-generics.rs
@@ -1,3 +1,10 @@
+// astconv uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects.
+// This `FreshTy(0)` can leak into substs, causing ICEs in several places.
+// Using `save-analysis` triggers type-checking `f` that would be normally skipped
+// as `type_of` emitted an error.
+//
+// compile-flags: -Zsave-analysis
+
 #![feature(trait_alias)]
 
 pub trait SelfInput = Fn(&mut Self);
diff --git a/src/test/ui/traits/alias/self-in-generics.stderr b/src/test/ui/traits/alias/self-in-generics.stderr
index a1056872ea6..110d60e6e91 100644
--- a/src/test/ui/traits/alias/self-in-generics.stderr
+++ b/src/test/ui/traits/alias/self-in-generics.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait alias `SelfInput` cannot be made into an object
-  --> $DIR/self-in-generics.rs:5:19
+  --> $DIR/self-in-generics.rs:12:19
    |
 LL | pub fn f(_f: &dyn SelfInput) {}
    |                   ^^^^^^^^^
diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
index 1d234518056..5ba189aa82a 100644
--- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
+++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.rs
@@ -5,7 +5,7 @@ fn strip_lf(s: &str) -> &str {
     //~| NOTE required by a bound introduced by this call
     //~| HELP the trait `FnMut<(char,)>` is not implemented for `u8`
     //~| HELP the following other types implement trait `Pattern<'a>`:
-    //~| NOTE required because of the requirements on the impl of `Pattern<'_>` for `u8`
+    //~| NOTE required for `u8` to implement `Pattern<'_>`
 
 }
 
diff --git a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
index 6ce57b6263e..41120c09fb1 100644
--- a/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
+++ b/src/test/ui/traits/bound/assoc-fn-bound-root-obligation.stderr
@@ -15,7 +15,7 @@ LL |     s.strip_suffix(b'\n').unwrap_or(s)
              &'c &'b str
              [char; N]
              char
-   = note: required because of the requirements on the impl of `Pattern<'_>` for `u8`
+   = note: required for `u8` to implement `Pattern<'_>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr
index 859403f202f..2478eb35422 100644
--- a/src/test/ui/traits/cycle-cache-err-60010.stderr
+++ b/src/test/ui/traits/cycle-cache-err-60010.stderr
@@ -17,12 +17,12 @@ note: required because it appears within the type `RootDatabase`
    |
 LL | struct RootDatabase {
    |        ^^^^^^^^^^^^
-note: required because of the requirements on the impl of `SourceDatabase` for `RootDatabase`
+note: required for `RootDatabase` to implement `SourceDatabase`
   --> $DIR/cycle-cache-err-60010.rs:44:9
    |
 LL | impl<T> SourceDatabase for T
    |         ^^^^^^^^^^^^^^     ^
-note: required because of the requirements on the impl of `Query<RootDatabase>` for `ParseQuery`
+note: required for `ParseQuery` to implement `Query<RootDatabase>`
   --> $DIR/cycle-cache-err-60010.rs:37:10
    |
 LL | impl<DB> Query<DB> for ParseQuery
diff --git a/src/test/ui/traits/inductive-overflow/lifetime.rs b/src/test/ui/traits/inductive-overflow/lifetime.rs
index c36c17d3d24..004e477374a 100644
--- a/src/test/ui/traits/inductive-overflow/lifetime.rs
+++ b/src/test/ui/traits/inductive-overflow/lifetime.rs
@@ -28,5 +28,5 @@ fn main() {
     is_send::<X<C<'static>>>();
     //~^ ERROR overflow evaluating
     //~| 3 redundant requirements hidden
-    //~| required because of
+    //~| required for
 }
diff --git a/src/test/ui/traits/inductive-overflow/lifetime.stderr b/src/test/ui/traits/inductive-overflow/lifetime.stderr
index 9ca615aacee..b72d53bddbc 100644
--- a/src/test/ui/traits/inductive-overflow/lifetime.stderr
+++ b/src/test/ui/traits/inductive-overflow/lifetime.stderr
@@ -4,13 +4,13 @@ error[E0275]: overflow evaluating the requirement `X<C<'_>>: NotAuto`
 LL |     is_send::<X<C<'static>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: required because of the requirements on the impl of `NotAuto` for `Box<X<C<'_>>>`
+note: required for `Box<X<C<'_>>>` to implement `NotAuto`
   --> $DIR/lifetime.rs:18:18
    |
 LL | impl<T: NotAuto> NotAuto for Box<T> {}
    |                  ^^^^^^^     ^^^^^^
    = note: 3 redundant requirements hidden
-   = note: required because of the requirements on the impl of `NotAuto` for `X<C<'static>>`
+   = note: required for `X<C<'static>>` to implement `NotAuto`
 note: required by a bound in `is_send`
   --> $DIR/lifetime.rs:22:15
    |
diff --git a/src/test/ui/traits/inductive-overflow/simultaneous.stderr b/src/test/ui/traits/inductive-overflow/simultaneous.stderr
index 230c2638c50..09930e60efe 100644
--- a/src/test/ui/traits/inductive-overflow/simultaneous.stderr
+++ b/src/test/ui/traits/inductive-overflow/simultaneous.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `{integer}: Tweedledum`
 LL |     is_ee(4);
    |     ^^^^^
    |
-note: required because of the requirements on the impl of `Combo` for `{integer}`
+note: required for `{integer}` to implement `Combo`
   --> $DIR/simultaneous.rs:11:34
    |
 LL | impl<T: Tweedledee + Tweedledum> Combo for T {}
diff --git a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
index d7697dcc640..3ec288d1382 100644
--- a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
+++ b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr
@@ -14,7 +14,7 @@ LL |     let (a, b) = copy(NoClone);
    |                  |
    |                  required by a bound introduced by this call
    |
-note: required because of the requirements on the impl of `Magic` for `NoClone`
+note: required for `NoClone` to implement `Magic`
   --> $DIR/supertrait-auto-trait.rs:8:12
    |
 LL | auto trait Magic: Copy {}
diff --git a/src/test/ui/traits/inductive-overflow/supertrait.stderr b/src/test/ui/traits/inductive-overflow/supertrait.stderr
index 95325a534f5..4b862cf79ce 100644
--- a/src/test/ui/traits/inductive-overflow/supertrait.stderr
+++ b/src/test/ui/traits/inductive-overflow/supertrait.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `NoClone: Magic`
 LL |     let (a, b) = copy(NoClone);
    |                  ^^^^
    |
-note: required because of the requirements on the impl of `Magic` for `NoClone`
+note: required for `NoClone` to implement `Magic`
   --> $DIR/supertrait.rs:5:16
    |
 LL | impl<T: Magic> Magic for T {}
diff --git a/src/test/ui/traits/issue-18400.stderr b/src/test/ui/traits/issue-18400.stderr
index 92e0f60079f..4394e6f7e05 100644
--- a/src/test/ui/traits/issue-18400.stderr
+++ b/src/test/ui/traits/issue-18400.stderr
@@ -5,13 +5,13 @@ LL |     0.contains(bits);
    |       ^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_18400`)
-note: required because of the requirements on the impl of `Set<&[_]>` for `{integer}`
+note: required for `{integer}` to implement `Set<&[_]>`
   --> $DIR/issue-18400.rs:6:16
    |
 LL | impl<'a, T, S> Set<&'a [T]> for S where
    |                ^^^^^^^^^^^^     ^
    = note: 128 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>` for `{integer}`
+   = note: required for `{integer}` to implement `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/issue-20692.stderr b/src/test/ui/traits/issue-20692.stderr
index 1d7f252e556..2028994cdaa 100644
--- a/src/test/ui/traits/issue-20692.stderr
+++ b/src/test/ui/traits/issue-20692.stderr
@@ -27,7 +27,7 @@ LL | trait Array: Sized + Copy {}
    |       |      |
    |       |      ...because it requires `Self: Sized`
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Array>` for `&T`
+   = note: required for `&T` to implement `CoerceUnsized<&dyn Array>`
    = note: required by cast to type `&dyn Array`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/issue-38604.stderr b/src/test/ui/traits/issue-38604.stderr
index d41488c15f7..50d6fb05465 100644
--- a/src/test/ui/traits/issue-38604.stderr
+++ b/src/test/ui/traits/issue-38604.stderr
@@ -25,7 +25,7 @@ LL | trait Foo where u32: Q<Self> {
    |       ---            ^^^^^^^ ...because it uses `Self` as a type parameter
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<()>`
+   = note: required for `Box<()>` to implement `CoerceUnsized<Box<dyn Foo>>`
    = note: required by cast to type `Box<dyn Foo>`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/issue-71036.rs b/src/test/ui/traits/issue-71036.rs
index 3d2df6fe997..69eed0c0462 100644
--- a/src/test/ui/traits/issue-71036.rs
+++ b/src/test/ui/traits/issue-71036.rs
@@ -12,6 +12,6 @@ impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for Foo<'
 //~^ ERROR the trait bound `&'a T: Unsize<&'a U>` is not satisfied
 //~| NOTE the trait `Unsize<&'a U>` is not implemented for `&'a T`
 //~| NOTE all implementations of `Unsize` are provided automatically by the compiler
-//~| NOTE required because of the requirements on the impl
+//~| NOTE required for
 
 fn main() {}
diff --git a/src/test/ui/traits/issue-71036.stderr b/src/test/ui/traits/issue-71036.stderr
index 3ee6db40e87..79eb7a2ae8b 100644
--- a/src/test/ui/traits/issue-71036.stderr
+++ b/src/test/ui/traits/issue-71036.stderr
@@ -5,7 +5,7 @@ LL | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Foo<'a, U>> for
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize<&'a U>` is not implemented for `&'a T`
    |
    = note: all implementations of `Unsize` are provided automatically by the compiler, see <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> for more information
-   = note: required because of the requirements on the impl of `DispatchFromDyn<&'a &'a U>` for `&'a &'a T`
+   = note: required for `&'a &'a T` to implement `DispatchFromDyn<&'a &'a U>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/issue-71136.stderr b/src/test/ui/traits/issue-71136.stderr
index 62a2a64ed14..f541733929d 100644
--- a/src/test/ui/traits/issue-71136.stderr
+++ b/src/test/ui/traits/issue-71136.stderr
@@ -7,7 +7,7 @@ LL | struct FooHolster {
 LL |     the_foos: Vec<Foo>,
    |     ^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Foo`
    |
-   = note: required because of the requirements on the impl of `Clone` for `Vec<Foo>`
+   = note: required for `Vec<Foo>` to implement `Clone`
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider annotating `Foo` with `#[derive(Clone)]`
    |
diff --git a/src/test/ui/traits/issue-82830.stderr b/src/test/ui/traits/issue-82830.stderr
index f863143c738..6a597a40215 100644
--- a/src/test/ui/traits/issue-82830.stderr
+++ b/src/test/ui/traits/issue-82830.stderr
@@ -4,7 +4,7 @@ error[E0275]: overflow evaluating the requirement `P: Sized`
 LL |     t: MaybeBox<P>,
    |        ^^^^^^^^^^^
    |
-note: required because of the requirements on the impl of `A<P, Box<P>>` for `P`
+note: required for `P` to implement `A<P, Box<P>>`
   --> $DIR/issue-82830.rs:10:12
    |
 LL | impl<Y, N> A<Y, N> for P {
diff --git a/src/test/ui/traits/issue-91594.stderr b/src/test/ui/traits/issue-91594.stderr
index f2b3de13beb..9f9acf85113 100644
--- a/src/test/ui/traits/issue-91594.stderr
+++ b/src/test/ui/traits/issue-91594.stderr
@@ -5,7 +5,7 @@ LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
    |
    = help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
-note: required because of the requirements on the impl of `Component<Foo>` for `Foo`
+note: required for `Foo` to implement `Component<Foo>`
   --> $DIR/issue-91594.rs:13:27
    |
 LL | impl<M: HasComponent<()>> Component<M> for Foo {
diff --git a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
index f5d6d72afc2..6acf2fe65ce 100644
--- a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
+++ b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
@@ -15,9 +15,9 @@ LL |       recurse(IteratorOfWrapped(elements).map(|t| t.0))
 error[E0275]: overflow evaluating the requirement `(): Sized`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`)
-   = note: required because of the requirements on the impl of `Iterator` for `std::iter::Empty<()>`
+   = note: required for `std::iter::Empty<()>` to implement `Iterator`
    = note: 171 redundant requirements hidden
-   = note: required because of the requirements on the impl of `Iterator` for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>`
+   = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>` to implement `Iterator`
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/traits/issue-97576.stderr b/src/test/ui/traits/issue-97576.stderr
index bdee073d6e3..9062a0fab63 100644
--- a/src/test/ui/traits/issue-97576.stderr
+++ b/src/test/ui/traits/issue-97576.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `String: From<impl ToString>` is not satisfied
 LL |             bar: bar.into(),
    |                      ^^^^ the trait `From<impl ToString>` is not implemented for `String`
    |
-   = note: required because of the requirements on the impl of `Into<String>` for `impl ToString`
+   = note: required for `impl ToString` to implement `Into<String>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr
index c5d4ccc2fcd..bf7c3bcc6aa 100644
--- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr
+++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr
@@ -66,7 +66,7 @@ LL |     is_send(Box::new(TestType));
    |     required by a bound introduced by this call
    |
    = note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied
-   = note: required because of the requirements on the impl of `Send` for `Unique<dummy2::TestType>`
+   = note: required for `Unique<dummy2::TestType>` to implement `Send`
    = note: required because it appears within the type `Box<dummy2::TestType>`
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
@@ -92,7 +92,7 @@ note: required because it appears within the type `Outer2<dummy3::TestType>`
    |
 LL | struct Outer2<T>(T);
    |        ^^^^^^
-   = note: required because of the requirements on the impl of `Send` for `Unique<Outer2<dummy3::TestType>>`
+   = note: required for `Unique<Outer2<dummy3::TestType>>` to implement `Send`
    = note: required because it appears within the type `Box<Outer2<dummy3::TestType>>`
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
@@ -109,7 +109,7 @@ LL |     is_sync(Outer2(TestType));
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `main::TestType`
-note: required because of the requirements on the impl of `Sync` for `Outer2<main::TestType>`
+note: required for `Outer2<main::TestType>` to implement `Sync`
   --> $DIR/negated-auto-traits-error.rs:14:22
    |
 LL | unsafe impl<T: Send> Sync for Outer2<T> {}
diff --git a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr
index 75d45d9052b..53178328c56 100644
--- a/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr
+++ b/src/test/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr
@@ -22,7 +22,7 @@ LL | impl I<i32> for B {}
    | ^^^^^^^^^^^^^^^^^
 LL | impl I<u32> for B {}
    | ^^^^^^^^^^^^^^^^^
-note: required because of the requirements on the impl of `V<_>` for `A<B>`
+note: required for `A<B>` to implement `V<_>`
   --> $DIR/not-suggest-non-existing-fully-qualified-path.rs:12:12
    |
 LL | impl<T, U> V<U> for A<T>
diff --git a/src/test/ui/traits/object/safety.stderr b/src/test/ui/traits/object/safety.stderr
index cf534d984c2..dc18adeafc7 100644
--- a/src/test/ui/traits/object/safety.stderr
+++ b/src/test/ui/traits/object/safety.stderr
@@ -11,7 +11,7 @@ LL | trait Tr {
    |       -- this trait cannot be made into an object...
 LL |     fn foo();
    |        ^^^ ...because associated function `foo` has no `self` parameter
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Tr>` for `&St`
+   = note: required for `&St` to implement `CoerceUnsized<&dyn Tr>`
    = note: required by cast to type `&dyn Tr`
 help: consider turning `foo` into a method by giving it a `&self` argument
    |
diff --git a/src/test/ui/traits/suggest-deferences/issue-39029.stderr b/src/test/ui/traits/suggest-deferences/issue-39029.stderr
index 5c324cd38a3..eb2b88059d4 100644
--- a/src/test/ui/traits/suggest-deferences/issue-39029.stderr
+++ b/src/test/ui/traits/suggest-deferences/issue-39029.stderr
@@ -2,18 +2,20 @@ error[E0277]: the trait bound `NoToSocketAddrs: ToSocketAddrs` is not satisfied
   --> $DIR/issue-39029.rs:16:37
    |
 LL |     let _errors = TcpListener::bind(&bad);
-   |                   ----------------- ^^^^
-   |                   |                 |
-   |                   |                 the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
-   |                   |                 help: consider dereferencing here: `&*bad`
+   |                   ----------------- ^^^^ the trait `ToSocketAddrs` is not implemented for `NoToSocketAddrs`
+   |                   |
    |                   required by a bound introduced by this call
    |
-   = note: required because of the requirements on the impl of `ToSocketAddrs` for `&NoToSocketAddrs`
+   = note: required for `&NoToSocketAddrs` to implement `ToSocketAddrs`
 note: required by a bound in `TcpListener::bind`
   --> $SRC_DIR/std/src/net/tcp.rs:LL:COL
    |
 LL |     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
    |                    ^^^^^^^^^^^^^ required by this bound in `TcpListener::bind`
+help: consider dereferencing here
+   |
+LL |     let _errors = TcpListener::bind(&*bad);
+   |                                      +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/suggest-deferences/issue-62530.stderr b/src/test/ui/traits/suggest-deferences/issue-62530.stderr
index d129328dae8..e47ae0b65af 100644
--- a/src/test/ui/traits/suggest-deferences/issue-62530.stderr
+++ b/src/test/ui/traits/suggest-deferences/issue-62530.stderr
@@ -2,10 +2,8 @@ error[E0277]: the trait bound `&String: SomeTrait` is not satisfied
   --> $DIR/issue-62530.rs:13:26
    |
 LL |     takes_type_parameter(&string);  // Error
-   |     -------------------- ^^^^^^^
-   |     |                    |
-   |     |                    the trait `SomeTrait` is not implemented for `&String`
-   |     |                    help: consider dereferencing here: `&*string`
+   |     -------------------- ^^^^^^^ the trait `SomeTrait` is not implemented for `&String`
+   |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `takes_type_parameter`
@@ -13,6 +11,10 @@ note: required by a bound in `takes_type_parameter`
    |
 LL | fn takes_type_parameter<T>(_x: T) where T: SomeTrait {}
    |                                            ^^^^^^^^^ required by this bound in `takes_type_parameter`
+help: consider dereferencing here
+   |
+LL |     takes_type_parameter(&*string);  // Error
+   |                           +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/suggest-deferences/multiple-0.stderr b/src/test/ui/traits/suggest-deferences/multiple-0.stderr
index efb3c7d123f..6a4d4b8d521 100644
--- a/src/test/ui/traits/suggest-deferences/multiple-0.stderr
+++ b/src/test/ui/traits/suggest-deferences/multiple-0.stderr
@@ -2,10 +2,8 @@ error[E0277]: the trait bound `&Baz: Happy` is not satisfied
   --> $DIR/multiple-0.rs:34:9
    |
 LL |     foo(&baz);
-   |     --- ^^^^
-   |     |   |
-   |     |   the trait `Happy` is not implemented for `&Baz`
-   |     |   help: consider dereferencing here: `&***baz`
+   |     --- ^^^^ the trait `Happy` is not implemented for `&Baz`
+   |     |
    |     required by a bound introduced by this call
    |
 note: required by a bound in `foo`
@@ -13,6 +11,10 @@ note: required by a bound in `foo`
    |
 LL | fn foo<T>(_: T) where T: Happy {}
    |                          ^^^^^ required by this bound in `foo`
+help: consider dereferencing here
+   |
+LL |     foo(&***baz);
+   |          +++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/suggest-deferences/root-obligation.stderr b/src/test/ui/traits/suggest-deferences/root-obligation.stderr
index 16e03e79c75..76663ace7ed 100644
--- a/src/test/ui/traits/suggest-deferences/root-obligation.stderr
+++ b/src/test/ui/traits/suggest-deferences/root-obligation.stderr
@@ -7,8 +7,8 @@ LL |         .filter(|c| "aeiou".contains(c))
    |                             required by a bound introduced by this call
    |
    = help: the trait `Fn<(char,)>` is not implemented for `char`
-   = note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&char`
-   = note: required because of the requirements on the impl of `Pattern<'_>` for `&char`
+   = note: required for `&char` to implement `FnOnce<(char,)>`
+   = note: required for `&char` to implement `Pattern<'_>`
 note: required by a bound in `core::str::<impl str>::contains`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
    |
diff --git a/src/test/ui/traits/test-2.stderr b/src/test/ui/traits/test-2.stderr
index 77ea4e4e974..eaa20b0b4f4 100644
--- a/src/test/ui/traits/test-2.stderr
+++ b/src/test/ui/traits/test-2.stderr
@@ -76,7 +76,7 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |       this trait cannot be made into an object...
    = help: consider moving `dup` to another trait
    = help: consider moving `blah` to another trait
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn bar>>` for `Box<{integer}>`
+   = note: required for `Box<{integer}>` to implement `CoerceUnsized<Box<dyn bar>>`
    = note: required by cast to type `Box<dyn bar>`
 
 error: aborting due to 5 previous errors
diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr
index f9906713f84..e11c3f81003 100644
--- a/src/test/ui/try-block/try-block-bad-type.stderr
+++ b/src/test/ui/try-block/try-block-bad-type.stderr
@@ -6,7 +6,7 @@ LL |         Err("")?;
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the trait `From<Infallible>` is implemented for `TryFromSliceError`
-   = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<u32, TryFromSliceError>`
+   = note: required for `Result<u32, TryFromSliceError>` to implement `FromResidual<Result<Infallible, &str>>`
 
 error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
   --> $DIR/try-block-bad-type.rs:12:9
diff --git a/src/test/ui/try-trait/bad-interconversion.stderr b/src/test/ui/try-trait/bad-interconversion.stderr
index 1dbf3ebdf82..529f5f16c8f 100644
--- a/src/test/ui/try-trait/bad-interconversion.stderr
+++ b/src/test/ui/try-trait/bad-interconversion.stderr
@@ -17,7 +17,7 @@ LL |     Ok(Err(123_i32)?)
              <f64 as From<i32>>
              <f64 as From<i8>>
            and 67 others
-   = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, i32>>` for `Result<u64, u8>`
+   = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
 
 error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
   --> $DIR/bad-interconversion.rs:11:12
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
index 2768f0c3ab7..586ea82342a 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
 LL |     (t, u)
    |     ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(T, U)`
+   = note: required for `(T, U)` to implement `Debug`
 help: consider restricting type parameter `T`
    |
 LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -16,7 +16,7 @@ error[E0277]: `U` doesn't implement `Debug`
 LL |     (t, u)
    |     ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(T, U)`
+   = note: required for `(T, U)` to implement `Debug`
 help: consider restricting type parameter `U`
    |
 LL | type Two<T, U: std::fmt::Debug> = impl Debug;
@@ -28,7 +28,7 @@ error[E0277]: `U` doesn't implement `Debug`
 LL |     (u, t)
    |     ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+   = note: required for `(U, T)` to implement `Debug`
 help: consider restricting type parameter `U`
    |
 LL | type Two<T, U: std::fmt::Debug> = impl Debug;
@@ -40,7 +40,7 @@ error[E0277]: `T` doesn't implement `Debug`
 LL |     (u, t)
    |     ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+   = note: required for `(U, T)` to implement `Debug`
 help: consider restricting type parameter `T`
    |
 LL | type Two<T: std::fmt::Debug, U> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
index c1712ca2efb..cb162d382b6 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
 LL |     (t, t)
    |     ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(T, T)`
+   = note: required for `(T, T)` to implement `Debug`
 help: consider restricting type parameter `T`
    |
 LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -16,7 +16,7 @@ error[E0277]: `U` doesn't implement `Debug`
 LL |     (u, t)
    |     ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+   = note: required for `(U, T)` to implement `Debug`
 help: consider restricting type parameter `U`
    |
 LL | type Two<T, U: std::fmt::Debug> = impl Debug;
@@ -28,7 +28,7 @@ error[E0277]: `T` doesn't implement `Debug`
 LL |     (u, t)
    |     ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+   = note: required for `(U, T)` to implement `Debug`
 help: consider restricting type parameter `T`
    |
 LL | type Two<T: std::fmt::Debug, U> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
index b83105c45f2..14cbfb3806f 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
 LL |     (t, 4u32)
    |     ^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(T, u32)`
+   = note: required for `(T, u32)` to implement `Debug`
 help: consider restricting type parameter `T`
    |
 LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -16,7 +16,7 @@ error[E0277]: `U` doesn't implement `Debug`
 LL |     (u, 4u32)
    |     ^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(U, u32)`
+   = note: required for `(U, u32)` to implement `Debug`
 help: consider restricting type parameter `U`
    |
 LL | type Two<T, U: std::fmt::Debug> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
index 50cf982733b..722693e4266 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
@@ -15,7 +15,7 @@ error[E0277]: `A` doesn't implement `Debug`
 LL |     (t, u, T::BAR)
    |     ^^^^^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
+   = note: required for `(A, B, _)` to implement `Debug`
 help: consider restricting type parameter `A`
    |
 LL | type Two<A: std::fmt::Debug, B> = impl Debug;
@@ -27,7 +27,7 @@ error[E0277]: `B` doesn't implement `Debug`
 LL |     (t, u, T::BAR)
    |     ^^^^^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
+   = note: required for `(A, B, _)` to implement `Debug`
 help: consider restricting type parameter `B`
    |
 LL | type Two<A, B: std::fmt::Debug> = impl Debug;
@@ -39,7 +39,7 @@ error[E0277]: `A` doesn't implement `Debug`
 LL |     (t, u, 42)
    |     ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
+   = note: required for `(A, B, i32)` to implement `Debug`
 help: consider restricting type parameter `A`
    |
 LL | type Two<A: std::fmt::Debug, B> = impl Debug;
@@ -51,7 +51,7 @@ error[E0277]: `B` doesn't implement `Debug`
 LL |     (t, u, 42)
    |     ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
+   = note: required for `(A, B, i32)` to implement `Debug`
 help: consider restricting type parameter `B`
    |
 LL | type Two<A, B: std::fmt::Debug> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
index 5da05a4390f..f84ec0cdc27 100644
--- a/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `B: Bar` is not satisfied
 LL |         MyBaz(bar)
    |         ^^^^^^^^^^ the trait `Bar` is not implemented for `B`
    |
-note: required because of the requirements on the impl of `Baz` for `MyBaz<B>`
+note: required for `MyBaz<B>` to implement `Baz`
   --> $DIR/issue-90400-2.rs:31:14
    |
 LL | impl<B: Bar> Baz for MyBaz<B> {
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
index cdaae99e286..66a6b0bbf74 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied
 LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
    |                                             ^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B`
    |
-   = note: required because of the requirements on the impl of `Into<&'static B>` for `&A`
+   = note: required for `&A` to implement `Into<&'static B>`
 help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
 LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
index a5ac38c38d4..b11198c584c 100644
--- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
@@ -4,7 +4,7 @@ error[E0277]: `T` doesn't implement `Debug`
 LL |     (t, 5i8)
    |     ^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(T, i8)`
+   = note: required for `(T, i8)` to implement `Debug`
 help: consider restricting type parameter `T`
    |
 LL | type Two<T: std::fmt::Debug, U> = impl Debug;
@@ -27,7 +27,7 @@ error[E0277]: `T` doesn't implement `Debug`
 LL |     (t, <U as Bar>::FOO)
    |     ^^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
    |
-   = note: required because of the requirements on the impl of `Debug` for `(T, _)`
+   = note: required for `(T, _)` to implement `Debug`
 help: consider restricting type parameter `T`
    |
 LL | type Two<T: std::fmt::Debug, U> = impl Debug;
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
index e70916573f6..95fb6f6a55a 100644
--- a/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `T: Trait` is not satisfied
 LL |     ()
    |     ^^ the trait `Trait` is not implemented for `T`
    |
-note: required because of the requirements on the impl of `ProofForConversion<T>` for `()`
+note: required for `()` to implement `ProofForConversion<T>`
   --> $DIR/underconstrained_generic.rs:13:16
    |
 LL | impl<X: Trait> ProofForConversion<X> for () {
diff --git a/src/test/ui/typeck/issue-90101.stderr b/src/test/ui/typeck/issue-90101.stderr
index ab9a72edfe9..d2729d85354 100644
--- a/src/test/ui/typeck/issue-90101.stderr
+++ b/src/test/ui/typeck/issue-90101.stderr
@@ -12,7 +12,7 @@ LL |     func(Path::new("hello").to_path_buf().to_string_lossy(), "world")
              <PathBuf as From<Cow<'a, Path>>>
              <PathBuf as From<OsString>>
              <PathBuf as From<String>>
-   = note: required because of the requirements on the impl of `Into<PathBuf>` for `Cow<'_, str>`
+   = note: required for `Cow<'_, str>` to implement `Into<PathBuf>`
 note: required by a bound in `func`
   --> $DIR/issue-90101.rs:3:20
    |
diff --git a/src/test/ui/typeck/issue-91633.rs b/src/test/ui/typeck/issue-91633.rs
new file mode 100644
index 00000000000..331a798dd7a
--- /dev/null
+++ b/src/test/ui/typeck/issue-91633.rs
@@ -0,0 +1,8 @@
+// check-pass
+fn f<T> (it: &[T])
+where
+    [T] : std::ops::Index<usize>,
+{
+    let _ = &it[0];
+}
+fn main(){}
diff --git a/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr
index e8e069708a8..503015f3bec 100644
--- a/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr
+++ b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr
@@ -4,7 +4,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     2.e1;
    |       ^^
    |
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
    |
 LL |     2.0e1;
    |       +
@@ -15,7 +15,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     2.E1;
    |       ^^
    |
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
    |
 LL |     2.0E1;
    |       +
@@ -26,7 +26,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     2.f32;
    |       ^^^
    |
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
    |
 LL |     2.0f32;
    |       +
@@ -37,7 +37,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     2.f64;
    |       ^^^
    |
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
    |
 LL |     2.0f64;
    |       +
@@ -48,7 +48,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     2.e+12;
    |       ^
    |
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
    |
 LL |     2.0e+12;
    |       +
@@ -59,7 +59,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     2.e-12;
    |       ^
    |
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
    |
 LL |     2.0e-12;
    |       +
@@ -70,7 +70,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 LL |     2.e1f32;
    |       ^^^^^
    |
-help: If the number is meant to be a floating point number, consider adding a `0` after the period
+help: if intended to be a floating point literal, consider adding a `0` after the period
    |
 LL |     2.0e1f32;
    |       +
diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs
new file mode 100644
index 00000000000..925463d6dee
--- /dev/null
+++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs
@@ -0,0 +1,8 @@
+#![feature(unboxed_closures)]
+
+fn a<F: Fn<usize>>(f: F) {}
+
+fn main() {
+    a(|_: usize| {});
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
new file mode 100644
index 00000000000..9a24fb8c2be
--- /dev/null
+++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/non-tupled-arg-mismatch.rs:6:5
+   |
+LL |     a(|_: usize| {});
+   |     ^ types differ
+   |
+   = note: expected trait `Fn<usize>`
+              found trait `Fn<(usize,)>`
+note: required by a bound in `a`
+  --> $DIR/non-tupled-arg-mismatch.rs:3:9
+   |
+LL | fn a<F: Fn<usize>>(f: F) {}
+   |         ^^^^^^^^^ required by this bound in `a`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
index fd58e1b1ebe..b968174dd2d 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
@@ -81,40 +81,8 @@ error: unnecessary `unsafe` block
 LL |     unsafe { unsafe { unsf() } }
    |     ^^^^^^ unnecessary `unsafe` block
 
-error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5
-   |
-LL | unsafe fn allow_level() {
-   | ----------------------- because it's nested under this `unsafe` fn
-...
-LL |     unsafe { unsf() }
-   |     ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:53:9
-   |
-LL | #[allow(unsafe_op_in_unsafe_fn)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9
-   |
-LL | unsafe fn nested_allow_level() {
-   | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL |         unsafe { unsf() }
-   |         ^^^^^^ unnecessary `unsafe` block
-   |
-   = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn`
-note: the lint level is defined here
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:65:13
-   |
-LL |     #[allow(unsafe_op_in_unsafe_fn)]
-   |             ^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0133]: call to unsafe function is unsafe and requires unsafe block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
    |
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
@@ -122,13 +90,13 @@ LL |     unsf();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:81:9
    |
 LL |         unsf();
    |         ^^^^^^ call to unsafe function
    |
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
-error: aborting due to 13 previous errors
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
index 30b07234034..db1e916a36c 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
@@ -58,7 +58,6 @@ unsafe fn allow_level() {
     VOID = ();
 
     unsafe { unsf() }
-    //~^ ERROR unnecessary `unsafe` block
 }
 
 unsafe fn nested_allow_level() {
@@ -70,7 +69,6 @@ unsafe fn nested_allow_level() {
         VOID = ();
 
         unsafe { unsf() }
-        //~^ ERROR unnecessary `unsafe` block
     }
 }
 
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
index 2ba6a72930d..e365293657e 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
@@ -83,26 +83,8 @@ LL |     unsafe { unsafe { unsf() } }
    |     |
    |     because it's nested under this `unsafe` block
 
-error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5
-   |
-LL | unsafe fn allow_level() {
-   | ----------------------- because it's nested under this `unsafe` fn
-...
-LL |     unsafe { unsf() }
-   |     ^^^^^^ unnecessary `unsafe` block
-
-error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9
-   |
-LL | unsafe fn nested_allow_level() {
-   | ------------------------------ because it's nested under this `unsafe` fn
-...
-LL |         unsafe { unsf() }
-   |         ^^^^^^ unnecessary `unsafe` block
-
 error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
    |
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
@@ -110,13 +92,13 @@ LL |     unsf();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:81:9
    |
 LL |         unsf();
    |         ^^^^^^ call to unsafe function
    |
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
-error: aborting due to 13 previous errors
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsized/issue-30355.stderr b/src/test/ui/unsized/issue-30355.stderr
index 71bbdf5dec7..d7af558eef4 100644
--- a/src/test/ui/unsized/issue-30355.stderr
+++ b/src/test/ui/unsized/issue-30355.stderr
@@ -2,11 +2,16 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
   --> $DIR/issue-30355.rs:5:8
    |
 LL |     &X(*Y)
-   |        ^^ doesn't have a size known at compile-time
+   |      - ^^ doesn't have a size known at compile-time
+   |      |
+   |      required by a bound introduced by this call
    |
    = help: the trait `Sized` is not implemented for `[u8]`
-   = note: all function arguments must have a statically known size
    = help: unsized fn params are gated as an unstable feature
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL |     &X(&*Y)
+   |        +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/hir-wf-check-erase-regions.stderr b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
index 037f8b9f337..b04588c5716 100644
--- a/src/test/ui/wf/hir-wf-check-erase-regions.stderr
+++ b/src/test/ui/wf/hir-wf-check-erase-regions.stderr
@@ -6,7 +6,7 @@ LL |     type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>;
    |
    = help: the trait `Iterator` is not implemented for `&T`
    = help: the trait `Iterator` is implemented for `&mut I`
-   = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+   = note: required for `&T` to implement `IntoIterator`
 note: required by a bound in `Flatten`
   --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
    |
@@ -21,7 +21,7 @@ LL |     fn into_iter(self) -> Self::IntoIter {
    |
    = help: the trait `Iterator` is not implemented for `&T`
    = help: the trait `Iterator` is implemented for `&mut I`
-   = note: required because of the requirements on the impl of `IntoIterator` for `&T`
+   = note: required for `&T` to implement `IntoIterator`
 note: required by a bound in `Flatten`
   --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL
    |
diff --git a/src/test/ui/wf/wf-const-type.stderr b/src/test/ui/wf/wf-const-type.stderr
index e47920d3dfc..85938364ede 100644
--- a/src/test/ui/wf/wf-const-type.stderr
+++ b/src/test/ui/wf/wf-const-type.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
 LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
    |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Option<NotCopy>`
+   = note: required for `Option<NotCopy>` to implement `Copy`
 note: required by a bound in `IsCopy`
   --> $DIR/wf-const-type.rs:7:17
    |
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
index 29dfb585ac6..6cf4f33f947 100644
--- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
@@ -11,7 +11,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+   = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
    = note: required by cast to type `Box<dyn Trait>`
 
 error[E0038]: the trait `Trait` cannot be made into an object
@@ -27,7 +27,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+   = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
    = note: required by cast to type `Box<(dyn Trait + 'static)>`
 
 error[E0038]: the trait `Trait` cannot be made into an object
@@ -43,7 +43,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn Trait>>` for `Box<S>`
+   = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>`
    = note: required by cast to type `Box<dyn Trait>`
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
index 02169f26f90..c9bd4549aaf 100644
--- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
@@ -11,7 +11,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
    = note: required by cast to type `&dyn Trait`
 
 error[E0038]: the trait `Trait` cannot be made into an object
@@ -27,7 +27,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
    = note: required by cast to type `&dyn Trait`
 
 error[E0038]: the trait `Trait` cannot be made into an object
@@ -43,7 +43,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
    = note: required by cast to type `&dyn Trait`
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/wf/wf-static-type.stderr b/src/test/ui/wf/wf-static-type.stderr
index 4ae69cf2e1f..16c6124b652 100644
--- a/src/test/ui/wf/wf-static-type.stderr
+++ b/src/test/ui/wf/wf-static-type.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
 LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
    |             ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`
    |
-   = note: required because of the requirements on the impl of `Copy` for `Option<NotCopy>`
+   = note: required for `Option<NotCopy>` to implement `Copy`
 note: required by a bound in `IsCopy`
   --> $DIR/wf-static-type.rs:7:17
    |
diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
index 6d141a58ef9..96fc1d36b9c 100644
--- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
@@ -25,7 +25,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>`
    = note: required by cast to type `&dyn Trait`
 
 error[E0038]: the trait `Trait` cannot be made into an object
@@ -45,7 +45,7 @@ LL | trait Trait: Sized {}
    |       -----  ^^^^^ ...because it requires `Self: Sized`
    |       |
    |       this trait cannot be made into an object...
-   = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&R`
+   = note: required for `&R` to implement `CoerceUnsized<&dyn Trait>`
    = note: required by cast to type `&dyn Trait`
 
 error: aborting due to 3 previous errors
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject efd4ca3dc0b89929dc8c5f5c023d25978d76cb6
+Subproject 9809f8ff33c2b998919fd0432c626f0f7323697
diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
index 6ad6837f0e3..bffbf20b4d2 100644
--- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs
+++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
@@ -57,10 +57,10 @@ impl EarlyLintPass for OctalEscapes {
         }
 
         if let ExprKind::Lit(lit) = &expr.kind {
-            if matches!(lit.token.kind, LitKind::Str) {
-                check_lit(cx, &lit.token, lit.span, true);
-            } else if matches!(lit.token.kind, LitKind::ByteStr) {
-                check_lit(cx, &lit.token, lit.span, false);
+            if matches!(lit.token_lit.kind, LitKind::Str) {
+                check_lit(cx, &lit.token_lit, lit.span, true);
+            } else if matches!(lit.token_lit.kind, LitKind::ByteStr) {
+                check_lit(cx, &lit.token_lit, lit.span, false);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 32718200c0b..fa2383066f3 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -589,12 +589,12 @@ impl Write {
                 },
             };
 
-            let replacement: String = match lit.token.kind {
+            let replacement: String = match lit.token_lit.kind {
                 LitKind::StrRaw(_) | LitKind::ByteStrRaw(_) if matches!(fmtstr.style, StrStyle::Raw(_)) => {
-                    lit.token.symbol.as_str().replace('{', "{{").replace('}', "}}")
+                    lit.token_lit.symbol.as_str().replace('{', "{{").replace('}', "}}")
                 },
                 LitKind::Str | LitKind::ByteStr if matches!(fmtstr.style, StrStyle::Cooked) => {
-                    lit.token.symbol.as_str().replace('{', "{{").replace('}', "}}")
+                    lit.token_lit.symbol.as_str().replace('{', "{{").replace('}', "}}")
                 },
                 LitKind::StrRaw(_)
                 | LitKind::Str
@@ -603,7 +603,7 @@ impl Write {
                 | LitKind::Integer
                 | LitKind::Float
                 | LitKind::Err => continue,
-                LitKind::Byte | LitKind::Char => match lit.token.symbol.as_str() {
+                LitKind::Byte | LitKind::Char => match lit.token_lit.symbol.as_str() {
                     "\"" if matches!(fmtstr.style, StrStyle::Cooked) => "\\\"",
                     "\"" if matches!(fmtstr.style, StrStyle::Raw(0)) => continue,
                     "\\\\" if matches!(fmtstr.style, StrStyle::Raw(_)) => "\\",
@@ -614,7 +614,7 @@ impl Write {
                     x => x,
                 }
                 .into(),
-                LitKind::Bool => lit.token.symbol.as_str().deref().into(),
+                LitKind::Bool => lit.token_lit.symbol.as_str().deref().into(),
             };
 
             if !fmt_spans.is_empty() {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 47f2a2d3482..3e9e5a03d5e 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3761,7 +3761,7 @@ impl<'test> TestCx<'test> {
 
     fn delete_file(&self, file: &PathBuf) {
         if !file.exists() {
-            // Deleting a nonexistant file would error.
+            // Deleting a nonexistent file would error.
             return;
         }
         if let Err(e) = fs::remove_file(file) {
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index c4462466646..022f7eb8e02 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -50,6 +50,7 @@ pub enum CommandKind {
     Has,
     Count,
     Is,
+    IsMany,
     Set,
 }
 
@@ -57,6 +58,7 @@ impl CommandKind {
     fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool {
         let count = match self {
             CommandKind::Has => (1..=3).contains(&args.len()),
+            CommandKind::IsMany => args.len() >= 3,
             CommandKind::Count | CommandKind::Is => 3 == args.len(),
             CommandKind::Set => 4 == args.len(),
         };
@@ -89,6 +91,7 @@ impl fmt::Display for CommandKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let text = match self {
             CommandKind::Has => "has",
+            CommandKind::IsMany => "ismany",
             CommandKind::Count => "count",
             CommandKind::Is => "is",
             CommandKind::Set => "set",
@@ -137,6 +140,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
             "has" => CommandKind::Has,
             "count" => CommandKind::Count,
             "is" => CommandKind::Is,
+            "ismany" => CommandKind::IsMany,
             "set" => CommandKind::Set,
             _ => {
                 print_err(&format!("Unrecognized command name `@{}`", cmd), lineno);
@@ -227,6 +231,44 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
                 _ => unreachable!(),
             }
         }
+        CommandKind::IsMany => {
+            // @ismany <path> <jsonpath> <value>...
+            let (path, query, values) = if let [path, query, values @ ..] = &command.args[..] {
+                (path, query, values)
+            } else {
+                unreachable!("Checked in CommandKind::validate")
+            };
+            let val = cache.get_value(path)?;
+            let got_values = select(&val, &query).unwrap();
+            assert!(!command.negated, "`@!ismany` is not supported");
+
+            // Serde json doesn't implement Ord or Hash for Value, so we must
+            // use a Vec here. While in theory that makes setwize equality
+            // O(n^2), in practice n will never be large enought to matter.
+            let expected_values =
+                values.iter().map(|v| string_to_value(v, cache)).collect::<Vec<_>>();
+            if expected_values.len() != got_values.len() {
+                return Err(CkError::FailedCheck(
+                    format!(
+                        "Expected {} values, but `{}` matched to {} values ({:?})",
+                        expected_values.len(),
+                        query,
+                        got_values.len(),
+                        got_values
+                    ),
+                    command,
+                ));
+            };
+            for got_value in got_values {
+                if !expected_values.iter().any(|exp| &**exp == got_value) {
+                    return Err(CkError::FailedCheck(
+                        format!("`{}` has match {:?}, which was not expected", query, got_value),
+                        command,
+                    ));
+                }
+            }
+            true
+        }
         CommandKind::Count => {
             // @count <path> <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
             assert_eq!(command.args.len(), 3);
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 50ef22af522f2545295090cc1ad3e4bd4aa8632
+Subproject ab88e64b152d3704c35db96dbbc6efaaed67773
diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml
index 0c81ff0789f..a70252fa65a 100644
--- a/src/tools/rust-analyzer/.github/workflows/ci.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml
@@ -101,7 +101,7 @@ jobs:
     - name: Install Nodejs
       uses: actions/setup-node@v1
       with:
-        node-version: 14.x
+        node-version: 16.x
 
     - name: Install xvfb
       if: matrix.os == 'ubuntu-latest'
diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml
index ca8eb1309de..3c36c4fb84a 100644
--- a/src/tools/rust-analyzer/.github/workflows/release.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/release.yaml
@@ -68,7 +68,7 @@ jobs:
       - name: Install Node.js
         uses: actions/setup-node@v1
         with:
-          node-version: 14.x
+          node-version: 16.x
 
       - name: Update apt repositories
         if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf'
@@ -133,7 +133,7 @@ jobs:
     container:
       image: rust:alpine
       volumes:
-        - /usr/local/cargo/registry
+        - /usr/local/cargo/registry:/usr/local/cargo/registry
 
     steps:
       - name: Install dependencies
@@ -176,7 +176,7 @@ jobs:
       - name: Install Nodejs
         uses: actions/setup-node@v1
         with:
-          node-version: 14.x
+          node-version: 16.x
 
       - run: echo "TAG=$(date --iso -u)" >> $GITHUB_ENV
         if: github.ref == 'refs/heads/release'
@@ -253,9 +253,9 @@ jobs:
       - name: Publish Extension (Code Marketplace, nightly)
         if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
-        run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix --pre-release
+        run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
 
       - name: Publish Extension (OpenVSX, nightly)
         if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
-        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix --pre-release
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
diff --git a/src/tools/rust-analyzer/.vscode/launch.json b/src/tools/rust-analyzer/.vscode/launch.json
index 021b8f048cf..1e21214ffc4 100644
--- a/src/tools/rust-analyzer/.vscode/launch.json
+++ b/src/tools/rust-analyzer/.vscode/launch.json
@@ -78,7 +78,7 @@
       "request": "launch",
       "runtimeExecutable": "${execPath}",
       "args": [
-        "--disable-extension", "matklad.rust-analyzer",
+        "--disable-extension", "rust-lang.rust-analyzer",
         "--extensionDevelopmentPath=${workspaceFolder}/editors/code"
       ],
       "outFiles": [
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 703f0e5b8af..7c6796d70bd 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -710,6 +710,7 @@ dependencies = [
  "ide-db",
  "itertools",
  "profile",
+ "serde_json",
  "sourcegen",
  "stdx",
  "syntax",
diff --git a/src/tools/rust-analyzer/bench_data/glorious_old_parser b/src/tools/rust-analyzer/bench_data/glorious_old_parser
index 7e900dfeb1e..764893daa12 100644
--- a/src/tools/rust-analyzer/bench_data/glorious_old_parser
+++ b/src/tools/rust-analyzer/bench_data/glorious_old_parser
@@ -1988,7 +1988,7 @@ impl<'a> Parser<'a> {
                     err.span_suggestion(
                         span,
                         "declare the type after the parameter binding",
-                        String::from("<identifier>: <type>"),
+                        "<identifier>: <type>",
                         Applicability::HasPlaceholders,
                     );
                 } else if require_name && is_trait_item {
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index 9b5a10acfbe..9580ce8007c 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -6,7 +6,7 @@
 //! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
 //! actual IO is done and lowered to input.
 
-use std::{fmt, iter::FromIterator, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
+use std::{fmt, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
 
 use cfg::CfgOptions;
 use rustc_hash::{FxHashMap, FxHashSet};
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index 92dffa7f372..4f626105a53 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -295,13 +295,13 @@ fn test_concat_expand() {
 #[rustc_builtin_macro]
 macro_rules! concat {}
 
-fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false); }
+fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false, '"', '\0'); }
 "##,
         expect![[r##"
 #[rustc_builtin_macro]
 macro_rules! concat {}
 
-fn main() { "foor0bar\nfalse"; }
+fn main() { "foor0bar\nfalse\"\u{0}"; }
 "##]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
index 30d39d52f38..457e43925c6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -885,7 +885,7 @@ macro_rules! m {
     ($t:ty) => ( fn bar() -> $ t {} )
 }
 
-fn bar() -> & 'a Baz<u8> {}
+fn bar() -> &'a Baz<u8> {}
 
 fn bar() -> extern "Rust"fn() -> Ret {}
 "#]],
@@ -1578,7 +1578,7 @@ macro_rules !register_methods {
             ($$($val: expr), *) = > {
                 struct Foo;
                 impl Foo {
-                    $(fn $method()-> & 'static[u32] {
+                    $(fn $method()-> &'static[u32] {
                         &[$$($$val), *]
                     }
                     )*
@@ -1591,10 +1591,10 @@ macro_rules !implement_methods {
     ($($val: expr), *) = > {
         struct Foo;
         impl Foo {
-            fn alpha()-> & 'static[u32] {
+            fn alpha()-> &'static[u32] {
                 &[$($val), *]
             }
-            fn beta()-> & 'static[u32] {
+            fn beta()-> &'static[u32] {
                 &[$($val), *]
             }
         }
@@ -1602,10 +1602,10 @@ macro_rules !implement_methods {
 }
 struct Foo;
 impl Foo {
-    fn alpha() -> & 'static[u32] {
+    fn alpha() -> &'static[u32] {
         &[1, 2, 3]
     }
-    fn beta() -> & 'static[u32] {
+    fn beta() -> &'static[u32] {
         &[1, 2, 3]
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index 2dff4adf2ee..d2505e7cafe 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -166,7 +166,7 @@ macro_rules! int_base {
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Binary for isize {
-    fn fmt(&self , f: &mut fmt::Formatter< '_>) -> fmt::Result {
+    fn fmt(&self , f: &mut fmt::Formatter<'_>) -> fmt::Result {
         Binary.fmt_int(*self as usize, f)
     }
 }
@@ -724,7 +724,7 @@ macro_rules! delegate_impl {
         }
     }
 }
-impl <> Data for & 'amut G where G: Data {}
+impl <> Data for &'amut G where G: Data {}
 "##]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
index 0710b1ac3d6..b8d2ca687c9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -78,7 +78,7 @@ m!(static bar: &'static str = "hello";);
 macro_rules! m {
     ($($t:tt)*) => { $($t)*}
 }
-static bar: & 'static str = "hello";
+static bar: &'static str = "hello";
 "#]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
index 72c44a0fbcb..029821e5e87 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
@@ -87,7 +87,7 @@ fn foo() { bar.; blub }
 fn foo() { bar.; blub }
 
 fn foo() {
-    bar. ;
+    bar.;
     blub
 }"##]],
     );
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
index 52a620fe22f..99f7f1b549e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
@@ -73,10 +73,12 @@ impl ModDir {
                 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
             }
             None if file_id.is_include_macro(db.upcast()) => {
+                let name = name.unescaped();
                 candidate_files.push(format!("{}.rs", name));
                 candidate_files.push(format!("{}/mod.rs", name));
             }
             None => {
+                let name = name.unescaped();
                 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
                 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
             }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
index 79a74873b4a..3fa585574de 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
@@ -132,9 +132,9 @@ pub struct Bar;
         expect![[r#"
             crate
             Bar: t v
-            async: t
+            r#async: t
 
-            crate::async
+            crate::r#async
             Bar: t v
         "#]],
     );
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
index 76da7c9f1ee..8befa7f7da7 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
@@ -251,9 +251,13 @@ fn format_args_expand(
     }
     for arg in &mut args {
         // Remove `key =`.
-        if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint)
+        if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=')
         {
-            arg.token_trees.drain(..2);
+            // but not with `==`
+            if !matches!(arg.token_trees.get(2), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' )
+            {
+                arg.token_trees.drain(..2);
+            }
         }
     }
     let _format_string = args.remove(0);
@@ -357,6 +361,12 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
     token.value().map(|it| it.into_owned())
 }
 
+fn unquote_char(lit: &tt::Literal) -> Option<char> {
+    let lit = ast::make::tokens::literal(&lit.to_string());
+    let token = ast::Char::cast(lit)?;
+    token.value()
+}
+
 fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> {
     let lit = ast::make::tokens::literal(&lit.to_string());
     let token = ast::ByteString::cast(lit)?;
@@ -408,8 +418,12 @@ fn concat_expand(
                 // concat works with string and char literals, so remove any quotes.
                 // It also works with integer, float and boolean literals, so just use the rest
                 // as-is.
-                let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
-                text.push_str(&component);
+                if let Some(c) = unquote_char(it) {
+                    text.push(c);
+                } else {
+                    let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
+                    text.push_str(&component);
+                }
             }
             // handle boolean literals
             tt::TokenTree::Leaf(tt::Leaf::Ident(id))
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
index e46f43a878f..893e6fe4b82 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
@@ -67,7 +67,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
             preorder.skip_subtree();
             continue;
         }
-
         // In some other situations, we can fix things by just appending some tokens.
         let end_range = TextRange::empty(node.text_range().end());
         match_ast! {
@@ -194,7 +193,75 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                     }
                 },
                 // FIXME: foo::
-                // FIXME: for, match etc.
+                ast::MatchExpr(it) => {
+                    if it.expr().is_none() {
+                        let match_token = match it.match_token() {
+                            Some(t) => t,
+                            None => continue
+                        };
+                        append.insert(match_token.into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::IDENT,
+                                text: "__ra_fixup".into(),
+                                range: end_range,
+                                id: EMPTY_ID
+                            },
+                        ]);
+                    }
+                    if it.match_arm_list().is_none() {
+                        // No match arms
+                        append.insert(node.clone().into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::L_CURLY,
+                                text: "{".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_CURLY,
+                                text: "}".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                        ]);
+                    }
+                },
+                ast::ForExpr(it) => {
+                    let for_token = match it.for_token() {
+                        Some(token) => token,
+                        None => continue
+                    };
+
+                    let [pat, in_token, iter] = [
+                        (SyntaxKind::UNDERSCORE, "_"),
+                        (SyntaxKind::IN_KW, "in"),
+                        (SyntaxKind::IDENT, "__ra_fixup")
+                    ].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID});
+
+                    if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
+                        append.insert(for_token.into(), vec![pat, in_token, iter]);
+                    // does something funky -- see test case for_no_pat
+                    } else if it.pat().is_none() {
+                        append.insert(for_token.into(), vec![pat]);
+                    }
+
+                    if it.loop_body().is_none() {
+                        append.insert(node.clone().into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::L_CURLY,
+                                text: "{".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_CURLY,
+                                text: "}".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                        ]);
+                    }
+                },
                 _ => (),
             }
         }
@@ -288,6 +355,111 @@ mod tests {
     }
 
     #[test]
+    fn just_for_token() {
+        check(
+            r#"
+fn foo() {
+    for
+}
+"#,
+            expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn for_no_iter_pattern() {
+        check(
+            r#"
+fn foo() {
+    for {}
+}
+"#,
+            expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn for_no_body() {
+        check(
+            r#"
+fn foo() {
+    for bar in qux
+}
+"#,
+            expect![[r#"
+fn foo () {for bar in qux {}}
+"#]],
+        )
+    }
+
+    // FIXME: https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695
+    #[test]
+    fn for_no_pat() {
+        check(
+            r#"
+fn foo() {
+    for in qux {
+
+    }
+}
+"#,
+            expect![[r#"
+fn foo () {__ra_fixup}
+"#]],
+        )
+    }
+
+    #[test]
+    fn match_no_expr_no_arms() {
+        check(
+            r#"
+fn foo() {
+    match
+}
+"#,
+            expect![[r#"
+fn foo () {match __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn match_expr_no_arms() {
+        check(
+            r#"
+fn foo() {
+    match x {
+
+    }
+}
+"#,
+            expect![[r#"
+fn foo () {match x {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn match_no_expr() {
+        check(
+            r#"
+fn foo() {
+    match {
+        _ => {}
+    }
+}
+"#,
+            expect![[r#"
+fn foo () {match __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
     fn incomplete_field_expr_1() {
         check(
             r#"
@@ -296,7 +468,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {a . __ra_fixup}
+fn foo () {a .__ra_fixup}
 "#]],
         )
     }
@@ -306,11 +478,11 @@ fn foo () {a . __ra_fixup}
         check(
             r#"
 fn foo() {
-    a. ;
+    a.;
 }
 "#,
             expect![[r#"
-fn foo () {a . __ra_fixup ;}
+fn foo () {a .__ra_fixup ;}
 "#]],
         )
     }
@@ -320,12 +492,12 @@ fn foo () {a . __ra_fixup ;}
         check(
             r#"
 fn foo() {
-    a. ;
+    a.;
     bar();
 }
 "#,
             expect![[r#"
-fn foo () {a . __ra_fixup ; bar () ;}
+fn foo () {a .__ra_fixup ; bar () ;}
 "#]],
         )
     }
@@ -353,7 +525,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {let x = a . __ra_fixup ;}
+fn foo () {let x = a .__ra_fixup ;}
 "#]],
         )
     }
@@ -369,7 +541,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {a . b ; bar () ;}
+fn foo () {a .b ; bar () ;}
 "#]],
         )
     }
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
index fea09521e87..d0f73ec8208 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/mod_path.rs
@@ -22,7 +22,7 @@ pub struct ModPath {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct EscapedModPath<'a>(&'a ModPath);
+pub struct UnescapedModPath<'a>(&'a ModPath);
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum PathKind {
@@ -102,8 +102,8 @@ impl ModPath {
         }
     }
 
-    pub fn escaped(&self) -> EscapedModPath<'_> {
-        EscapedModPath(self)
+    pub fn unescaped(&self) -> UnescapedModPath<'_> {
+        UnescapedModPath(self)
     }
 
     fn _fmt(&self, f: &mut fmt::Formatter<'_>, escaped: bool) -> fmt::Result {
@@ -134,9 +134,9 @@ impl ModPath {
             }
             first_segment = false;
             if escaped {
-                segment.escaped().fmt(f)?
-            } else {
                 segment.fmt(f)?
+            } else {
+                segment.unescaped().fmt(f)?
             };
         }
         Ok(())
@@ -145,13 +145,13 @@ impl ModPath {
 
 impl Display for ModPath {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self._fmt(f, false)
+        self._fmt(f, true)
     }
 }
 
-impl<'a> Display for EscapedModPath<'a> {
+impl<'a> Display for UnescapedModPath<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0._fmt(f, true)
+        self.0._fmt(f, false)
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
index 47d191822d8..87c663eec8e 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
@@ -7,12 +7,16 @@ use syntax::{ast, SmolStr, SyntaxKind};
 /// `Name` is a wrapper around string, which is used in hir for both references
 /// and declarations. In theory, names should also carry hygiene info, but we are
 /// not there yet!
+///
+/// Note that `Name` holds and prints escaped name i.e. prefixed with "r#" when it
+/// is a raw identifier. Use [`unescaped()`][Name::unescaped] when you need the
+/// name without "r#".
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct Name(Repr);
 
-/// `EscapedName` will add a prefix "r#" to the wrapped `Name` when it is a raw identifier
+/// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct EscapedName<'a>(&'a Name);
+pub struct UnescapedName<'a>(&'a Name);
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 enum Repr {
@@ -34,37 +38,26 @@ fn is_raw_identifier(name: &str) -> bool {
     is_keyword && !matches!(name, "self" | "crate" | "super" | "Self")
 }
 
-impl<'a> fmt::Display for EscapedName<'a> {
+impl<'a> fmt::Display for UnescapedName<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match &self.0 .0 {
             Repr::Text(text) => {
-                if is_raw_identifier(text) {
-                    write!(f, "r#{}", &text)
-                } else {
-                    fmt::Display::fmt(&text, f)
-                }
+                let text = text.strip_prefix("r#").unwrap_or(text);
+                fmt::Display::fmt(&text, f)
             }
             Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
         }
     }
 }
 
-impl<'a> EscapedName<'a> {
-    pub fn is_escaped(&self) -> bool {
-        match &self.0 .0 {
-            Repr::Text(it) => is_raw_identifier(&it),
-            Repr::TupleField(_) => false,
-        }
-    }
-
-    /// Returns the textual representation of this name as a [`SmolStr`].
-    /// Prefer using this over [`ToString::to_string`] if possible as this conversion is cheaper in
-    /// the general case.
+impl<'a> UnescapedName<'a> {
+    /// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over
+    /// [`ToString::to_string`] if possible as this conversion is cheaper in the general case.
     pub fn to_smol_str(&self) -> SmolStr {
         match &self.0 .0 {
             Repr::Text(it) => {
-                if is_raw_identifier(&it) {
-                    SmolStr::from_iter(["r#", &it])
+                if let Some(stripped) = it.strip_prefix("r#") {
+                    SmolStr::new(stripped)
                 } else {
                     it.clone()
                 }
@@ -97,9 +90,11 @@ impl Name {
 
     /// Resolve a name from the text of token.
     fn resolve(raw_text: &str) -> Name {
+        // When `raw_text` starts with "r#" but the name does not coincide with any
+        // keyword, we never need the prefix so we strip it.
         match raw_text.strip_prefix("r#") {
-            Some(text) => Name::new_text(SmolStr::new(text)),
-            None => Name::new_text(raw_text.into()),
+            Some(text) if !is_raw_identifier(text) => Name::new_text(SmolStr::new(text)),
+            _ => Name::new_text(raw_text.into()),
         }
     }
 
@@ -142,8 +137,15 @@ impl Name {
         }
     }
 
-    pub fn escaped(&self) -> EscapedName<'_> {
-        EscapedName(self)
+    pub fn unescaped(&self) -> UnescapedName<'_> {
+        UnescapedName(self)
+    }
+
+    pub fn is_escaped(&self) -> bool {
+        match &self.0 {
+            Repr::Text(it) => it.starts_with("r#"),
+            Repr::TupleField(_) => false,
+        }
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs
index 82f410ecda9..e839e97bf02 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/quote.rs
@@ -196,8 +196,8 @@ impl_to_to_tokentrees! {
     tt::Literal => self { self };
     tt::Ident => self { self };
     tt::Punct => self { self };
-    &str => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}};
-    String => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}}
+    &str => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}};
+    String => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}}
 }
 
 #[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
index 0495a4e64ca..6ecb6e6fd17 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -2,7 +2,6 @@
 
 use std::{
     collections::HashMap,
-    convert::TryInto,
     fmt::{Display, Write},
 };
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index 5e7320a5dd3..53259d66dec 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -14,8 +14,9 @@ use crate::{
     consteval::intern_const_scalar,
     infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
     lower::lower_to_chalk_mutability,
-    static_lifetime, ConcreteConst, ConstValue, Interner, Substitution, Ty, TyBuilder, TyExt,
-    TyKind,
+    primitive::UintTy,
+    static_lifetime, ConcreteConst, ConstValue, Interner, Scalar, Substitution, Ty, TyBuilder,
+    TyExt, TyKind,
 };
 
 use super::PatLike;
@@ -294,7 +295,29 @@ impl<'a> InferenceContext<'a> {
                 let start_ty = self.infer_expr(*start, &Expectation::has_type(expected.clone()));
                 self.infer_expr(*end, &Expectation::has_type(start_ty))
             }
-            Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
+            &Pat::Lit(expr) => {
+                // FIXME: using `Option` here is a workaround until we can use if-let chains in stable.
+                let mut pat_ty = None;
+
+                // Like slice patterns, byte string patterns can denote both `&[u8; N]` and `&[u8]`.
+                if let Expr::Literal(Literal::ByteString(_)) = self.body[expr] {
+                    if let Some((inner, ..)) = expected.as_reference() {
+                        let inner = self.resolve_ty_shallow(inner);
+                        if matches!(inner.kind(Interner), TyKind::Slice(_)) {
+                            let elem_ty = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner);
+                            let slice_ty = TyKind::Slice(elem_ty).intern(Interner);
+                            let ty = TyKind::Ref(Mutability::Not, static_lifetime(), slice_ty)
+                                .intern(Interner);
+                            self.write_expr_ty(expr, ty.clone());
+                            pat_ty = Some(ty);
+                        }
+                    }
+                }
+
+                pat_ty.unwrap_or_else(|| {
+                    self.infer_expr(expr, &Expectation::has_type(expected.clone()))
+                })
+            }
             Pat::Box { inner } => match self.resolve_boxed_box() {
                 Some(box_adt) => {
                     let (inner_ty, alloc_ty) = match expected.as_adt() {
@@ -343,7 +366,9 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
         // FIXME: ConstBlock/Path/Lit might actually evaluate to ref, but inference is unimplemented.
         Pat::Path(..) => true,
         Pat::ConstBlock(..) => true,
-        Pat::Lit(expr) => !matches!(body[*expr], Expr::Literal(Literal::String(..))),
+        Pat::Lit(expr) => {
+            !matches!(body[*expr], Expr::Literal(Literal::String(..) | Literal::ByteString(..)))
+        }
         Pat::Bind {
             mode: BindingAnnotation::Mutable | BindingAnnotation::Unannotated,
             subpat: Some(subpat),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
index 399553356b0..94efe7bc11a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs
@@ -316,6 +316,51 @@ fn infer_pattern_match_string_literal() {
 }
 
 #[test]
+fn infer_pattern_match_byte_string_literal() {
+    check_infer_with_mismatches(
+        r#"
+        //- minicore: index
+        struct S;
+        impl<T, const N: usize> core::ops::Index<S> for [T; N] {
+            type Output = [u8];
+            fn index(&self, index: core::ops::RangeFull) -> &Self::Output {
+                loop {}
+            }
+        }
+        fn test(v: [u8; 3]) {
+            if let b"foo" = &v[S] {}
+            if let b"foo" = &v {}
+        }
+        "#,
+        expect![[r#"
+            105..109 'self': &[T; N]
+            111..116 'index': {unknown}
+            157..180 '{     ...     }': &[u8]
+            167..174 'loop {}': !
+            172..174 '{}': ()
+            191..192 'v': [u8; 3]
+            203..261 '{     ...v {} }': ()
+            209..233 'if let...[S] {}': ()
+            212..230 'let b"... &v[S]': bool
+            216..222 'b"foo"': &[u8]
+            216..222 'b"foo"': &[u8]
+            225..230 '&v[S]': &[u8]
+            226..227 'v': [u8; 3]
+            226..230 'v[S]': [u8]
+            228..229 'S': S
+            231..233 '{}': ()
+            238..259 'if let... &v {}': ()
+            241..256 'let b"foo" = &v': bool
+            245..251 'b"foo"': &[u8; 3]
+            245..251 'b"foo"': &[u8; 3]
+            254..256 '&v': &[u8; 3]
+            255..256 'v': [u8; 3]
+            257..259 '{}': ()
+        "#]],
+    );
+}
+
+#[test]
 fn infer_pattern_match_or() {
     check_infer_with_mismatches(
         r#"
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index 6c6c11ea4eb..50374f4b3fe 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -14,6 +14,7 @@ use crate::{MacroKind, Type};
 
 macro_rules! diagnostics {
     ($($diag:ident,)*) => {
+        #[derive(Debug)]
         pub enum AnyDiagnostic {$(
             $diag(Box<$diag>),
         )*}
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index f5e2e443070..ae2896e1932 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -368,6 +368,7 @@ impl SourceAnalyzer {
         let local = if field.name_ref().is_some() {
             None
         } else {
+            // Shorthand syntax, resolve to the local
             let path = ModPath::from_segments(PathKind::Plain, once(local_name.clone()));
             match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
                 Some(ValueNs::LocalBinding(pat_id)) => {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
index f9b42661425..8c7670e0cb7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
@@ -1,28 +1,20 @@
 //! See [`AssistContext`].
 
-use std::mem;
-
 use hir::Semantics;
-use ide_db::{
-    base_db::{AnchoredPathBuf, FileId, FileRange},
-    SnippetCap,
-};
-use ide_db::{
-    label::Label,
-    source_change::{FileSystemEdit, SourceChange},
-    RootDatabase,
-};
+use ide_db::base_db::{FileId, FileRange};
+use ide_db::{label::Label, RootDatabase};
 use syntax::{
     algo::{self, find_node_at_offset, find_node_at_range},
-    AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
-    SyntaxToken, TextRange, TextSize, TokenAtOffset,
+    AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange,
+    TextSize, TokenAtOffset,
 };
-use text_edit::{TextEdit, TextEditBuilder};
 
 use crate::{
     assist_config::AssistConfig, Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel,
 };
 
+pub(crate) use ide_db::source_change::{SourceChangeBuilder, TreeMutator};
+
 /// `AssistContext` allows to apply an assist or check if it could be applied.
 ///
 /// Assists use a somewhat over-engineered approach, given the current needs.
@@ -163,7 +155,7 @@ impl Assists {
         id: AssistId,
         label: impl Into<String>,
         target: TextRange,
-        f: impl FnOnce(&mut AssistBuilder),
+        f: impl FnOnce(&mut SourceChangeBuilder),
     ) -> Option<()> {
         let mut f = Some(f);
         self.add_impl(None, id, label.into(), target, &mut |it| f.take().unwrap()(it))
@@ -175,7 +167,7 @@ impl Assists {
         id: AssistId,
         label: impl Into<String>,
         target: TextRange,
-        f: impl FnOnce(&mut AssistBuilder),
+        f: impl FnOnce(&mut SourceChangeBuilder),
     ) -> Option<()> {
         let mut f = Some(f);
         self.add_impl(Some(group), id, label.into(), target, &mut |it| f.take().unwrap()(it))
@@ -187,7 +179,7 @@ impl Assists {
         id: AssistId,
         label: String,
         target: TextRange,
-        f: &mut dyn FnMut(&mut AssistBuilder),
+        f: &mut dyn FnMut(&mut SourceChangeBuilder),
     ) -> Option<()> {
         if !self.is_allowed(&id) {
             return None;
@@ -195,7 +187,7 @@ impl Assists {
 
         let mut trigger_signature_help = false;
         let source_change = if self.resolve.should_resolve(&id) {
-            let mut builder = AssistBuilder::new(self.file);
+            let mut builder = SourceChangeBuilder::new(self.file);
             f(&mut builder);
             trigger_signature_help = builder.trigger_signature_help;
             Some(builder.finish())
@@ -216,132 +208,3 @@ impl Assists {
         }
     }
 }
-
-pub(crate) struct AssistBuilder {
-    edit: TextEditBuilder,
-    file_id: FileId,
-    source_change: SourceChange,
-    trigger_signature_help: bool,
-
-    /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
-    mutated_tree: Option<TreeMutator>,
-}
-
-pub(crate) struct TreeMutator {
-    immutable: SyntaxNode,
-    mutable_clone: SyntaxNode,
-}
-
-impl TreeMutator {
-    pub(crate) fn new(immutable: &SyntaxNode) -> TreeMutator {
-        let immutable = immutable.ancestors().last().unwrap();
-        let mutable_clone = immutable.clone_for_update();
-        TreeMutator { immutable, mutable_clone }
-    }
-
-    pub(crate) fn make_mut<N: AstNode>(&self, node: &N) -> N {
-        N::cast(self.make_syntax_mut(node.syntax())).unwrap()
-    }
-
-    pub(crate) fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
-        let ptr = SyntaxNodePtr::new(node);
-        ptr.to_node(&self.mutable_clone)
-    }
-}
-
-impl AssistBuilder {
-    pub(crate) fn new(file_id: FileId) -> AssistBuilder {
-        AssistBuilder {
-            edit: TextEdit::builder(),
-            file_id,
-            source_change: SourceChange::default(),
-            trigger_signature_help: false,
-            mutated_tree: None,
-        }
-    }
-
-    pub(crate) fn edit_file(&mut self, file_id: FileId) {
-        self.commit();
-        self.file_id = file_id;
-    }
-
-    fn commit(&mut self) {
-        if let Some(tm) = self.mutated_tree.take() {
-            algo::diff(&tm.immutable, &tm.mutable_clone).into_text_edit(&mut self.edit)
-        }
-
-        let edit = mem::take(&mut self.edit).finish();
-        if !edit.is_empty() {
-            self.source_change.insert_source_edit(self.file_id, edit);
-        }
-    }
-
-    pub(crate) fn make_mut<N: AstNode>(&mut self, node: N) -> N {
-        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(node.syntax())).make_mut(&node)
-    }
-    /// Returns a copy of the `node`, suitable for mutation.
-    ///
-    /// Syntax trees in rust-analyzer are typically immutable, and mutating
-    /// operations panic at runtime. However, it is possible to make a copy of
-    /// the tree and mutate the copy freely. Mutation is based on interior
-    /// mutability, and different nodes in the same tree see the same mutations.
-    ///
-    /// The typical pattern for an assist is to find specific nodes in the read
-    /// phase, and then get their mutable couterparts using `make_mut` in the
-    /// mutable state.
-    pub(crate) fn make_syntax_mut(&mut self, node: SyntaxNode) -> SyntaxNode {
-        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(&node)).make_syntax_mut(&node)
-    }
-
-    /// Remove specified `range` of text.
-    pub(crate) fn delete(&mut self, range: TextRange) {
-        self.edit.delete(range)
-    }
-    /// Append specified `text` at the given `offset`
-    pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
-        self.edit.insert(offset, text.into())
-    }
-    /// Append specified `snippet` at the given `offset`
-    pub(crate) fn insert_snippet(
-        &mut self,
-        _cap: SnippetCap,
-        offset: TextSize,
-        snippet: impl Into<String>,
-    ) {
-        self.source_change.is_snippet = true;
-        self.insert(offset, snippet);
-    }
-    /// Replaces specified `range` of text with a given string.
-    pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
-        self.edit.replace(range, replace_with.into())
-    }
-    /// Replaces specified `range` of text with a given `snippet`.
-    pub(crate) fn replace_snippet(
-        &mut self,
-        _cap: SnippetCap,
-        range: TextRange,
-        snippet: impl Into<String>,
-    ) {
-        self.source_change.is_snippet = true;
-        self.replace(range, snippet);
-    }
-    pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
-        algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
-    }
-    pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
-        let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
-        self.source_change.push_file_system_edit(file_system_edit);
-    }
-    pub(crate) fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
-        let file_system_edit = FileSystemEdit::MoveFile { src, dst };
-        self.source_change.push_file_system_edit(file_system_edit);
-    }
-    pub(crate) fn trigger_signature_help(&mut self) {
-        self.trigger_signature_help = true;
-    }
-
-    fn finish(mut self) -> SourceChange {
-        self.commit();
-        mem::take(&mut self.source_change)
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index c808c010c67..62cf5ab4f37 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -944,7 +944,7 @@ foo!();
 struct Foo(usize);
 
 impl FooB for Foo {
-    $0fn foo< 'lt>(& 'lt self){}
+    $0fn foo<'lt>(&'lt self){}
 }
 "#,
         )
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index 4ab8e93a290..d8f52270846 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -5,7 +5,7 @@ use syntax::{
     match_ast, SyntaxNode,
 };
 
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: convert_tuple_struct_to_named_struct
 //
@@ -80,7 +80,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
 
 fn edit_struct_def(
     ctx: &AssistContext<'_>,
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     strukt: &Either<ast::Struct, ast::Variant>,
     tuple_fields: ast::TupleFieldList,
     names: Vec<ast::Name>,
@@ -122,7 +122,7 @@ fn edit_struct_def(
 
 fn edit_struct_references(
     ctx: &AssistContext<'_>,
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     strukt: Either<hir::Struct, hir::Variant>,
     names: &[ast::Name],
 ) {
@@ -132,7 +132,7 @@ fn edit_struct_references(
     };
     let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();
 
-    let edit_node = |edit: &mut AssistBuilder, node: SyntaxNode| -> Option<()> {
+    let edit_node = |edit: &mut SourceChangeBuilder, node: SyntaxNode| -> Option<()> {
         match_ast! {
             match node {
                 ast::TupleStructPat(tuple_struct_pat) => {
@@ -203,7 +203,7 @@ fn edit_struct_references(
 
 fn edit_field_references(
     ctx: &AssistContext<'_>,
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     fields: impl Iterator<Item = ast::TupleField>,
     names: &[ast::Name],
 ) {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
index c1f57532bb2..dc581ff3bd2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
@@ -8,7 +8,7 @@ use syntax::{
     TextRange,
 };
 
-use crate::assist_context::{AssistBuilder, AssistContext, Assists};
+use crate::assist_context::{AssistContext, Assists, SourceChangeBuilder};
 
 // Assist: destructure_tuple_binding
 //
@@ -151,7 +151,7 @@ struct TupleData {
 }
 fn edit_tuple_assignment(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     data: &TupleData,
     in_sub_pattern: bool,
 ) {
@@ -195,7 +195,7 @@ fn edit_tuple_assignment(
 
 fn edit_tuple_usages(
     data: &TupleData,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     ctx: &AssistContext<'_>,
     in_sub_pattern: bool,
 ) {
@@ -211,7 +211,7 @@ fn edit_tuple_usages(
 }
 fn edit_tuple_usage(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     usage: &FileReference,
     data: &TupleData,
     in_sub_pattern: bool,
@@ -239,7 +239,7 @@ fn edit_tuple_usage(
 
 fn edit_tuple_field_usage(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     data: &TupleData,
     index: TupleIndex,
 ) {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index a93648f2d31..dfb56521264 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -20,7 +20,7 @@ use syntax::{
     SyntaxNode, T,
 };
 
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: extract_struct_from_enum_variant
 //
@@ -374,7 +374,7 @@ fn apply_references(
 
 fn process_references(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     visited_modules: &mut FxHashSet<Module>,
     enum_module_def: &ModuleDef,
     variant_hir_name: &Name,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
index b9637ee8d7c..b484635121e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
@@ -8,7 +8,7 @@ use syntax::{
 };
 
 use crate::{
-    assist_context::{AssistBuilder, AssistContext, Assists},
+    assist_context::{AssistContext, Assists, SourceChangeBuilder},
     utils::generate_trait_impl_text,
     AssistId, AssistKind,
 };
@@ -120,7 +120,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
 }
 
 fn generate_edit(
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     strukt: ast::Struct,
     field_type_syntax: &SyntaxNode,
     field_name: impl Display,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
index ce91dd23703..2fc754e3e50 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
@@ -5,7 +5,7 @@ use syntax::{
     AstNode, TextRange,
 };
 
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
 
 static ASSIST_NAME: &str = "introduce_named_lifetime";
 static ASSIST_LABEL: &str = "Introduce named lifetime";
@@ -140,7 +140,7 @@ enum NeedsLifetime {
 }
 
 impl NeedsLifetime {
-    fn make_mut(self, builder: &mut AssistBuilder) -> Self {
+    fn make_mut(self, builder: &mut SourceChangeBuilder) -> Self {
         match self {
             Self::SelfParam(it) => Self::SelfParam(builder.make_mut(it)),
             Self::RefType(it) => Self::RefType(builder.make_mut(it)),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
index 59ea94ea1ff..bd2e8fbe389 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
@@ -8,7 +8,8 @@ use syntax::{
 use SyntaxKind::WHITESPACE;
 
 use crate::{
-    assist_context::AssistBuilder, utils::next_prev, AssistContext, AssistId, AssistKind, Assists,
+    assist_context::SourceChangeBuilder, utils::next_prev, AssistContext, AssistId, AssistKind,
+    Assists,
 };
 
 // Assist: remove_unused_param
@@ -88,7 +89,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) ->
 
 fn process_usages(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     file_id: FileId,
     references: Vec<FileReference>,
     arg_to_remove: usize,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index bd50208da5f..d139f78a6f3 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -10,7 +10,7 @@ use syntax::{
 };
 
 use crate::{
-    assist_context::{AssistBuilder, AssistContext, Assists},
+    assist_context::{AssistContext, Assists, SourceChangeBuilder},
     utils::{
         add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_fn_body,
         generate_trait_impl_text, render_snippet, Cursor, DefaultMethods,
@@ -224,7 +224,7 @@ fn impl_def_from_trait(
 }
 
 fn update_attribute(
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     old_derives: &[ast::Path],
     old_tree: &ast::TokenTree,
     old_trait_path: &ast::Path,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index 3e61d0741d3..103e3259fa2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -20,7 +20,7 @@ use syntax::{
     SyntaxNode, TextRange, TextSize, T,
 };
 
-use crate::assist_context::{AssistBuilder, AssistContext};
+use crate::assist_context::{AssistContext, SourceChangeBuilder};
 
 pub(crate) mod suggest_name;
 mod gen_trait_fn_body;
@@ -484,7 +484,7 @@ fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str
 }
 
 pub(crate) fn add_method_to_adt(
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     adt: &ast::Adt,
     impl_def: Option<ast::Impl>,
     method: &str,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
index 72579e6026a..55c3e28392a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -617,7 +617,6 @@ pub(super) fn complete_name_ref(
 
                     dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx);
                     item_list::complete_item_list_in_expr(acc, ctx, path_ctx, expr_ctx);
-                    record::complete_record_expr_func_update(acc, ctx, path_ctx, expr_ctx);
                     snippet::complete_expr_snippet(acc, ctx, path_ctx, expr_ctx);
                 }
                 PathKind::Type { location } => {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
index 5d0ddaaf2a2..4d66af9e8d5 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
@@ -1,8 +1,10 @@
 //! Completion of names from the current scope in expression position.
 
 use hir::ScopeDef;
+use syntax::ast;
 
 use crate::{
+    completions::record::add_default_update,
     context::{ExprCtx, PathCompletionCtx, Qualified},
     CompletionContext, Completions,
 };
@@ -219,60 +221,78 @@ pub(crate) fn complete_expr_path(
                 _ => (),
             });
 
-            if is_func_update.is_none() {
-                let mut add_keyword =
-                    |kw, snippet| acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet);
+            match is_func_update {
+                Some(record_expr) => {
+                    let ty = ctx.sema.type_of_expr(&ast::Expr::RecordExpr(record_expr.clone()));
 
-                if !in_block_expr {
-                    add_keyword("unsafe", "unsafe {\n    $0\n}");
-                }
-                add_keyword("match", "match $1 {\n    $0\n}");
-                add_keyword("while", "while $1 {\n    $0\n}");
-                add_keyword("while let", "while let $1 = $2 {\n    $0\n}");
-                add_keyword("loop", "loop {\n    $0\n}");
-                if in_match_guard {
-                    add_keyword("if", "if $0");
-                } else {
-                    add_keyword("if", "if $1 {\n    $0\n}");
+                    match ty.as_ref().and_then(|t| t.original.as_adt()) {
+                        Some(hir::Adt::Union(_)) => (),
+                        _ => {
+                            cov_mark::hit!(functional_update);
+                            let missing_fields =
+                                ctx.sema.record_literal_missing_fields(record_expr);
+                            if !missing_fields.is_empty() {
+                                add_default_update(acc, ctx, ty);
+                            }
+                        }
+                    };
                 }
-                add_keyword("if let", "if let $1 = $2 {\n    $0\n}");
-                add_keyword("for", "for $1 in $2 {\n    $0\n}");
-                add_keyword("true", "true");
-                add_keyword("false", "false");
+                None => {
+                    let mut add_keyword = |kw, snippet| {
+                        acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet)
+                    };
 
-                if in_condition || in_block_expr {
-                    add_keyword("let", "let");
-                }
+                    if !in_block_expr {
+                        add_keyword("unsafe", "unsafe {\n    $0\n}");
+                    }
+                    add_keyword("match", "match $1 {\n    $0\n}");
+                    add_keyword("while", "while $1 {\n    $0\n}");
+                    add_keyword("while let", "while let $1 = $2 {\n    $0\n}");
+                    add_keyword("loop", "loop {\n    $0\n}");
+                    if in_match_guard {
+                        add_keyword("if", "if $0");
+                    } else {
+                        add_keyword("if", "if $1 {\n    $0\n}");
+                    }
+                    add_keyword("if let", "if let $1 = $2 {\n    $0\n}");
+                    add_keyword("for", "for $1 in $2 {\n    $0\n}");
+                    add_keyword("true", "true");
+                    add_keyword("false", "false");
 
-                if after_if_expr {
-                    add_keyword("else", "else {\n    $0\n}");
-                    add_keyword("else if", "else if $1 {\n    $0\n}");
-                }
+                    if in_condition || in_block_expr {
+                        add_keyword("let", "let");
+                    }
 
-                if wants_mut_token {
-                    add_keyword("mut", "mut ");
-                }
+                    if after_if_expr {
+                        add_keyword("else", "else {\n    $0\n}");
+                        add_keyword("else if", "else if $1 {\n    $0\n}");
+                    }
 
-                if in_loop_body {
-                    if in_block_expr {
-                        add_keyword("continue", "continue;");
-                        add_keyword("break", "break;");
-                    } else {
-                        add_keyword("continue", "continue");
-                        add_keyword("break", "break");
+                    if wants_mut_token {
+                        add_keyword("mut", "mut ");
+                    }
+
+                    if in_loop_body {
+                        if in_block_expr {
+                            add_keyword("continue", "continue;");
+                            add_keyword("break", "break;");
+                        } else {
+                            add_keyword("continue", "continue");
+                            add_keyword("break", "break");
+                        }
                     }
-                }
 
-                if let Some(ty) = innermost_ret_ty {
-                    add_keyword(
-                        "return",
-                        match (in_block_expr, ty.is_unit()) {
-                            (true, true) => "return ;",
-                            (true, false) => "return;",
-                            (false, true) => "return $0",
-                            (false, false) => "return",
-                        },
-                    );
+                    if let Some(ty) = innermost_ret_ty {
+                        add_keyword(
+                            "return",
+                            match (in_block_expr, ty.is_unit()) {
+                                (true, true) => "return ;",
+                                (true, false) => "return;",
+                                (false, true) => "return $0",
+                                (false, false) => "return",
+                            },
+                        );
+                    }
                 }
             }
         }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
index e9256803cc4..785db6fde1d 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -233,7 +233,8 @@ fn add_type_alias_impl(
     type_alias: hir::TypeAlias,
 ) {
     let alias_name = type_alias.name(ctx.db);
-    let (alias_name, escaped_name) = (alias_name.to_smol_str(), alias_name.escaped().to_smol_str());
+    let (alias_name, escaped_name) =
+        (alias_name.unescaped().to_smol_str(), alias_name.to_smol_str());
 
     let label = format!("type {} =", alias_name);
     let replacement = format!("type {} = ", escaped_name);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs
index 1c9042390d3..bfb98b9f277 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/record.rs
@@ -3,7 +3,7 @@ use ide_db::SymbolKind;
 use syntax::ast::{self, Expr};
 
 use crate::{
-    context::{DotAccess, DotAccessKind, ExprCtx, PathCompletionCtx, PatternContext, Qualified},
+    context::{DotAccess, DotAccessKind, PatternContext},
     CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
     CompletionRelevancePostfixMatch, Completions,
 };
@@ -14,7 +14,24 @@ pub(crate) fn complete_record_pattern_fields(
     pattern_ctx: &PatternContext,
 ) {
     if let PatternContext { record_pat: Some(record_pat), .. } = pattern_ctx {
-        complete_fields(acc, ctx, ctx.sema.record_pattern_missing_fields(record_pat));
+        let ty = ctx.sema.type_of_pat(&ast::Pat::RecordPat(record_pat.clone()));
+        let missing_fields = match ty.as_ref().and_then(|t| t.original.as_adt()) {
+            Some(hir::Adt::Union(un)) => {
+                // ctx.sema.record_pat_missing_fields will always return
+                // an empty Vec on a union literal. This is normally
+                // reasonable, but here we'd like to present the full list
+                // of fields if the literal is empty.
+                let were_fields_specified =
+                    record_pat.record_pat_field_list().and_then(|fl| fl.fields().next()).is_some();
+
+                match were_fields_specified {
+                    false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
+                    true => return,
+                }
+            }
+            _ => ctx.sema.record_pattern_missing_fields(record_pat),
+        };
+        complete_fields(acc, ctx, missing_fields);
     }
 }
 
@@ -42,8 +59,13 @@ pub(crate) fn complete_record_expr_fields(
         }
         _ => {
             let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
-            add_default_update(acc, ctx, ty, &missing_fields);
+
+            if !missing_fields.is_empty() {
+                cov_mark::hit!(functional_update_field);
+                add_default_update(acc, ctx, ty);
+            }
             if dot_prefix {
+                cov_mark::hit!(functional_update_one_dot);
                 let mut item =
                     CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), "..");
                 item.insert_text(".");
@@ -56,41 +78,18 @@ pub(crate) fn complete_record_expr_fields(
     complete_fields(acc, ctx, missing_fields);
 }
 
-// FIXME: This should probably be part of complete_path_expr
-pub(crate) fn complete_record_expr_func_update(
-    acc: &mut Completions,
-    ctx: &CompletionContext<'_>,
-    path_ctx: &PathCompletionCtx,
-    expr_ctx: &ExprCtx,
-) {
-    if !matches!(path_ctx.qualified, Qualified::No) {
-        return;
-    }
-    if let ExprCtx { is_func_update: Some(record_expr), .. } = expr_ctx {
-        let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
-
-        match ty.as_ref().and_then(|t| t.original.as_adt()) {
-            Some(hir::Adt::Union(_)) => (),
-            _ => {
-                let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
-                add_default_update(acc, ctx, ty, &missing_fields);
-            }
-        };
-    }
-}
-
-fn add_default_update(
+pub(crate) fn add_default_update(
     acc: &mut Completions,
     ctx: &CompletionContext<'_>,
     ty: Option<hir::TypeInfo>,
-    missing_fields: &[(hir::Field, hir::Type)],
 ) {
     let default_trait = ctx.famous_defs().core_default_Default();
-    let impl_default_trait = default_trait
+    let impls_default_trait = default_trait
         .zip(ty.as_ref())
         .map_or(false, |(default_trait, ty)| ty.original.impls_trait(ctx.db, default_trait, &[]));
-    if impl_default_trait && !missing_fields.is_empty() {
+    if impls_default_trait {
         // FIXME: This should make use of scope_def like completions so we get all the other goodies
+        // that is we should handle this like actually completing the default function
         let completion_text = "..Default::default()";
         let mut item = CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
         let completion_text =
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index e35f79d2b69..759742d3472 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -134,6 +134,7 @@ pub(crate) struct ExprCtx {
     pub(crate) in_condition: bool,
     pub(crate) incomplete_let: bool,
     pub(crate) ref_expr_parent: Option<ast::RefExpr>,
+    /// The surrounding RecordExpression we are completing a functional update
     pub(crate) is_func_update: Option<ast::RecordExpr>,
     pub(crate) self_param: Option<hir::SelfParam>,
     pub(crate) innermost_ret_ty: Option<hir::Type>,
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
index 946134b0ff9..693007ca307 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -117,7 +117,7 @@ pub(crate) fn render_field(
 ) -> CompletionItem {
     let is_deprecated = ctx.is_deprecated(field);
     let name = field.name(ctx.db());
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let mut item = CompletionItem::new(
         SymbolKind::Field,
         ctx.source_range(),
@@ -283,8 +283,8 @@ fn render_resolution_path(
 
     let name = local_name.to_smol_str();
     let mut item = render_resolution_simple_(ctx, &local_name, import_to_add, resolution);
-    if local_name.escaped().is_escaped() {
-        item.insert_text(local_name.escaped().to_smol_str());
+    if local_name.is_escaped() {
+        item.insert_text(local_name.to_smol_str());
     }
     // Add `<>` for generic types
     let type_path_no_ty_args = matches!(
@@ -306,7 +306,7 @@ fn render_resolution_path(
                 item.lookup_by(name.clone())
                     .label(SmolStr::from_iter([&name, "<…>"]))
                     .trigger_call_info()
-                    .insert_snippet(cap, format!("{}<$0>", local_name.escaped()));
+                    .insert_snippet(cap, format!("{}<$0>", local_name));
             }
         }
     }
@@ -342,7 +342,8 @@ fn render_resolution_simple_(
     let ctx = ctx.import_to_add(import_to_add);
     let kind = res_to_kind(resolution);
 
-    let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.to_smol_str());
+    let mut item =
+        CompletionItem::new(kind, ctx.source_range(), local_name.unescaped().to_smol_str());
     item.set_relevance(ctx.completion_relevance())
         .set_documentation(scope_def_docs(db, resolution))
         .set_deprecated(scope_def_is_deprecated(&ctx, resolution));
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
index a810eef18dd..93ea825e004 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/const_.rs
@@ -13,7 +13,7 @@ pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option
 fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
     let db = ctx.db();
     let name = const_.name(db)?;
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let detail = const_.display(db).to_string();
 
     let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), name.clone());
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
index 4b5535718c5..9cf64691298 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/function.rs
@@ -52,10 +52,10 @@ fn render(
 
     let (call, escaped_call) = match &func_kind {
         FuncKind::Method(_, Some(receiver)) => (
-            format!("{}.{}", receiver, &name).into(),
-            format!("{}.{}", receiver.escaped(), name.escaped()).into(),
+            format!("{}.{}", receiver.unescaped(), name.unescaped()).into(),
+            format!("{}.{}", receiver, name).into(),
         ),
-        _ => (name.to_smol_str(), name.escaped().to_smol_str()),
+        _ => (name.unescaped().to_smol_str(), name.to_smol_str()),
     };
     let mut item = CompletionItem::new(
         if func.self_param(db).is_some() {
@@ -96,7 +96,7 @@ fn render(
     item.set_documentation(ctx.docs(func))
         .set_deprecated(ctx.is_deprecated(func) || ctx.is_deprecated_assoc_item(func))
         .detail(detail(db, func))
-        .lookup_by(name.to_smol_str());
+        .lookup_by(name.unescaped().to_smol_str());
 
     match ctx.completion.config.snippet_cap {
         Some(cap) => {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
index 91a253f8fc8..707dea206be 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/literal.rs
@@ -73,7 +73,7 @@ fn render(
         None => (name.clone().into(), name.into(), false),
     };
     let (qualified_name, escaped_qualified_name) =
-        (qualified_name.to_string(), qualified_name.escaped().to_string());
+        (qualified_name.unescaped().to_string(), qualified_name.to_string());
     let snippet_cap = ctx.snippet_cap();
 
     let mut rendered = match kind {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
index ca2269f1398..eabd0bd17d6 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/macro_.rs
@@ -46,7 +46,7 @@ fn render(
         ctx.source_range()
     };
 
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let docs = ctx.docs(macro_);
     let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default();
     let is_fn_like = macro_.is_fn_like(completion.db);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
index 34a384f2f7a..1c1299e33b6 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs
@@ -31,7 +31,7 @@ pub(crate) fn render_struct_pat(
     }
 
     let name = local_name.unwrap_or_else(|| strukt.name(ctx.db()));
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let kind = strukt.kind(ctx.db());
     let label = format_literal_label(name.as_str(), kind);
     let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?;
@@ -53,10 +53,10 @@ pub(crate) fn render_variant_pat(
     let (visible_fields, fields_omitted) = visible_fields(ctx.completion, &fields, variant)?;
 
     let (name, escaped_name) = match path {
-        Some(path) => (path.to_string().into(), path.escaped().to_string().into()),
+        Some(path) => (path.unescaped().to_string().into(), path.to_string().into()),
         None => {
             let name = local_name.unwrap_or_else(|| variant.name(ctx.db()));
-            (name.to_smol_str(), name.escaped().to_smol_str())
+            (name.unescaped().to_smol_str(), name.to_smol_str())
         }
     };
 
@@ -146,7 +146,7 @@ fn render_record_as_pat(
             format!(
                 "{name} {{ {}{} }}",
                 fields.enumerate().format_with(", ", |(idx, field), f| {
-                    f(&format_args!("{}${}", field.name(db).escaped(), idx + 1))
+                    f(&format_args!("{}${}", field.name(db), idx + 1))
                 }),
                 if fields_omitted { ", .." } else { "" },
                 name = name
@@ -155,7 +155,7 @@ fn render_record_as_pat(
         None => {
             format!(
                 "{name} {{ {}{} }}",
-                fields.map(|field| field.name(db).escaped().to_smol_str()).format(", "),
+                fields.map(|field| field.name(db).to_smol_str()).format(", "),
                 if fields_omitted { ", .." } else { "" },
                 name = name
             )
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
index f1b23c76e7b..de919429f2f 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/type_alias.rs
@@ -32,11 +32,11 @@ fn render(
     let name = type_alias.name(db);
     let (name, escaped_name) = if with_eq {
         (
+            SmolStr::from_iter([&name.unescaped().to_smol_str(), " = "]),
             SmolStr::from_iter([&name.to_smol_str(), " = "]),
-            SmolStr::from_iter([&name.escaped().to_smol_str(), " = "]),
         )
     } else {
-        (name.to_smol_str(), name.escaped().to_smol_str())
+        (name.unescaped().to_smol_str(), name.to_smol_str())
     };
     let detail = type_alias.display(db).to_string();
 
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs
index 9c9540a9bd9..bb32330f276 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/union_literal.rs
@@ -21,8 +21,8 @@ pub(crate) fn render_union_literal(
     let name = local_name.unwrap_or_else(|| un.name(ctx.db()));
 
     let (qualified_name, escaped_qualified_name) = match path {
-        Some(p) => (p.to_string(), p.escaped().to_string()),
-        None => (name.to_string(), name.escaped().to_string()),
+        Some(p) => (p.unescaped().to_string(), p.to_string()),
+        None => (name.unescaped().to_string(), name.to_string()),
     };
 
     let mut item = CompletionItem::new(
@@ -42,15 +42,15 @@ pub(crate) fn render_union_literal(
         format!(
             "{} {{ ${{1|{}|}}: ${{2:()}} }}$0",
             escaped_qualified_name,
-            fields.iter().map(|field| field.name(ctx.db()).escaped().to_smol_str()).format(",")
+            fields.iter().map(|field| field.name(ctx.db()).to_smol_str()).format(",")
         )
     } else {
         format!(
             "{} {{ {} }}",
             escaped_qualified_name,
-            fields.iter().format_with(", ", |field, f| {
-                f(&format_args!("{}: ()", field.name(ctx.db()).escaped()))
-            })
+            fields
+                .iter()
+                .format_with(", ", |field, f| { f(&format_args!("{}: ()", field.name(ctx.db()))) })
         )
     };
 
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs
index 003a0c11ed2..664845330eb 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/variant.rs
@@ -24,9 +24,9 @@ pub(crate) fn render_record_lit(
 ) -> RenderedLiteral {
     let completions = fields.iter().enumerate().format_with(", ", |(idx, field), f| {
         if snippet_cap.is_some() {
-            f(&format_args!("{}: ${{{}:()}}", field.name(db).escaped(), idx + 1))
+            f(&format_args!("{}: ${{{}:()}}", field.name(db), idx + 1))
         } else {
-            f(&format_args!("{}: ()", field.name(db).escaped()))
+            f(&format_args!("{}: ()", field.name(db)))
         }
     });
 
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs
index f6accc68e5e..328faaa060f 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/record.rs
@@ -103,8 +103,9 @@ fn foo(f: Struct) {
 }
 
 #[test]
-fn functional_update() {
-    // FIXME: This should filter out all completions that do not have the type `Foo`
+fn in_functional_update() {
+    cov_mark::check!(functional_update);
+
     check(
         r#"
 //- minicore:default
@@ -116,13 +117,21 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, $0 }
+    let foo2 = Foo { thing, ..$0 }
 }
 "#,
         expect![[r#"
             fd ..Default::default()
-            fd foo1                 u32
-            fd foo2                 u32
+            fn main()               fn()
+            lc foo                  Foo
+            lc thing                i32
+            md core
+            st Foo
+            st Foo {…}              Foo { foo1: u32, foo2: u32 }
+            tt Default
+            bt u32
+            kw crate::
+            kw self::
         "#]],
     );
     check(
@@ -136,14 +145,19 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, .$0 }
+    let foo2 = Foo { thing, ..Default::$0 }
 }
 "#,
         expect![[r#"
-            fd ..Default::default()
-            sn ..
+            fn default() (as Default) fn() -> Self
         "#]],
     );
+}
+
+#[test]
+fn functional_update_no_dot() {
+    cov_mark::check!(functional_update_field);
+    // FIXME: This should filter out all completions that do not have the type `Foo`
     check(
         r#"
 //- minicore:default
@@ -155,23 +169,20 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, ..$0 }
+    let foo2 = Foo { thing, $0 }
 }
 "#,
         expect![[r#"
             fd ..Default::default()
-            fn main()               fn()
-            lc foo                  Foo
-            lc thing                i32
-            md core
-            st Foo
-            st Foo {…}              Foo { foo1: u32, foo2: u32 }
-            tt Default
-            bt u32
-            kw crate::
-            kw self::
+            fd foo1                 u32
+            fd foo2                 u32
         "#]],
     );
+}
+
+#[test]
+fn functional_update_one_dot() {
+    cov_mark::check!(functional_update_one_dot);
     check(
         r#"
 //- minicore:default
@@ -183,11 +194,12 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, ..Default::$0 }
+    let foo2 = Foo { thing, .$0 }
 }
 "#,
         expect![[r#"
-            fn default() (as Default) fn() -> Self
+            fd ..Default::default()
+            sn ..
         "#]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index bd038cdaa06..9eaabeec7a4 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -4,7 +4,7 @@
 //! get a super-set of matches. Then, we we confirm each match using precise
 //! name resolution.
 
-use std::{convert::TryInto, mem, sync::Arc};
+use std::{mem, sync::Arc};
 
 use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
 use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
index 8132c73ef26..21314ad74ef 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
@@ -3,12 +3,15 @@
 //!
 //! It can be viewed as a dual for `Change`.
 
-use std::{collections::hash_map::Entry, iter};
+use std::{collections::hash_map::Entry, iter, mem};
 
 use base_db::{AnchoredPathBuf, FileId};
 use rustc_hash::FxHashMap;
 use stdx::never;
-use text_edit::TextEdit;
+use syntax::{algo, AstNode, SyntaxNode, SyntaxNodePtr, TextRange, TextSize};
+use text_edit::{TextEdit, TextEditBuilder};
+
+use crate::SnippetCap;
 
 #[derive(Default, Debug, Clone)]
 pub struct SourceChange {
@@ -81,6 +84,135 @@ impl From<FxHashMap<FileId, TextEdit>> for SourceChange {
     }
 }
 
+pub struct SourceChangeBuilder {
+    pub edit: TextEditBuilder,
+    pub file_id: FileId,
+    pub source_change: SourceChange,
+    pub trigger_signature_help: bool,
+
+    /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
+    pub mutated_tree: Option<TreeMutator>,
+}
+
+pub struct TreeMutator {
+    immutable: SyntaxNode,
+    mutable_clone: SyntaxNode,
+}
+
+impl TreeMutator {
+    pub fn new(immutable: &SyntaxNode) -> TreeMutator {
+        let immutable = immutable.ancestors().last().unwrap();
+        let mutable_clone = immutable.clone_for_update();
+        TreeMutator { immutable, mutable_clone }
+    }
+
+    pub fn make_mut<N: AstNode>(&self, node: &N) -> N {
+        N::cast(self.make_syntax_mut(node.syntax())).unwrap()
+    }
+
+    pub fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
+        let ptr = SyntaxNodePtr::new(node);
+        ptr.to_node(&self.mutable_clone)
+    }
+}
+
+impl SourceChangeBuilder {
+    pub fn new(file_id: FileId) -> SourceChangeBuilder {
+        SourceChangeBuilder {
+            edit: TextEdit::builder(),
+            file_id,
+            source_change: SourceChange::default(),
+            trigger_signature_help: false,
+            mutated_tree: None,
+        }
+    }
+
+    pub fn edit_file(&mut self, file_id: FileId) {
+        self.commit();
+        self.file_id = file_id;
+    }
+
+    fn commit(&mut self) {
+        if let Some(tm) = self.mutated_tree.take() {
+            algo::diff(&tm.immutable, &tm.mutable_clone).into_text_edit(&mut self.edit)
+        }
+
+        let edit = mem::take(&mut self.edit).finish();
+        if !edit.is_empty() {
+            self.source_change.insert_source_edit(self.file_id, edit);
+        }
+    }
+
+    pub fn make_mut<N: AstNode>(&mut self, node: N) -> N {
+        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(node.syntax())).make_mut(&node)
+    }
+    /// Returns a copy of the `node`, suitable for mutation.
+    ///
+    /// Syntax trees in rust-analyzer are typically immutable, and mutating
+    /// operations panic at runtime. However, it is possible to make a copy of
+    /// the tree and mutate the copy freely. Mutation is based on interior
+    /// mutability, and different nodes in the same tree see the same mutations.
+    ///
+    /// The typical pattern for an assist is to find specific nodes in the read
+    /// phase, and then get their mutable couterparts using `make_mut` in the
+    /// mutable state.
+    pub fn make_syntax_mut(&mut self, node: SyntaxNode) -> SyntaxNode {
+        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(&node)).make_syntax_mut(&node)
+    }
+
+    /// Remove specified `range` of text.
+    pub fn delete(&mut self, range: TextRange) {
+        self.edit.delete(range)
+    }
+    /// Append specified `text` at the given `offset`
+    pub fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
+        self.edit.insert(offset, text.into())
+    }
+    /// Append specified `snippet` at the given `offset`
+    pub fn insert_snippet(
+        &mut self,
+        _cap: SnippetCap,
+        offset: TextSize,
+        snippet: impl Into<String>,
+    ) {
+        self.source_change.is_snippet = true;
+        self.insert(offset, snippet);
+    }
+    /// Replaces specified `range` of text with a given string.
+    pub fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
+        self.edit.replace(range, replace_with.into())
+    }
+    /// Replaces specified `range` of text with a given `snippet`.
+    pub fn replace_snippet(
+        &mut self,
+        _cap: SnippetCap,
+        range: TextRange,
+        snippet: impl Into<String>,
+    ) {
+        self.source_change.is_snippet = true;
+        self.replace(range, snippet);
+    }
+    pub fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
+        algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
+    }
+    pub fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
+        let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
+        self.source_change.push_file_system_edit(file_system_edit);
+    }
+    pub fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
+        let file_system_edit = FileSystemEdit::MoveFile { src, dst };
+        self.source_change.push_file_system_edit(file_system_edit);
+    }
+    pub fn trigger_signature_help(&mut self) {
+        self.trigger_signature_help = true;
+    }
+
+    pub fn finish(mut self) -> SourceChange {
+        self.commit();
+        mem::take(&mut self.source_change)
+    }
+}
+
 #[derive(Debug, Clone)]
 pub enum FileSystemEdit {
     CreateFile { dst: AnchoredPathBuf, initial_contents: String },
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
index e221425edd5..9b9e21a4ddb 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
@@ -15,6 +15,7 @@ itertools = "0.10.3"
 
 
 either = "1.7.0"
+serde_json = "1.0.82"
 
 profile = { path = "../profile", version = "0.0.0" }
 stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs
index 97ea5c456a6..5694f33525e 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs
@@ -43,7 +43,7 @@ mod tests {
     use crate::{tests::check_diagnostics_with_config, DiagnosticsConfig};
 
     pub(crate) fn check(ra_fixture: &str) {
-        let config = DiagnosticsConfig::default();
+        let config = DiagnosticsConfig::test_sample();
         check_diagnostics_with_config(config, ra_fixture)
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
new file mode 100644
index 00000000000..a21db5b2cec
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -0,0 +1,310 @@
+//! This diagnostic provides an assist for creating a struct definition from a JSON
+//! example.
+
+use hir::{PathResolution, Semantics};
+use ide_db::{
+    base_db::FileId,
+    helpers::mod_path_to_ast,
+    imports::insert_use::{insert_use, ImportScope},
+    source_change::SourceChangeBuilder,
+    RootDatabase,
+};
+use itertools::Itertools;
+use stdx::{format_to, never};
+use syntax::{
+    ast::{self, make},
+    SyntaxKind, SyntaxNode,
+};
+use text_edit::TextEdit;
+
+use crate::{fix, Diagnostic, DiagnosticsConfig, Severity};
+
+#[derive(Default)]
+struct State {
+    result: String,
+    struct_counts: usize,
+    has_serialize: bool,
+    has_deserialize: bool,
+}
+
+impl State {
+    fn generate_new_name(&mut self) -> ast::Name {
+        self.struct_counts += 1;
+        make::name(&format!("Struct{}", self.struct_counts))
+    }
+
+    fn serde_derive(&self) -> String {
+        let mut v = vec![];
+        if self.has_serialize {
+            v.push("Serialize");
+        }
+        if self.has_deserialize {
+            v.push("Deserialize");
+        }
+        match v.as_slice() {
+            [] => "".to_string(),
+            [x] => format!("#[derive({x})]\n"),
+            [x, y] => format!("#[derive({x}, {y})]\n"),
+            _ => {
+                never!();
+                "".to_string()
+            }
+        }
+    }
+
+    fn build_struct(&mut self, value: &serde_json::Map<String, serde_json::Value>) -> ast::Type {
+        let name = self.generate_new_name();
+        let ty = make::ty(&name.to_string());
+        let strukt = make::struct_(
+            None,
+            name,
+            None,
+            make::record_field_list(value.iter().sorted_unstable_by_key(|x| x.0).map(
+                |(name, value)| make::record_field(None, make::name(name), self.type_of(value)),
+            ))
+            .into(),
+        );
+        format_to!(self.result, "{}{}\n", self.serde_derive(), strukt);
+        ty
+    }
+
+    fn type_of(&mut self, value: &serde_json::Value) -> ast::Type {
+        match value {
+            serde_json::Value::Null => make::ty_unit(),
+            serde_json::Value::Bool(_) => make::ty("bool"),
+            serde_json::Value::Number(it) => make::ty(if it.is_i64() { "i64" } else { "f64" }),
+            serde_json::Value::String(_) => make::ty("String"),
+            serde_json::Value::Array(it) => {
+                let ty = match it.iter().next() {
+                    Some(x) => self.type_of(x),
+                    None => make::ty_placeholder(),
+                };
+                make::ty(&format!("Vec<{ty}>"))
+            }
+            serde_json::Value::Object(x) => self.build_struct(x),
+        }
+    }
+}
+
+pub(crate) fn json_in_items(
+    sema: &Semantics<'_, RootDatabase>,
+    acc: &mut Vec<Diagnostic>,
+    file_id: FileId,
+    node: &SyntaxNode,
+    config: &DiagnosticsConfig,
+) {
+    (|| {
+        if node.kind() == SyntaxKind::ERROR
+            && node.first_token().map(|x| x.kind()) == Some(SyntaxKind::L_CURLY)
+            && node.last_token().map(|x| x.kind()) == Some(SyntaxKind::R_CURLY)
+        {
+            let node_string = node.to_string();
+            if let Ok(it) = serde_json::from_str(&node_string) {
+                if let serde_json::Value::Object(it) = it {
+                    let import_scope = ImportScope::find_insert_use_container(node, sema)?;
+                    let range = node.text_range();
+                    let mut edit = TextEdit::builder();
+                    edit.delete(range);
+                    let mut state = State::default();
+                    let semantics_scope = sema.scope(node)?;
+                    let scope_resolve =
+                        |it| semantics_scope.speculative_resolve(&make::path_from_text(it));
+                    let scope_has = |it| scope_resolve(it).is_some();
+                    let deserialize_resolved = scope_resolve("::serde::Deserialize");
+                    let serialize_resolved = scope_resolve("::serde::Serialize");
+                    state.has_deserialize = deserialize_resolved.is_some();
+                    state.has_serialize = serialize_resolved.is_some();
+                    state.build_struct(&it);
+                    edit.insert(range.start(), state.result);
+                    acc.push(
+                        Diagnostic::new(
+                            "json-is-not-rust",
+                            "JSON syntax is not valid as a Rust item",
+                            range,
+                        )
+                        .severity(Severity::WeakWarning)
+                        .with_fixes(Some(vec![{
+                            let mut scb = SourceChangeBuilder::new(file_id);
+                            let scope = match import_scope.clone() {
+                                ImportScope::File(it) => ImportScope::File(scb.make_mut(it)),
+                                ImportScope::Module(it) => ImportScope::Module(scb.make_mut(it)),
+                                ImportScope::Block(it) => ImportScope::Block(scb.make_mut(it)),
+                            };
+                            let current_module = semantics_scope.module();
+                            if !scope_has("Serialize") {
+                                if let Some(PathResolution::Def(it)) = serialize_resolved {
+                                    if let Some(it) = current_module.find_use_path_prefixed(
+                                        sema.db,
+                                        it,
+                                        config.insert_use.prefix_kind,
+                                    ) {
+                                        insert_use(
+                                            &scope,
+                                            mod_path_to_ast(&it),
+                                            &config.insert_use,
+                                        );
+                                    }
+                                }
+                            }
+                            if !scope_has("Deserialize") {
+                                if let Some(PathResolution::Def(it)) = deserialize_resolved {
+                                    if let Some(it) = current_module.find_use_path_prefixed(
+                                        sema.db,
+                                        it,
+                                        config.insert_use.prefix_kind,
+                                    ) {
+                                        insert_use(
+                                            &scope,
+                                            mod_path_to_ast(&it),
+                                            &config.insert_use,
+                                        );
+                                    }
+                                }
+                            }
+                            let mut sc = scb.finish();
+                            sc.insert_source_edit(file_id, edit.finish());
+                            fix("convert_json_to_struct", "Convert JSON to struct", sc, range)
+                        }])),
+                    );
+                }
+            }
+        }
+        Some(())
+    })();
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        tests::{check_diagnostics_with_config, check_fix, check_no_fix},
+        DiagnosticsConfig,
+    };
+
+    #[test]
+    fn diagnostic_for_simple_case() {
+        let mut config = DiagnosticsConfig::test_sample();
+        config.disabled.insert("syntax-error".to_string());
+        check_diagnostics_with_config(
+            config,
+            r#"
+            { "foo": "bar" }
+         // ^^^^^^^^^^^^^^^^ 💡 weak: JSON syntax is not valid as a Rust item
+"#,
+        );
+    }
+
+    #[test]
+    fn types_of_primitives() {
+        check_fix(
+            r#"
+            //- /lib.rs crate:lib deps:serde
+            use serde::Serialize;
+
+            fn some_garbage() {
+
+            }
+
+            {$0
+                "foo": "bar",
+                "bar": 2.3,
+                "baz": null,
+                "bay": 57,
+                "box": true
+            }
+            //- /serde.rs crate:serde
+
+            pub trait Serialize {
+                fn serialize() -> u8;
+            }
+            "#,
+            r#"
+            use serde::Serialize;
+
+            fn some_garbage() {
+
+            }
+
+            #[derive(Serialize)]
+            struct Struct1{ bar: f64, bay: i64, baz: (), r#box: bool, foo: String }
+
+            "#,
+        );
+    }
+
+    #[test]
+    fn nested_structs() {
+        check_fix(
+            r#"
+            {$0
+                "foo": "bar",
+                "bar": {
+                    "kind": "Object",
+                    "value": {}
+                }
+            }
+            "#,
+            r#"
+            struct Struct3{  }
+            struct Struct2{ kind: String, value: Struct3 }
+            struct Struct1{ bar: Struct2, foo: String }
+
+            "#,
+        );
+    }
+
+    #[test]
+    fn arrays() {
+        check_fix(
+            r#"
+            //- /lib.rs crate:lib deps:serde
+            {
+                "of_string": ["foo", "2", "x"], $0
+                "of_object": [{
+                    "x": 10,
+                    "y": 20
+                }, {
+                    "x": 10,
+                    "y": 20
+                }],
+                "nested": [[[2]]],
+                "empty": []
+            }
+            //- /serde.rs crate:serde
+
+            pub trait Serialize {
+                fn serialize() -> u8;
+            }
+            pub trait Deserialize {
+                fn deserialize() -> u8;
+            }
+            "#,
+            r#"
+            use serde::Serialize;
+            use serde::Deserialize;
+
+            #[derive(Serialize, Deserialize)]
+            struct Struct2{ x: i64, y: i64 }
+            #[derive(Serialize, Deserialize)]
+            struct Struct1{ empty: Vec<_>, nested: Vec<Vec<Vec<i64>>>, of_object: Vec<Struct2>, of_string: Vec<String> }
+
+            "#,
+        );
+    }
+
+    #[test]
+    fn no_emit_outside_of_item_position() {
+        check_no_fix(
+            r#"
+            fn foo() {
+                let json = {$0
+                    "foo": "bar",
+                    "bar": {
+                        "kind": "Object",
+                        "value": {}
+                    }
+                };
+            }
+            "#,
+        );
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
index d6a66dc1509..43ff4ed5a6c 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs
@@ -79,7 +79,7 @@ pub macro panic {
 
     #[test]
     fn include_macro_should_allow_empty_content() {
-        let mut config = DiagnosticsConfig::default();
+        let mut config = DiagnosticsConfig::test_sample();
 
         // FIXME: This is a false-positive, the file is actually linked in via
         // `include!` macro
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
index e032c578f02..a80299106bd 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs
@@ -68,7 +68,7 @@ fn missing_record_expr_field_fixes(
     }
     let new_field = make::record_field(
         None,
-        make::name(&record_expr_field.field_name()?.text()),
+        make::name(&record_expr_field.field_name()?.ident_token()?.text()),
         make::ty(&new_field_type.display_source_code(sema.db, module.into()).ok()?),
     );
 
@@ -109,7 +109,7 @@ fn missing_record_expr_field_fixes(
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{check_diagnostics, check_fix};
+    use crate::tests::{check_diagnostics, check_fix, check_no_fix};
 
     #[test]
     fn no_such_field_diagnostics() {
@@ -280,4 +280,18 @@ struct Foo {
 "#,
         )
     }
+
+    #[test]
+    fn test_tuple_field_on_record_struct() {
+        check_no_fix(
+            r#"
+struct Struct {}
+fn main() {
+    Struct {
+        0$0: 0
+    }
+}
+"#,
+        )
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index 41abaa836f5..61e63ea7a93 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -50,6 +50,7 @@ mod handlers {
     pub(crate) mod field_shorthand;
     pub(crate) mod useless_braces;
     pub(crate) mod unlinked_file;
+    pub(crate) mod json_is_not_rust;
 }
 
 #[cfg(test)]
@@ -59,6 +60,7 @@ use hir::{diagnostics::AnyDiagnostic, InFile, Semantics};
 use ide_db::{
     assists::{Assist, AssistId, AssistKind, AssistResolveStrategy},
     base_db::{FileId, FileRange, SourceDatabase},
+    imports::insert_use::InsertUseConfig,
     label::Label,
     source_change::SourceChange,
     FxHashSet, RootDatabase,
@@ -139,13 +141,37 @@ impl Default for ExprFillDefaultMode {
     }
 }
 
-#[derive(Default, Debug, Clone)]
+#[derive(Debug, Clone)]
 pub struct DiagnosticsConfig {
     pub proc_macros_enabled: bool,
     pub proc_attr_macros_enabled: bool,
     pub disable_experimental: bool,
     pub disabled: FxHashSet<String>,
     pub expr_fill_default: ExprFillDefaultMode,
+    // FIXME: We may want to include a whole `AssistConfig` here
+    pub insert_use: InsertUseConfig,
+}
+
+impl DiagnosticsConfig {
+    pub fn test_sample() -> Self {
+        use hir::PrefixKind;
+        use ide_db::imports::insert_use::ImportGranularity;
+
+        Self {
+            proc_macros_enabled: Default::default(),
+            proc_attr_macros_enabled: Default::default(),
+            disable_experimental: Default::default(),
+            disabled: Default::default(),
+            expr_fill_default: Default::default(),
+            insert_use: InsertUseConfig {
+                granularity: ImportGranularity::Preserve,
+                enforce_granularity: false,
+                prefix_kind: PrefixKind::Plain,
+                group: false,
+                skip_glob_imports: false,
+            },
+        }
+    }
 }
 
 struct DiagnosticsContext<'a> {
@@ -172,9 +198,12 @@ pub fn diagnostics(
         }),
     );
 
-    for node in parse.tree().syntax().descendants() {
+    let parse = sema.parse(file_id);
+
+    for node in parse.syntax().descendants() {
         handlers::useless_braces::useless_braces(&mut res, file_id, &node);
         handlers::field_shorthand::field_shorthand(&mut res, file_id, &node);
+        handlers::json_is_not_rust::json_in_items(&sema, &mut res, file_id, &node, &config);
     }
 
     let module = sema.to_module_def(file_id);
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
index 7312bca32fe..729619cfde0 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/tests.rs
@@ -37,7 +37,7 @@ fn check_nth_fix(nth: usize, ra_fixture_before: &str, ra_fixture_after: &str) {
     let after = trim_indent(ra_fixture_after);
 
     let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
-    let mut conf = DiagnosticsConfig::default();
+    let mut conf = DiagnosticsConfig::test_sample();
     conf.expr_fill_default = ExprFillDefaultMode::Default;
     let diagnostic =
         super::diagnostics(&db, &conf, &AssistResolveStrategy::All, file_position.file_id)
@@ -69,7 +69,7 @@ pub(crate) fn check_no_fix(ra_fixture: &str) {
     let (db, file_position) = RootDatabase::with_position(ra_fixture);
     let diagnostic = super::diagnostics(
         &db,
-        &DiagnosticsConfig::default(),
+        &DiagnosticsConfig::test_sample(),
         &AssistResolveStrategy::All,
         file_position.file_id,
     )
@@ -82,7 +82,7 @@ pub(crate) fn check_expect(ra_fixture: &str, expect: Expect) {
     let (db, file_id) = RootDatabase::with_single_file(ra_fixture);
     let diagnostics = super::diagnostics(
         &db,
-        &DiagnosticsConfig::default(),
+        &DiagnosticsConfig::test_sample(),
         &AssistResolveStrategy::All,
         file_id,
     );
@@ -91,7 +91,7 @@ pub(crate) fn check_expect(ra_fixture: &str, expect: Expect) {
 
 #[track_caller]
 pub(crate) fn check_diagnostics(ra_fixture: &str) {
-    let mut config = DiagnosticsConfig::default();
+    let mut config = DiagnosticsConfig::test_sample();
     config.disabled.insert("inactive-code".to_string());
     check_diagnostics_with_config(config, ra_fixture)
 }
@@ -127,7 +127,7 @@ pub(crate) fn check_diagnostics_with_config(config: DiagnosticsConfig, ra_fixtur
 
 #[test]
 fn test_disabled_diagnostics() {
-    let mut config = DiagnosticsConfig::default();
+    let mut config = DiagnosticsConfig::test_sample();
     config.disabled.insert("unresolved-module".into());
 
     let (db, file_id) = RootDatabase::with_single_file(r#"mod foo;"#);
@@ -137,7 +137,7 @@ fn test_disabled_diagnostics() {
 
     let diagnostics = super::diagnostics(
         &db,
-        &DiagnosticsConfig::default(),
+        &DiagnosticsConfig::test_sample(),
         &AssistResolveStrategy::All,
         file_id,
     );
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index b2123b9a879..d6cd5783f05 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -1,4 +1,4 @@
-use std::{convert::TryInto, mem::discriminant};
+use std::mem::discriminant;
 
 use crate::{doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo, TryToNav};
 use hir::{AsAssocItem, AssocItem, Semantics};
diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
index b0853b10fde..0181c6b8e45 100644
--- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs
@@ -2225,4 +2225,190 @@ macro_rules! foo {
             "#]],
         );
     }
+
+    #[test]
+    fn test_paths_with_raw_ident() {
+        check(
+            r#"
+//- /lib.rs
+$0
+mod r#mod {
+    #[test]
+    fn r#fn() {}
+
+    /// ```
+    /// ```
+    fn r#for() {}
+
+    /// ```
+    /// ```
+    struct r#struct<r#type>(r#type);
+
+    /// ```
+    /// ```
+    impl<r#type> r#struct<r#type> {
+        /// ```
+        /// ```
+        fn r#fn() {}
+    }
+
+    enum r#enum {}
+    impl r#struct<r#enum> {
+        /// ```
+        /// ```
+        fn r#fn() {}
+    }
+
+    trait r#trait {}
+
+    /// ```
+    /// ```
+    impl<T> r#trait for r#struct<T> {}
+}
+"#,
+            &[TestMod, Test, DocTest, DocTest, DocTest, DocTest, DocTest, DocTest],
+            expect![[r#"
+                [
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 1..461,
+                            focus_range: 5..10,
+                            name: "r#mod",
+                            kind: Module,
+                            description: "mod r#mod",
+                        },
+                        kind: TestMod {
+                            path: "r#mod",
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 17..41,
+                            focus_range: 32..36,
+                            name: "r#fn",
+                            kind: Function,
+                        },
+                        kind: Test {
+                            test_id: Path(
+                                "r#mod::r#fn",
+                            ),
+                            attr: TestAttr {
+                                ignore: false,
+                            },
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 47..84,
+                            name: "r#for",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#for",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 90..146,
+                            name: "r#struct",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#struct",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 152..266,
+                            focus_range: 189..205,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#struct<r#type>",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 216..260,
+                            name: "r#fn",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#struct<r#type>::r#fn",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 323..367,
+                            name: "r#fn",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#struct<r#enum>::r#fn",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 401..459,
+                            focus_range: 445..456,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#struct<T>",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                ]
+            "#]],
+        )
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs
index 32e39f82a0e..f4d0387440d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/status.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/status.rs
@@ -1,4 +1,4 @@
-use std::{fmt, iter::FromIterator, sync::Arc};
+use std::{fmt, sync::Arc};
 
 use hir::{ExpandResult, MacroFile};
 use ide_db::base_db::{
diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
index aca6ecd424e..e4c56565b92 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
@@ -228,16 +228,7 @@ fn convert_tokens<C: TokenConvertor>(conv: &mut C) -> tt::Subtree {
             }
 
             let spacing = match conv.peek().map(|next| next.kind(conv)) {
-                Some(kind)
-                    if !kind.is_trivia()
-                        && kind.is_punct()
-                        && kind != T!['[']
-                        && kind != T!['{']
-                        && kind != T!['(']
-                        && kind != UNDERSCORE =>
-                {
-                    tt::Spacing::Joint
-                }
+                Some(kind) if !kind.is_trivia() => tt::Spacing::Joint,
                 _ => tt::Spacing::Alone,
             };
             let char = match token.to_char(conv) {
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
index e7402104eb8..dcaceade652 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs
@@ -564,8 +564,10 @@ fn path_expr(p: &mut Parser<'_>, r: Restrictions) -> (CompletedMarker, BlockLike
 // test record_lit
 // fn foo() {
 //     S {};
+//     S { x };
 //     S { x, y: 32, };
 //     S { x, y: 32, ..Default::default() };
+//     S { x: ::default() };
 //     TupleStruct { 0: 1 };
 // }
 pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
@@ -582,16 +584,26 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
 
         match p.current() {
             IDENT | INT_NUMBER => {
-                // test_err record_literal_before_ellipsis_recovery
+                // test_err record_literal_missing_ellipsis_recovery
                 // fn main() {
-                //     S { field ..S::default() }
+                //     S { S::default() }
                 // }
-                if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
-                    name_ref_or_index(p);
-                    p.expect(T![:]);
+                if p.nth_at(1, T![::]) {
+                    m.abandon(p);
+                    p.expect(T![..]);
+                    expr(p);
+                } else {
+                    // test_err record_literal_before_ellipsis_recovery
+                    // fn main() {
+                    //     S { field ..S::default() }
+                    // }
+                    if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
+                        name_ref_or_index(p);
+                        p.expect(T![:]);
+                    }
+                    expr(p);
+                    m.complete(p, RECORD_EXPR_FIELD);
                 }
-                expr(p);
-                m.complete(p, RECORD_EXPR_FIELD);
             }
             T![.] if p.at(T![..]) => {
                 m.abandon(p);
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
index 4cbf1030614..7e21a808da0 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/patterns.rs
@@ -75,6 +75,16 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
         //         Some(1..) => ()
         //     }
         //
+        //     match () {
+        //         S { a: 0 } => (),
+        //         S { a: 1.. } => (),
+        //     }
+        //
+        //     match () {
+        //         [0] => (),
+        //         [1..] => (),
+        //     }
+        //
         //     match (10 as u8, 5 as u8) {
         //         (0, _) => (),
         //         (1.., _) => ()
@@ -88,11 +98,27 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
                 let m = lhs.precede(p);
                 p.bump(range_op);
 
-                // `0 .. =>` or `let 0 .. =` or `Some(0 .. )`
-                //       ^                ^                ^
-                if p.at(T![=]) | p.at(T![')']) | p.at(T![,]) {
+                // testing if we're at one of the following positions:
+                // `0 .. =>`
+                //       ^
+                // `let 0 .. =`
+                //           ^
+                // `let 0..: _ =`
+                //         ^
+                // (1.., _)
+                //     ^
+                // `Some(0 .. )`
+                //            ^
+                // `S { t: 0.. }`
+                //             ^
+                // `[0..]`
+                //      ^
+                if matches!(p.current(), T![=] | T![,] | T![:] | T![')'] | T!['}'] | T![']']) {
                     // test half_open_range_pat
-                    // fn f() { let 0 .. = 1u32; }
+                    // fn f() {
+                    //     let 0 .. = 1u32;
+                    //     let 0..: _ = 1u32;
+                    // }
                 } else {
                     atom_pat(p, recovery_set);
                 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
new file mode 100644
index 00000000000..0c5b618e6f0
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
@@ -0,0 +1,43 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        RECORD_EXPR
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "S"
+          WHITESPACE " "
+          RECORD_EXPR_FIELD_LIST
+            L_CURLY "{"
+            WHITESPACE " "
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "S"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "default"
+              ARG_LIST
+                L_PAREN "("
+                R_PAREN ")"
+            WHITESPACE " "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 19: expected DOT2
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs
new file mode 100644
index 00000000000..1b594e8ab96
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs
@@ -0,0 +1,3 @@
+fn main() {
+    S { S::default() }
+}
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
index 44c967e8dc5..cfef5d3f953 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
@@ -172,6 +172,122 @@ SOURCE_FILE
               WHITESPACE "\n    "
               R_CURLY "}"
         WHITESPACE "\n\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                RECORD_PAT
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "S"
+                  WHITESPACE " "
+                  RECORD_PAT_FIELD_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    RECORD_PAT_FIELD
+                      NAME_REF
+                        IDENT "a"
+                      COLON ":"
+                      WHITESPACE " "
+                      LITERAL_PAT
+                        LITERAL
+                          INT_NUMBER "0"
+                    WHITESPACE " "
+                    R_CURLY "}"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                RECORD_PAT
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "S"
+                  WHITESPACE " "
+                  RECORD_PAT_FIELD_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    RECORD_PAT_FIELD
+                      NAME_REF
+                        IDENT "a"
+                      COLON ":"
+                      WHITESPACE " "
+                      RANGE_PAT
+                        LITERAL_PAT
+                          LITERAL
+                            INT_NUMBER "1"
+                        DOT2 ".."
+                    WHITESPACE " "
+                    R_CURLY "}"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                SLICE_PAT
+                  L_BRACK "["
+                  LITERAL_PAT
+                    LITERAL
+                      INT_NUMBER "0"
+                  R_BRACK "]"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                SLICE_PAT
+                  L_BRACK "["
+                  RANGE_PAT
+                    LITERAL_PAT
+                      LITERAL
+                        INT_NUMBER "1"
+                    DOT2 ".."
+                  R_BRACK "]"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
         MATCH_EXPR
           MATCH_KW "match"
           WHITESPACE " "
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
index 6c586a89560..2411d51096b 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
@@ -11,6 +11,16 @@ fn main() {
         Some(1..) => ()
     }
 
+    match () {
+        S { a: 0 } => (),
+        S { a: 1.. } => (),
+    }
+
+    match () {
+        [0] => (),
+        [1..] => (),
+    }
+
     match (10 as u8, 5 as u8) {
         (0, _) => (),
         (1.., _) => ()
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
index 9997d0ae348..00948c322f4 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
@@ -40,6 +40,26 @@ SOURCE_FILE
                     PATH_SEGMENT
                       NAME_REF
                         IDENT "x"
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "x"
               COMMA ","
               WHITESPACE " "
               RECORD_EXPR_FIELD
@@ -105,6 +125,35 @@ SOURCE_FILE
             PATH
               PATH_SEGMENT
                 NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                NAME_REF
+                  IDENT "x"
+                COLON ":"
+                WHITESPACE " "
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        COLON2 "::"
+                        NAME_REF
+                          IDENT "default"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
                   IDENT "TupleStruct"
             WHITESPACE " "
             RECORD_EXPR_FIELD_LIST
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
index 6285e554977..86411fbb7dc 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
@@ -1,6 +1,8 @@
 fn foo() {
     S {};
+    S { x };
     S { x, y: 32, };
     S { x, y: 32, ..Default::default() };
+    S { x: ::default() };
     TupleStruct { 0: 1 };
 }
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
index 3d3587a7063..4b401b60df0 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
@@ -11,7 +11,7 @@ SOURCE_FILE
     BLOCK_EXPR
       STMT_LIST
         L_CURLY "{"
-        WHITESPACE " "
+        WHITESPACE "\n    "
         LET_STMT
           LET_KW "let"
           WHITESPACE " "
@@ -27,6 +27,25 @@ SOURCE_FILE
           LITERAL
             INT_NUMBER "1u32"
           SEMICOLON ";"
-        WHITESPACE " "
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          RANGE_PAT
+            LITERAL_PAT
+              LITERAL
+                INT_NUMBER "0"
+            DOT2 ".."
+          COLON ":"
+          WHITESPACE " "
+          INFER_TYPE
+            UNDERSCORE "_"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "1u32"
+          SEMICOLON ";"
+        WHITESPACE "\n"
         R_CURLY "}"
   WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
index 1360eda0565..c9386a221a9 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
@@ -1 +1,4 @@
-fn f() { let 0 .. = 1u32; }
+fn f() {
+    let 0 .. = 1u32;
+    let 0..: _ = 1u32;
+}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
index 8437444e183..268a03bb535 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/msg/flat.rs
@@ -35,10 +35,7 @@
 //! as we don't have bincode in Cargo.toml yet, lets stick with serde_json for
 //! the time being.
 
-use std::{
-    collections::{HashMap, VecDeque},
-    convert::TryInto,
-};
+use std::collections::{HashMap, VecDeque};
 
 use serde::{Deserialize, Serialize};
 use tt::TokenId;
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
index 4a07f22779e..a405497f3c9 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
@@ -157,7 +157,7 @@ impl From<TokenTree> for TokenStream {
 }
 
 /// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
+impl FromIterator<TokenTree> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
         trees.into_iter().map(TokenStream::from).collect()
     }
@@ -165,7 +165,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
 
 /// A "flattening" operation on token streams, collects token trees
 /// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
+impl FromIterator<TokenStream> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
         let mut builder = bridge::client::TokenStreamBuilder::new();
         streams.into_iter().for_each(|stream| builder.push(stream.0));
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
index ebdfca00d73..b1e982f4779 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
@@ -12,7 +12,6 @@ use super::proc_macro::bridge::{self, server};
 
 use std::collections::HashMap;
 use std::hash::Hash;
-use std::iter::FromIterator;
 use std::ops::Bound;
 use std::{ascii, vec::IntoIter};
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
index c50a16bf4d1..7ab1f421daf 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
@@ -207,7 +207,7 @@ impl ConcatStreamsHelper {
 }
 
 /// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
+impl FromIterator<TokenTree> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
         trees.into_iter().map(TokenStream::from).collect()
     }
@@ -215,7 +215,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
 
 /// A "flattening" operation on token streams, collects token trees
 /// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
+impl FromIterator<TokenStream> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
         let iter = streams.into_iter();
         let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
index 05a565fbf34..ed49cc75966 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
@@ -12,7 +12,6 @@ use super::proc_macro::bridge::{self, server};
 
 use std::collections::HashMap;
 use std::hash::Hash;
-use std::iter::FromIterator;
 use std::ops::Bound;
 use std::{ascii, vec::IntoIter};
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs
deleted file mode 100644
index 9d56f0eaf88..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-//! Proc macro ABI.
-
-#[allow(dead_code)]
-#[doc(hidden)]
-mod proc_macro;
-
-#[allow(dead_code)]
-#[doc(hidden)]
-mod ra_server;
-
-use libloading::Library;
-use proc_macro_api::ProcMacroKind;
-
-use super::PanicMessage;
-
-pub use ra_server::TokenStream;
-
-pub(crate) struct Abi {
-    exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
-}
-
-impl From<proc_macro::bridge::PanicMessage> for PanicMessage {
-    fn from(p: proc_macro::bridge::PanicMessage) -> Self {
-        Self { message: p.as_str().map(|s| s.to_string()) }
-    }
-}
-
-impl Abi {
-    pub unsafe fn from_lib(lib: &Library, symbol_name: String) -> Result<Abi, libloading::Error> {
-        let macros: libloading::Symbol<'_, &&[proc_macro::bridge::client::ProcMacro]> =
-            lib.get(symbol_name.as_bytes())?;
-        Ok(Self { exported_macros: macros.to_vec() })
-    }
-
-    pub fn expand(
-        &self,
-        macro_name: &str,
-        macro_body: &tt::Subtree,
-        attributes: Option<&tt::Subtree>,
-    ) -> Result<tt::Subtree, PanicMessage> {
-        let parsed_body = TokenStream::with_subtree(macro_body.clone());
-
-        let parsed_attributes =
-            attributes.map_or(TokenStream::new(), |attr| TokenStream::with_subtree(attr.clone()));
-
-        for proc_macro in &self.exported_macros {
-            match proc_macro {
-                proc_macro::bridge::client::ProcMacro::CustomDerive {
-                    trait_name, client, ..
-                } if *trait_name == macro_name => {
-                    let res = client.run(
-                        &proc_macro::bridge::server::SameThread,
-                        ra_server::RustAnalyzer::default(),
-                        parsed_body,
-                        true,
-                    );
-                    return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
-                }
-                proc_macro::bridge::client::ProcMacro::Bang { name, client }
-                    if *name == macro_name =>
-                {
-                    let res = client.run(
-                        &proc_macro::bridge::server::SameThread,
-                        ra_server::RustAnalyzer::default(),
-                        parsed_body,
-                        true,
-                    );
-                    return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
-                }
-                proc_macro::bridge::client::ProcMacro::Attr { name, client }
-                    if *name == macro_name =>
-                {
-                    let res = client.run(
-                        &proc_macro::bridge::server::SameThread,
-                        ra_server::RustAnalyzer::default(),
-                        parsed_attributes,
-                        parsed_body,
-                        true,
-                    );
-                    return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
-                }
-                _ => continue,
-            }
-        }
-
-        Err(proc_macro::bridge::PanicMessage::String("Nothing to expand".to_string()).into())
-    }
-
-    pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
-        self.exported_macros
-            .iter()
-            .map(|proc_macro| match proc_macro {
-                proc_macro::bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
-                    (trait_name.to_string(), ProcMacroKind::CustomDerive)
-                }
-                proc_macro::bridge::client::ProcMacro::Bang { name, .. } => {
-                    (name.to_string(), ProcMacroKind::FuncLike)
-                }
-                proc_macro::bridge::client::ProcMacro::Attr { name, .. } => {
-                    (name.to_string(), ProcMacroKind::Attr)
-                }
-            })
-            .collect()
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs
deleted file mode 100644
index 48030f8d82d..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-//! Buffer management for same-process client<->server communication.
-
-use std::io::{self, Write};
-use std::mem;
-use std::ops::{Deref, DerefMut};
-use std::slice;
-
-#[repr(C)]
-pub struct Buffer {
-    data: *mut u8,
-    len: usize,
-    capacity: usize,
-    reserve: extern "C" fn(Buffer, usize) -> Buffer,
-    drop: extern "C" fn(Buffer),
-}
-
-unsafe impl Sync for Buffer {}
-unsafe impl Send for Buffer {}
-
-impl Default for Buffer {
-    #[inline]
-    fn default() -> Self {
-        Self::from(vec![])
-    }
-}
-
-impl Deref for Buffer {
-    type Target = [u8];
-    #[inline]
-    fn deref(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.data as *const u8, self.len) }
-    }
-}
-
-impl DerefMut for Buffer {
-    #[inline]
-    fn deref_mut(&mut self) -> &mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.data, self.len) }
-    }
-}
-
-impl Buffer {
-    #[inline]
-    pub(super) fn new() -> Self {
-        Self::default()
-    }
-
-    #[inline]
-    pub(super) fn clear(&mut self) {
-        self.len = 0;
-    }
-
-    #[inline]
-    pub(super) fn take(&mut self) -> Self {
-        mem::take(self)
-    }
-
-    // We have the array method separate from extending from a slice. This is
-    // because in the case of small arrays, codegen can be more efficient
-    // (avoiding a memmove call). With extend_from_slice, LLVM at least
-    // currently is not able to make that optimization.
-    #[inline]
-    pub(super) fn extend_from_array<const N: usize>(&mut self, xs: &[u8; N]) {
-        if xs.len() > (self.capacity - self.len) {
-            let b = self.take();
-            *self = (b.reserve)(b, xs.len());
-        }
-        unsafe {
-            xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
-            self.len += xs.len();
-        }
-    }
-
-    #[inline]
-    pub(super) fn extend_from_slice(&mut self, xs: &[u8]) {
-        if xs.len() > (self.capacity - self.len) {
-            let b = self.take();
-            *self = (b.reserve)(b, xs.len());
-        }
-        unsafe {
-            xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
-            self.len += xs.len();
-        }
-    }
-
-    #[inline]
-    pub(super) fn push(&mut self, v: u8) {
-        // The code here is taken from Vec::push, and we know that reserve()
-        // will panic if we're exceeding isize::MAX bytes and so there's no need
-        // to check for overflow.
-        if self.len == self.capacity {
-            let b = self.take();
-            *self = (b.reserve)(b, 1);
-        }
-        unsafe {
-            *self.data.add(self.len) = v;
-            self.len += 1;
-        }
-    }
-}
-
-impl Write for Buffer {
-    #[inline]
-    fn write(&mut self, xs: &[u8]) -> io::Result<usize> {
-        self.extend_from_slice(xs);
-        Ok(xs.len())
-    }
-
-    #[inline]
-    fn write_all(&mut self, xs: &[u8]) -> io::Result<()> {
-        self.extend_from_slice(xs);
-        Ok(())
-    }
-
-    #[inline]
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-impl Drop for Buffer {
-    #[inline]
-    fn drop(&mut self) {
-        let b = self.take();
-        (b.drop)(b);
-    }
-}
-
-impl From<Vec<u8>> for Buffer {
-    fn from(mut v: Vec<u8>) -> Self {
-        let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity());
-        mem::forget(v);
-
-        // This utility function is nested in here because it can *only*
-        // be safely called on `Buffer`s created by *this* `proc_macro`.
-        fn to_vec(b: Buffer) -> Vec<u8> {
-            unsafe {
-                let Buffer { data, len, capacity, .. } = b;
-                mem::forget(b);
-                Vec::from_raw_parts(data, len, capacity)
-            }
-        }
-
-        extern "C" fn reserve(b: Buffer, additional: usize) -> Buffer {
-            let mut v = to_vec(b);
-            v.reserve(additional);
-            Buffer::from(v)
-        }
-
-        extern "C" fn drop(b: Buffer) {
-            mem::drop(to_vec(b));
-        }
-
-        Buffer { data, len, capacity, reserve, drop }
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs
deleted file mode 100644
index 22bda8ba5a7..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs
+++ /dev/null
@@ -1,529 +0,0 @@
-//! Client-side types.
-
-use super::*;
-
-use std::marker::PhantomData;
-
-macro_rules! define_handles {
-    (
-        'owned: $($oty:ident,)*
-        'interned: $($ity:ident,)*
-    ) => {
-        #[repr(C)]
-        #[allow(non_snake_case)]
-        pub struct HandleCounters {
-            $($oty: AtomicUsize,)*
-            $($ity: AtomicUsize,)*
-        }
-
-        impl HandleCounters {
-            // FIXME(eddyb) use a reference to the `static COUNTERS`, instead of
-            // a wrapper `fn` pointer, once `const fn` can reference `static`s.
-            extern "C" fn get() -> &'static Self {
-                static COUNTERS: HandleCounters = HandleCounters {
-                    $($oty: AtomicUsize::new(1),)*
-                    $($ity: AtomicUsize::new(1),)*
-                };
-                &COUNTERS
-            }
-        }
-
-        // FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
-        #[repr(C)]
-        #[allow(non_snake_case)]
-        pub(super) struct HandleStore<S: server::Types> {
-            $($oty: handle::OwnedStore<S::$oty>,)*
-            $($ity: handle::InternedStore<S::$ity>,)*
-        }
-
-        impl<S: server::Types> HandleStore<S> {
-            pub(super) fn new(handle_counters: &'static HandleCounters) -> Self {
-                HandleStore {
-                    $($oty: handle::OwnedStore::new(&handle_counters.$oty),)*
-                    $($ity: handle::InternedStore::new(&handle_counters.$ity),)*
-                }
-            }
-        }
-
-        $(
-            #[repr(C)]
-            pub(crate) struct $oty {
-                handle: handle::Handle,
-                // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
-                // way of doing this, but that requires unstable features.
-                // rust-analyzer uses this code and avoids unstable features.
-                _marker: PhantomData<*mut ()>,
-            }
-
-            // Forward `Drop::drop` to the inherent `drop` method.
-            impl Drop for $oty {
-                fn drop(&mut self) {
-                    $oty {
-                        handle: self.handle,
-                        _marker: PhantomData,
-                    }.drop();
-                }
-            }
-
-            impl<S> Encode<S> for $oty {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    let handle = self.handle;
-                    mem::forget(self);
-                    handle.encode(w, s);
-                }
-            }
-
-            impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$oty, $oty>
-            {
-                fn decode(r: &mut Reader<'_>, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
-                    s.$oty.take(handle::Handle::decode(r, &mut ()))
-                }
-            }
-
-            impl<S> Encode<S> for &$oty {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    self.handle.encode(w, s);
-                }
-            }
-
-            impl<'s, S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>>
-                for &'s Marked<S::$oty, $oty>
-            {
-                fn decode(r: &mut Reader<'_>, s: &'s HandleStore<server::MarkedTypes<S>>) -> Self {
-                    &s.$oty[handle::Handle::decode(r, &mut ())]
-                }
-            }
-
-            impl<S> Encode<S> for &mut $oty {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    self.handle.encode(w, s);
-                }
-            }
-
-            impl<'s, S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>>
-                for &'s mut Marked<S::$oty, $oty>
-            {
-                fn decode(
-                    r: &mut Reader<'_>,
-                    s: &'s mut HandleStore<server::MarkedTypes<S>>
-                ) -> Self {
-                    &mut s.$oty[handle::Handle::decode(r, &mut ())]
-                }
-            }
-
-            impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$oty, $oty>
-            {
-                fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
-                    s.$oty.alloc(self).encode(w, s);
-                }
-            }
-
-            impl<S> DecodeMut<'_, '_, S> for $oty {
-                fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-                    $oty {
-                        handle: handle::Handle::decode(r, s),
-                        _marker: PhantomData,
-                    }
-                }
-            }
-        )*
-
-        $(
-            #[repr(C)]
-            #[derive(Copy, Clone, PartialEq, Eq, Hash)]
-            pub(crate) struct $ity {
-                handle: handle::Handle,
-                // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
-                // way of doing this, but that requires unstable features.
-                // rust-analyzer uses this code and avoids unstable features.
-                _marker: PhantomData<*mut ()>,
-            }
-
-            impl<S> Encode<S> for $ity {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    self.handle.encode(w, s);
-                }
-            }
-
-            impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$ity, $ity>
-            {
-                fn decode(r: &mut Reader<'_>, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
-                    s.$ity.copy(handle::Handle::decode(r, &mut ()))
-                }
-            }
-
-            impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$ity, $ity>
-            {
-                fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
-                    s.$ity.alloc(self).encode(w, s);
-                }
-            }
-
-            impl<S> DecodeMut<'_, '_, S> for $ity {
-                fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-                    $ity {
-                        handle: handle::Handle::decode(r, s),
-                        _marker: PhantomData,
-                    }
-                }
-            }
-        )*
-    }
-}
-define_handles! {
-    'owned:
-    FreeFunctions,
-    TokenStream,
-    Literal,
-    SourceFile,
-    MultiSpan,
-    Diagnostic,
-
-    'interned:
-    Ident,
-    Span,
-}
-
-// FIXME(eddyb) generate these impls by pattern-matching on the
-// names of methods - also could use the presence of `fn drop`
-// to distinguish between 'owned and 'interned, above.
-// Alternatively, special "modes" could be listed of types in with_api
-// instead of pattern matching on methods, here and in server decl.
-
-impl Clone for TokenStream {
-    fn clone(&self) -> Self {
-        self.clone()
-    }
-}
-
-impl Clone for Literal {
-    fn clone(&self) -> Self {
-        self.clone()
-    }
-}
-
-impl fmt::Debug for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Literal")
-            // format the kind without quotes, as in `kind: Float`
-            .field("kind", &format_args!("{}", &self.debug_kind()))
-            .field("symbol", &self.symbol())
-            // format `Some("...")` on one line even in {:#?} mode
-            .field("suffix", &format_args!("{:?}", &self.suffix()))
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-impl Clone for SourceFile {
-    fn clone(&self) -> Self {
-        self.clone()
-    }
-}
-
-impl Span {
-    pub(crate) fn def_site() -> Span {
-        Bridge::with(|bridge| bridge.globals.def_site)
-    }
-
-    pub(crate) fn call_site() -> Span {
-        Bridge::with(|bridge| bridge.globals.call_site)
-    }
-
-    pub(crate) fn mixed_site() -> Span {
-        Bridge::with(|bridge| bridge.globals.mixed_site)
-    }
-}
-
-impl fmt::Debug for Span {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.debug())
-    }
-}
-
-macro_rules! define_client_side {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
-    }),* $(,)?) => {
-        $(impl $name {
-            $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)* {
-                Bridge::with(|bridge| {
-                    let mut buf = bridge.cached_buffer.take();
-
-                    buf.clear();
-                    api_tags::Method::$name(api_tags::$name::$method).encode(&mut buf, &mut ());
-                    reverse_encode!(buf; $($arg),*);
-
-                    buf = bridge.dispatch.call(buf);
-
-                    let r = Result::<_, PanicMessage>::decode(&mut &buf[..], &mut ());
-
-                    bridge.cached_buffer = buf;
-
-                    r.unwrap_or_else(|e| panic::resume_unwind(e.into()))
-                })
-            })*
-        })*
-    }
-}
-with_api!(self, self, define_client_side);
-
-struct Bridge<'a> {
-    /// Reusable buffer (only `clear`-ed, never shrunk), primarily
-    /// used for making requests.
-    cached_buffer: Buffer,
-
-    /// Server-side function that the client uses to make requests.
-    dispatch: closure::Closure<'a, Buffer, Buffer>,
-
-    /// Provided globals for this macro expansion.
-    globals: ExpnGlobals<Span>,
-}
-
-enum BridgeState<'a> {
-    /// No server is currently connected to this client.
-    NotConnected,
-
-    /// A server is connected and available for requests.
-    Connected(Bridge<'a>),
-
-    /// Access to the bridge is being exclusively acquired
-    /// (e.g., during `BridgeState::with`).
-    InUse,
-}
-
-enum BridgeStateL {}
-
-impl<'a> scoped_cell::ApplyL<'a> for BridgeStateL {
-    type Out = BridgeState<'a>;
-}
-
-thread_local! {
-    static BRIDGE_STATE: scoped_cell::ScopedCell<BridgeStateL> =
-        scoped_cell::ScopedCell::new(BridgeState::NotConnected);
-}
-
-impl BridgeState<'_> {
-    /// Take exclusive control of the thread-local
-    /// `BridgeState`, and pass it to `f`, mutably.
-    /// The state will be restored after `f` exits, even
-    /// by panic, including modifications made to it by `f`.
-    ///
-    /// N.B., while `f` is running, the thread-local state
-    /// is `BridgeState::InUse`.
-    fn with<R>(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R {
-        BRIDGE_STATE.with(|state| {
-            state.replace(BridgeState::InUse, |mut state| {
-                // FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone
-                f(&mut *state)
-            })
-        })
-    }
-}
-
-impl Bridge<'_> {
-    fn with<R>(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R {
-        BridgeState::with(|state| match state {
-            BridgeState::NotConnected => {
-                panic!("procedural macro API is used outside of a procedural macro");
-            }
-            BridgeState::InUse => {
-                panic!("procedural macro API is used while it's already in use");
-            }
-            BridgeState::Connected(bridge) => f(bridge),
-        })
-    }
-}
-
-pub(crate) fn is_available() -> bool {
-    BridgeState::with(|state| match state {
-        BridgeState::Connected(_) | BridgeState::InUse => true,
-        BridgeState::NotConnected => false,
-    })
-}
-
-/// A client-side RPC entry-point, which may be using a different `proc_macro`
-/// from the one used by the server, but can be invoked compatibly.
-///
-/// Note that the (phantom) `I` ("input") and `O` ("output") type parameters
-/// decorate the `Client<I, O>` with the RPC "interface" of the entry-point, but
-/// do not themselves participate in ABI, at all, only facilitate type-checking.
-///
-/// E.g. `Client<TokenStream, TokenStream>` is the common proc macro interface,
-/// used for `#[proc_macro] fn foo(input: TokenStream) -> TokenStream`,
-/// indicating that the RPC input and output will be serialized token streams,
-/// and forcing the use of APIs that take/return `S::TokenStream`, server-side.
-#[repr(C)]
-pub struct Client<I, O> {
-    // FIXME(eddyb) use a reference to the `static COUNTERS`, instead of
-    // a wrapper `fn` pointer, once `const fn` can reference `static`s.
-    pub(super) get_handle_counters: extern "C" fn() -> &'static HandleCounters,
-
-    pub(super) run: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-
-    pub(super) _marker: PhantomData<fn(I) -> O>,
-}
-
-impl<I, O> Copy for Client<I, O> {}
-impl<I, O> Clone for Client<I, O> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-fn maybe_install_panic_hook(force_show_panics: bool) {
-    // Hide the default panic output within `proc_macro` expansions.
-    // NB. the server can't do this because it may use a different libstd.
-    static HIDE_PANICS_DURING_EXPANSION: Once = Once::new();
-    HIDE_PANICS_DURING_EXPANSION.call_once(|| {
-        let prev = panic::take_hook();
-        panic::set_hook(Box::new(move |info| {
-            let show = BridgeState::with(|state| match state {
-                BridgeState::NotConnected => true,
-                BridgeState::Connected(_) | BridgeState::InUse => force_show_panics,
-            });
-            if show {
-                prev(info)
-            }
-        }));
-    });
-}
-
-/// Client-side helper for handling client panics, entering the bridge,
-/// deserializing input and serializing output.
-// FIXME(eddyb) maybe replace `Bridge::enter` with this?
-fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
-    config: BridgeConfig<'_>,
-    f: impl FnOnce(A) -> R,
-) -> Buffer {
-    let BridgeConfig { input: mut buf, dispatch, force_show_panics, .. } = config;
-
-    panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        maybe_install_panic_hook(force_show_panics);
-
-        let reader = &mut &buf[..];
-        let (globals, input) = <(ExpnGlobals<Span>, A)>::decode(reader, &mut ());
-
-        // Put the buffer we used for input back in the `Bridge` for requests.
-        let new_state =
-            BridgeState::Connected(Bridge { cached_buffer: buf.take(), dispatch, globals });
-
-        BRIDGE_STATE.with(|state| {
-            state.set(new_state, || {
-                let output = f(input);
-
-                // Take the `cached_buffer` back out, for the output value.
-                buf = Bridge::with(|bridge| bridge.cached_buffer.take());
-
-                // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
-                // from encoding a panic (`Err(e: PanicMessage)`) to avoid
-                // having handles outside the `bridge.enter(|| ...)` scope, and
-                // to catch panics that could happen while encoding the success.
-                //
-                // Note that panics should be impossible beyond this point, but
-                // this is defensively trying to avoid any accidental panicking
-                // reaching the `extern "C"` (which should `abort` but might not
-                // at the moment, so this is also potentially preventing UB).
-                buf.clear();
-                Ok::<_, ()>(output).encode(&mut buf, &mut ());
-            })
-        })
-    }))
-    .map_err(PanicMessage::from)
-    .unwrap_or_else(|e| {
-        buf.clear();
-        Err::<(), _>(e).encode(&mut buf, &mut ());
-    });
-    buf
-}
-
-impl Client<super::super::TokenStream, super::super::TokenStream> {
-    pub const fn expand1(
-        f: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
-    ) -> Self {
-        Client {
-            get_handle_counters: HandleCounters::get,
-            run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| {
-                run_client(bridge, |input| f(super::super::TokenStream(input)).0)
-            }),
-            _marker: PhantomData,
-        }
-    }
-}
-
-impl Client<(super::super::TokenStream, super::super::TokenStream), super::super::TokenStream> {
-    pub const fn expand2(
-        f: impl Fn(super::super::TokenStream, super::super::TokenStream) -> super::super::TokenStream
-            + Copy,
-    ) -> Self {
-        Client {
-            get_handle_counters: HandleCounters::get,
-            run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| {
-                run_client(bridge, |(input, input2)| {
-                    f(super::super::TokenStream(input), super::super::TokenStream(input2)).0
-                })
-            }),
-            _marker: PhantomData,
-        }
-    }
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum ProcMacro {
-    CustomDerive {
-        trait_name: &'static str,
-        attributes: &'static [&'static str],
-        client: Client<super::super::TokenStream, super::super::TokenStream>,
-    },
-
-    Attr {
-        name: &'static str,
-        client: Client<
-            (super::super::TokenStream, super::super::TokenStream),
-            super::super::TokenStream,
-        >,
-    },
-
-    Bang {
-        name: &'static str,
-        client: Client<super::super::TokenStream, super::super::TokenStream>,
-    },
-}
-
-impl ProcMacro {
-    pub fn name(&self) -> &'static str {
-        match self {
-            ProcMacro::CustomDerive { trait_name, .. } => trait_name,
-            ProcMacro::Attr { name, .. } => name,
-            ProcMacro::Bang { name, .. } => name,
-        }
-    }
-
-    pub const fn custom_derive(
-        trait_name: &'static str,
-        attributes: &'static [&'static str],
-        expand: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
-    ) -> Self {
-        ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) }
-    }
-
-    pub const fn attr(
-        name: &'static str,
-        expand: impl Fn(super::super::TokenStream, super::super::TokenStream) -> super::super::TokenStream
-            + Copy,
-    ) -> Self {
-        ProcMacro::Attr { name, client: Client::expand2(expand) }
-    }
-
-    pub const fn bang(
-        name: &'static str,
-        expand: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
-    ) -> Self {
-        ProcMacro::Bang { name, client: Client::expand1(expand) }
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs
deleted file mode 100644
index d371ae3cea0..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-//! Closure type (equivalent to `&mut dyn FnMut(A) -> R`) that's `repr(C)`.
-
-use std::marker::PhantomData;
-
-#[repr(C)]
-pub struct Closure<'a, A, R> {
-    call: unsafe extern "C" fn(*mut Env, A) -> R,
-    env: *mut Env,
-    // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
-    // this, but that requires unstable features. rust-analyzer uses this code
-    // and avoids unstable features.
-    //
-    // The `'a` lifetime parameter represents the lifetime of `Env`.
-    _marker: PhantomData<*mut &'a mut ()>,
-}
-
-struct Env;
-
-impl<'a, A, R, F: FnMut(A) -> R> From<&'a mut F> for Closure<'a, A, R> {
-    fn from(f: &'a mut F) -> Self {
-        unsafe extern "C" fn call<A, R, F: FnMut(A) -> R>(env: *mut Env, arg: A) -> R {
-            (*(env as *mut _ as *mut F))(arg)
-        }
-        Closure { call: call::<A, R, F>, env: f as *mut _ as *mut Env, _marker: PhantomData }
-    }
-}
-
-impl<'a, A, R> Closure<'a, A, R> {
-    pub fn call(&mut self, arg: A) -> R {
-        unsafe { (self.call)(self.env, arg) }
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs
deleted file mode 100644
index c219a9465d3..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-//! Server-side handles and storage for per-handle data.
-
-use std::collections::{BTreeMap, HashMap};
-use std::hash::{BuildHasher, Hash};
-use std::num::NonZeroU32;
-use std::ops::{Index, IndexMut};
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-pub(super) type Handle = NonZeroU32;
-
-/// A store that associates values of type `T` with numeric handles. A value can
-/// be looked up using its handle.
-pub(super) struct OwnedStore<T: 'static> {
-    counter: &'static AtomicUsize,
-    data: BTreeMap<Handle, T>,
-}
-
-impl<T> OwnedStore<T> {
-    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
-        // Ensure the handle counter isn't 0, which would panic later,
-        // when `NonZeroU32::new` (aka `Handle::new`) is called in `alloc`.
-        assert_ne!(counter.load(Ordering::SeqCst), 0);
-
-        OwnedStore { counter, data: BTreeMap::new() }
-    }
-}
-
-impl<T> OwnedStore<T> {
-    pub(super) fn alloc(&mut self, x: T) -> Handle {
-        let counter = self.counter.fetch_add(1, Ordering::SeqCst);
-        let handle = Handle::new(counter as u32).expect("`proc_macro` handle counter overflowed");
-        assert!(self.data.insert(handle, x).is_none());
-        handle
-    }
-
-    pub(super) fn take(&mut self, h: Handle) -> T {
-        self.data.remove(&h).expect("use-after-free in `proc_macro` handle")
-    }
-}
-
-impl<T> Index<Handle> for OwnedStore<T> {
-    type Output = T;
-    fn index(&self, h: Handle) -> &T {
-        self.data.get(&h).expect("use-after-free in `proc_macro` handle")
-    }
-}
-
-impl<T> IndexMut<Handle> for OwnedStore<T> {
-    fn index_mut(&mut self, h: Handle) -> &mut T {
-        self.data.get_mut(&h).expect("use-after-free in `proc_macro` handle")
-    }
-}
-
-// HACK(eddyb) deterministic `std::collections::hash_map::RandomState` replacement
-// that doesn't require adding any dependencies to `proc_macro` (like `rustc-hash`).
-#[derive(Clone)]
-struct NonRandomState;
-
-impl BuildHasher for NonRandomState {
-    type Hasher = std::collections::hash_map::DefaultHasher;
-    #[inline]
-    fn build_hasher(&self) -> Self::Hasher {
-        Self::Hasher::new()
-    }
-}
-
-/// Like `OwnedStore`, but avoids storing any value more than once.
-pub(super) struct InternedStore<T: 'static> {
-    owned: OwnedStore<T>,
-    interner: HashMap<T, Handle, NonRandomState>,
-}
-
-impl<T: Copy + Eq + Hash> InternedStore<T> {
-    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
-        InternedStore {
-            owned: OwnedStore::new(counter),
-            interner: HashMap::with_hasher(NonRandomState),
-        }
-    }
-
-    pub(super) fn alloc(&mut self, x: T) -> Handle {
-        let owned = &mut self.owned;
-        *self.interner.entry(x).or_insert_with(|| owned.alloc(x))
-    }
-
-    pub(super) fn copy(&mut self, h: Handle) -> T {
-        self.owned[h]
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs
deleted file mode 100644
index ffd44079323..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs
+++ /dev/null
@@ -1,493 +0,0 @@
-//! Internal interface for communicating between a `proc_macro` client
-//! (a proc macro crate) and a `proc_macro` server (a compiler front-end).
-//!
-//! Serialization (with C ABI buffers) and unique integer handles are employed
-//! to allow safely interfacing between two copies of `proc_macro` built
-//! (from the same source) by different compilers with potentially mismatching
-//! Rust ABIs (e.g., stage0/bin/rustc vs stage1/bin/rustc during bootstrap).
-
-#![deny(unsafe_code)]
-
-pub use super::{Delimiter, Level, LineColumn, Spacing};
-use std::fmt;
-use std::hash::Hash;
-use std::marker;
-use std::mem;
-use std::ops::Bound;
-use std::panic;
-use std::sync::atomic::AtomicUsize;
-use std::sync::Once;
-use std::thread;
-
-/// Higher-order macro describing the server RPC API, allowing automatic
-/// generation of type-safe Rust APIs, both client-side and server-side.
-///
-/// `with_api!(MySelf, my_self, my_macro)` expands to:
-/// ```rust,ignore (pseudo-code)
-/// my_macro! {
-///     // ...
-///     Literal {
-///         // ...
-///         fn character(ch: char) -> MySelf::Literal;
-///         // ...
-///         fn span(my_self: &MySelf::Literal) -> MySelf::Span;
-///         fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span);
-///     },
-///     // ...
-/// }
-/// ```
-///
-/// The first two arguments serve to customize the arguments names
-/// and argument/return types, to enable several different usecases:
-///
-/// If `my_self` is just `self`, then each `fn` signature can be used
-/// as-is for a method. If it's anything else (`self_` in practice),
-/// then the signatures don't have a special `self` argument, and
-/// can, therefore, have a different one introduced.
-///
-/// If `MySelf` is just `Self`, then the types are only valid inside
-/// a trait or a trait impl, where the trait has associated types
-/// for each of the API types. If non-associated types are desired,
-/// a module name (`self` in practice) can be used instead of `Self`.
-macro_rules! with_api {
-    ($S:ident, $self:ident, $m:ident) => {
-        $m! {
-            FreeFunctions {
-                fn drop($self: $S::FreeFunctions);
-                fn track_env_var(var: &str, value: Option<&str>);
-                fn track_path(path: &str);
-            },
-            TokenStream {
-                fn drop($self: $S::TokenStream);
-                fn clone($self: &$S::TokenStream) -> $S::TokenStream;
-                fn is_empty($self: &$S::TokenStream) -> bool;
-                fn expand_expr($self: &$S::TokenStream) -> Result<$S::TokenStream, ()>;
-                fn from_str(src: &str) -> $S::TokenStream;
-                fn to_string($self: &$S::TokenStream) -> String;
-                fn from_token_tree(
-                    tree: TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>,
-                ) -> $S::TokenStream;
-                fn concat_trees(
-                    base: Option<$S::TokenStream>,
-                    trees: Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>,
-                ) -> $S::TokenStream;
-                fn concat_streams(
-                    base: Option<$S::TokenStream>,
-                    streams: Vec<$S::TokenStream>,
-                ) -> $S::TokenStream;
-                fn into_trees(
-                    $self: $S::TokenStream
-                ) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>;
-            },
-            Ident {
-                fn new(string: &str, span: $S::Span, is_raw: bool) -> $S::Ident;
-                fn span($self: $S::Ident) -> $S::Span;
-                fn with_span($self: $S::Ident, span: $S::Span) -> $S::Ident;
-            },
-            Literal {
-                fn drop($self: $S::Literal);
-                fn clone($self: &$S::Literal) -> $S::Literal;
-                fn from_str(s: &str) -> Result<$S::Literal, ()>;
-                fn to_string($self: &$S::Literal) -> String;
-                fn debug_kind($self: &$S::Literal) -> String;
-                fn symbol($self: &$S::Literal) -> String;
-                fn suffix($self: &$S::Literal) -> Option<String>;
-                fn integer(n: &str) -> $S::Literal;
-                fn typed_integer(n: &str, kind: &str) -> $S::Literal;
-                fn float(n: &str) -> $S::Literal;
-                fn f32(n: &str) -> $S::Literal;
-                fn f64(n: &str) -> $S::Literal;
-                fn string(string: &str) -> $S::Literal;
-                fn character(ch: char) -> $S::Literal;
-                fn byte_string(bytes: &[u8]) -> $S::Literal;
-                fn span($self: &$S::Literal) -> $S::Span;
-                fn set_span($self: &mut $S::Literal, span: $S::Span);
-                fn subspan(
-                    $self: &$S::Literal,
-                    start: Bound<usize>,
-                    end: Bound<usize>,
-                ) -> Option<$S::Span>;
-            },
-            SourceFile {
-                fn drop($self: $S::SourceFile);
-                fn clone($self: &$S::SourceFile) -> $S::SourceFile;
-                fn eq($self: &$S::SourceFile, other: &$S::SourceFile) -> bool;
-                fn path($self: &$S::SourceFile) -> String;
-                fn is_real($self: &$S::SourceFile) -> bool;
-            },
-            MultiSpan {
-                fn drop($self: $S::MultiSpan);
-                fn new() -> $S::MultiSpan;
-                fn push($self: &mut $S::MultiSpan, span: $S::Span);
-            },
-            Diagnostic {
-                fn drop($self: $S::Diagnostic);
-                fn new(level: Level, msg: &str, span: $S::MultiSpan) -> $S::Diagnostic;
-                fn sub(
-                    $self: &mut $S::Diagnostic,
-                    level: Level,
-                    msg: &str,
-                    span: $S::MultiSpan,
-                );
-                fn emit($self: $S::Diagnostic);
-            },
-            Span {
-                fn debug($self: $S::Span) -> String;
-                fn source_file($self: $S::Span) -> $S::SourceFile;
-                fn parent($self: $S::Span) -> Option<$S::Span>;
-                fn source($self: $S::Span) -> $S::Span;
-                fn start($self: $S::Span) -> LineColumn;
-                fn end($self: $S::Span) -> LineColumn;
-                fn before($self: $S::Span) -> $S::Span;
-                fn after($self: $S::Span) -> $S::Span;
-                fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
-                fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
-                fn source_text($self: $S::Span) -> Option<String>;
-                fn save_span($self: $S::Span) -> usize;
-                fn recover_proc_macro_span(id: usize) -> $S::Span;
-            },
-        }
-    };
-}
-
-// FIXME(eddyb) this calls `encode` for each argument, but in reverse,
-// to match the ordering in `reverse_decode`.
-macro_rules! reverse_encode {
-    ($writer:ident;) => {};
-    ($writer:ident; $first:ident $(, $rest:ident)*) => {
-        reverse_encode!($writer; $($rest),*);
-        $first.encode(&mut $writer, &mut ());
-    }
-}
-
-// FIXME(eddyb) this calls `decode` for each argument, but in reverse,
-// to avoid borrow conflicts from borrows started by `&mut` arguments.
-macro_rules! reverse_decode {
-    ($reader:ident, $s:ident;) => {};
-    ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => {
-        reverse_decode!($reader, $s; $($rest: $rest_ty),*);
-        let $first = <$first_ty>::decode(&mut $reader, $s);
-    }
-}
-
-#[allow(unsafe_code)]
-mod buffer;
-#[forbid(unsafe_code)]
-pub mod client;
-#[allow(unsafe_code)]
-mod closure;
-#[forbid(unsafe_code)]
-mod handle;
-#[macro_use]
-#[forbid(unsafe_code)]
-mod rpc;
-#[allow(unsafe_code)]
-mod scoped_cell;
-#[allow(unsafe_code)]
-mod selfless_reify;
-#[forbid(unsafe_code)]
-pub mod server;
-
-use buffer::Buffer;
-pub use rpc::PanicMessage;
-use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
-
-/// Configuration for establishing an active connection between a server and a
-/// client.  The server creates the bridge config (`run_server` in `server.rs`),
-/// then passes it to the client through the function pointer in the `run` field
-/// of `client::Client`. The client constructs a local `Bridge` from the config
-/// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
-#[repr(C)]
-pub struct BridgeConfig<'a> {
-    /// Buffer used to pass initial input to the client.
-    input: Buffer,
-
-    /// Server-side function that the client uses to make requests.
-    dispatch: closure::Closure<'a, Buffer, Buffer>,
-
-    /// If 'true', always invoke the default panic hook
-    force_show_panics: bool,
-
-    // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
-    // this, but that requires unstable features. rust-analyzer uses this code
-    // and avoids unstable features.
-    _marker: marker::PhantomData<*mut ()>,
-}
-
-#[forbid(unsafe_code)]
-#[allow(non_camel_case_types)]
-mod api_tags {
-    use super::rpc::{DecodeMut, Encode, Reader, Writer};
-
-    macro_rules! declare_tags {
-        ($($name:ident {
-            $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
-        }),* $(,)?) => {
-            $(
-                pub(super) enum $name {
-                    $($method),*
-                }
-                rpc_encode_decode!(enum $name { $($method),* });
-            )*
-
-            pub(super) enum Method {
-                $($name($name)),*
-            }
-            rpc_encode_decode!(enum Method { $($name(m)),* });
-        }
-    }
-    with_api!(self, self, declare_tags);
-}
-
-/// Helper to wrap associated types to allow trait impl dispatch.
-/// That is, normally a pair of impls for `T::Foo` and `T::Bar`
-/// can overlap, but if the impls are, instead, on types like
-/// `Marked<T::Foo, Foo>` and `Marked<T::Bar, Bar>`, they can't.
-trait Mark {
-    type Unmarked;
-    fn mark(unmarked: Self::Unmarked) -> Self;
-}
-
-/// Unwrap types wrapped by `Mark::mark` (see `Mark` for details).
-trait Unmark {
-    type Unmarked;
-    fn unmark(self) -> Self::Unmarked;
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-struct Marked<T, M> {
-    value: T,
-    _marker: marker::PhantomData<M>,
-}
-
-impl<T, M> Mark for Marked<T, M> {
-    type Unmarked = T;
-    fn mark(unmarked: Self::Unmarked) -> Self {
-        Marked { value: unmarked, _marker: marker::PhantomData }
-    }
-}
-impl<T, M> Unmark for Marked<T, M> {
-    type Unmarked = T;
-    fn unmark(self) -> Self::Unmarked {
-        self.value
-    }
-}
-impl<'a, T, M> Unmark for &'a Marked<T, M> {
-    type Unmarked = &'a T;
-    fn unmark(self) -> Self::Unmarked {
-        &self.value
-    }
-}
-impl<'a, T, M> Unmark for &'a mut Marked<T, M> {
-    type Unmarked = &'a mut T;
-    fn unmark(self) -> Self::Unmarked {
-        &mut self.value
-    }
-}
-
-impl<T: Mark> Mark for Vec<T> {
-    type Unmarked = Vec<T::Unmarked>;
-    fn mark(unmarked: Self::Unmarked) -> Self {
-        // Should be a no-op due to std's in-place collect optimizations.
-        unmarked.into_iter().map(T::mark).collect()
-    }
-}
-impl<T: Unmark> Unmark for Vec<T> {
-    type Unmarked = Vec<T::Unmarked>;
-    fn unmark(self) -> Self::Unmarked {
-        // Should be a no-op due to std's in-place collect optimizations.
-        self.into_iter().map(T::unmark).collect()
-    }
-}
-
-macro_rules! mark_noop {
-    ($($ty:ty),* $(,)?) => {
-        $(
-            impl Mark for $ty {
-                type Unmarked = Self;
-                fn mark(unmarked: Self::Unmarked) -> Self {
-                    unmarked
-                }
-            }
-            impl Unmark for $ty {
-                type Unmarked = Self;
-                fn unmark(self) -> Self::Unmarked {
-                    self
-                }
-            }
-        )*
-    }
-}
-mark_noop! {
-    (),
-    bool,
-    char,
-    &'_ [u8],
-    &'_ str,
-    String,
-    u8,
-    usize,
-    Delimiter,
-    Level,
-    LineColumn,
-    Spacing,
-}
-
-rpc_encode_decode!(
-    enum Delimiter {
-        Parenthesis,
-        Brace,
-        Bracket,
-        None,
-    }
-);
-rpc_encode_decode!(
-    enum Level {
-        Error,
-        Warning,
-        Note,
-        Help,
-    }
-);
-rpc_encode_decode!(struct LineColumn { line, column });
-rpc_encode_decode!(
-    enum Spacing {
-        Alone,
-        Joint,
-    }
-);
-
-macro_rules! mark_compound {
-    (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
-        impl<$($T: Mark),+> Mark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn mark(unmarked: Self::Unmarked) -> Self {
-                $name {
-                    $($field: Mark::mark(unmarked.$field)),*
-                }
-            }
-        }
-        impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn unmark(self) -> Self::Unmarked {
-                $name {
-                    $($field: Unmark::unmark(self.$field)),*
-                }
-            }
-        }
-    };
-    (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
-        impl<$($T: Mark),+> Mark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn mark(unmarked: Self::Unmarked) -> Self {
-                match unmarked {
-                    $($name::$variant $(($field))? => {
-                        $name::$variant $((Mark::mark($field)))?
-                    })*
-                }
-            }
-        }
-        impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn unmark(self) -> Self::Unmarked {
-                match self {
-                    $($name::$variant $(($field))? => {
-                        $name::$variant $((Unmark::unmark($field)))?
-                    })*
-                }
-            }
-        }
-    }
-}
-
-macro_rules! compound_traits {
-    ($($t:tt)*) => {
-        rpc_encode_decode!($($t)*);
-        mark_compound!($($t)*);
-    };
-}
-
-compound_traits!(
-    enum Bound<T> {
-        Included(x),
-        Excluded(x),
-        Unbounded,
-    }
-);
-
-compound_traits!(
-    enum Option<T> {
-        Some(t),
-        None,
-    }
-);
-
-compound_traits!(
-    enum Result<T, E> {
-        Ok(t),
-        Err(e),
-    }
-);
-
-#[derive(Copy, Clone)]
-pub struct DelimSpan<Span> {
-    pub open: Span,
-    pub close: Span,
-    pub entire: Span,
-}
-
-impl<Span: Copy> DelimSpan<Span> {
-    pub fn from_single(span: Span) -> Self {
-        DelimSpan { open: span, close: span, entire: span }
-    }
-}
-
-compound_traits!(struct DelimSpan<Span> { open, close, entire });
-
-#[derive(Clone)]
-pub struct Group<TokenStream, Span> {
-    pub delimiter: Delimiter,
-    pub stream: Option<TokenStream>,
-    pub span: DelimSpan<Span>,
-}
-
-compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
-
-#[derive(Clone)]
-pub struct Punct<Span> {
-    pub ch: u8,
-    pub joint: bool,
-    pub span: Span,
-}
-
-compound_traits!(struct Punct<Span> { ch, joint, span });
-
-#[derive(Clone)]
-pub enum TokenTree<TokenStream, Span, Ident, Literal> {
-    Group(Group<TokenStream, Span>),
-    Punct(Punct<Span>),
-    Ident(Ident),
-    Literal(Literal),
-}
-
-compound_traits!(
-    enum TokenTree<TokenStream, Span, Ident, Literal> {
-        Group(tt),
-        Punct(tt),
-        Ident(tt),
-        Literal(tt),
-    }
-);
-
-/// Globals provided alongside the initial inputs for a macro expansion.
-/// Provides values such as spans which are used frequently to avoid RPC.
-#[derive(Clone)]
-pub struct ExpnGlobals<Span> {
-    pub def_site: Span,
-    pub call_site: Span,
-    pub mixed_site: Span,
-}
-
-compound_traits!(
-    struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
-);
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs
deleted file mode 100644
index e9d7a46c06f..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs
+++ /dev/null
@@ -1,304 +0,0 @@
-//! Serialization for client-server communication.
-
-use std::any::Any;
-use std::char;
-use std::io::Write;
-use std::num::NonZeroU32;
-use std::str;
-
-pub(super) type Writer = super::buffer::Buffer;
-
-pub(super) trait Encode<S>: Sized {
-    fn encode(self, w: &mut Writer, s: &mut S);
-}
-
-pub(super) type Reader<'a> = &'a [u8];
-
-pub(super) trait Decode<'a, 's, S>: Sized {
-    fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
-}
-
-pub(super) trait DecodeMut<'a, 's, S>: Sized {
-    fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
-}
-
-macro_rules! rpc_encode_decode {
-    (le $ty:ty) => {
-        impl<S> Encode<S> for $ty {
-            fn encode(self, w: &mut Writer, _: &mut S) {
-                w.extend_from_array(&self.to_le_bytes());
-            }
-        }
-
-        impl<S> DecodeMut<'_, '_, S> for $ty {
-            fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
-                const N: usize = ::std::mem::size_of::<$ty>();
-
-                let mut bytes = [0; N];
-                bytes.copy_from_slice(&r[..N]);
-                *r = &r[N..];
-
-                Self::from_le_bytes(bytes)
-            }
-        }
-    };
-    (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => {
-        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
-            fn encode(self, w: &mut Writer, s: &mut S) {
-                $(self.$field.encode(w, s);)*
-            }
-        }
-
-        impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
-            for $name $(<$($T),+>)?
-        {
-            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-                $name {
-                    $($field: DecodeMut::decode(r, s)),*
-                }
-            }
-        }
-    };
-    (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
-        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
-            fn encode(self, w: &mut Writer, s: &mut S) {
-                // HACK(eddyb): `Tag` enum duplicated between the
-                // two impls as there's no other place to stash it.
-                #[allow(non_upper_case_globals)]
-                mod tag {
-                    #[repr(u8)] enum Tag { $($variant),* }
-
-                    $(pub const $variant: u8 = Tag::$variant as u8;)*
-                }
-
-                match self {
-                    $($name::$variant $(($field))* => {
-                        tag::$variant.encode(w, s);
-                        $($field.encode(w, s);)*
-                    })*
-                }
-            }
-        }
-
-        impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
-            for $name $(<$($T),+>)?
-        {
-            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-                // HACK(eddyb): `Tag` enum duplicated between the
-                // two impls as there's no other place to stash it.
-                #[allow(non_upper_case_globals)]
-                mod tag {
-                    #[repr(u8)] enum Tag { $($variant),* }
-
-                    $(pub const $variant: u8 = Tag::$variant as u8;)*
-                }
-
-                match u8::decode(r, s) {
-                    $(tag::$variant => {
-                        $(let $field = DecodeMut::decode(r, s);)*
-                        $name::$variant $(($field))*
-                    })*
-                    _ => unreachable!(),
-                }
-            }
-        }
-    }
-}
-
-impl<S> Encode<S> for () {
-    fn encode(self, _: &mut Writer, _: &mut S) {}
-}
-
-impl<S> DecodeMut<'_, '_, S> for () {
-    fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
-}
-
-impl<S> Encode<S> for u8 {
-    fn encode(self, w: &mut Writer, _: &mut S) {
-        w.push(self);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for u8 {
-    fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
-        let x = r[0];
-        *r = &r[1..];
-        x
-    }
-}
-
-rpc_encode_decode!(le u32);
-rpc_encode_decode!(le usize);
-
-impl<S> Encode<S> for bool {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        (self as u8).encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for bool {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        match u8::decode(r, s) {
-            0 => false,
-            1 => true,
-            _ => unreachable!(),
-        }
-    }
-}
-
-impl<S> Encode<S> for char {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        (self as u32).encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for char {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        char::from_u32(u32::decode(r, s)).unwrap()
-    }
-}
-
-impl<S> Encode<S> for NonZeroU32 {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.get().encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        Self::new(u32::decode(r, s)).unwrap()
-    }
-}
-
-impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.0.encode(w, s);
-        self.1.encode(w, s);
-    }
-}
-
-impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
-    for (A, B)
-{
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
-    }
-}
-
-impl<S> Encode<S> for &[u8] {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.len().encode(w, s);
-        w.write_all(self).unwrap();
-    }
-}
-
-impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        let len = usize::decode(r, s);
-        let xs = &r[..len];
-        *r = &r[len..];
-        xs
-    }
-}
-
-impl<S> Encode<S> for &str {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.as_bytes().encode(w, s);
-    }
-}
-
-impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
-    }
-}
-
-impl<S> Encode<S> for String {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self[..].encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for String {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        <&str>::decode(r, s).to_string()
-    }
-}
-
-impl<S, T: Encode<S>> Encode<S> for Vec<T> {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.len().encode(w, s);
-        for x in self {
-            x.encode(w, s);
-        }
-    }
-}
-
-impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        let len = usize::decode(r, s);
-        let mut vec = Vec::with_capacity(len);
-        for _ in 0..len {
-            vec.push(T::decode(r, s));
-        }
-        vec
-    }
-}
-
-/// Simplified version of panic payloads, ignoring
-/// types other than `&'static str` and `String`.
-pub enum PanicMessage {
-    StaticStr(&'static str),
-    String(String),
-    Unknown,
-}
-
-impl From<Box<dyn Any + Send>> for PanicMessage {
-    fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
-        if let Some(s) = payload.downcast_ref::<&'static str>() {
-            return PanicMessage::StaticStr(s);
-        }
-        if let Ok(s) = payload.downcast::<String>() {
-            return PanicMessage::String(*s);
-        }
-        PanicMessage::Unknown
-    }
-}
-
-impl Into<Box<dyn Any + Send>> for PanicMessage {
-    fn into(self) -> Box<dyn Any + Send> {
-        match self {
-            PanicMessage::StaticStr(s) => Box::new(s),
-            PanicMessage::String(s) => Box::new(s),
-            PanicMessage::Unknown => {
-                struct UnknownPanicMessage;
-                Box::new(UnknownPanicMessage)
-            }
-        }
-    }
-}
-
-impl PanicMessage {
-    pub fn as_str(&self) -> Option<&str> {
-        match self {
-            PanicMessage::StaticStr(s) => Some(s),
-            PanicMessage::String(s) => Some(s),
-            PanicMessage::Unknown => None,
-        }
-    }
-}
-
-impl<S> Encode<S> for PanicMessage {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.as_str().encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for PanicMessage {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        match Option::<String>::decode(r, s) {
-            Some(s) => PanicMessage::String(s),
-            None => PanicMessage::Unknown,
-        }
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs
deleted file mode 100644
index 2cde1f65adf..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-//! `Cell` variant for (scoped) existential lifetimes.
-
-use std::cell::Cell;
-use std::mem;
-use std::ops::{Deref, DerefMut};
-
-/// Type lambda application, with a lifetime.
-#[allow(unused_lifetimes)]
-pub trait ApplyL<'a> {
-    type Out;
-}
-
-/// Type lambda taking a lifetime, i.e., `Lifetime -> Type`.
-pub trait LambdaL: for<'a> ApplyL<'a> {}
-
-impl<T: for<'a> ApplyL<'a>> LambdaL for T {}
-
-// HACK(eddyb) work around projection limitations with a newtype
-// FIXME(#52812) replace with `&'a mut <T as ApplyL<'b>>::Out`
-pub struct RefMutL<'a, 'b, T: LambdaL>(&'a mut <T as ApplyL<'b>>::Out);
-
-impl<'a, 'b, T: LambdaL> Deref for RefMutL<'a, 'b, T> {
-    type Target = <T as ApplyL<'b>>::Out;
-    fn deref(&self) -> &Self::Target {
-        self.0
-    }
-}
-
-impl<'a, 'b, T: LambdaL> DerefMut for RefMutL<'a, 'b, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        self.0
-    }
-}
-
-pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);
-
-impl<T: LambdaL> ScopedCell<T> {
-    pub const fn new(value: <T as ApplyL<'static>>::Out) -> Self {
-        ScopedCell(Cell::new(value))
-    }
-
-    /// Sets the value in `self` to `replacement` while
-    /// running `f`, which gets the old value, mutably.
-    /// The old value will be restored after `f` exits, even
-    /// by panic, including modifications made to it by `f`.
-    pub fn replace<'a, R>(
-        &self,
-        replacement: <T as ApplyL<'a>>::Out,
-        f: impl for<'b, 'c> FnOnce(RefMutL<'b, 'c, T>) -> R,
-    ) -> R {
-        /// Wrapper that ensures that the cell always gets filled
-        /// (with the original state, optionally changed by `f`),
-        /// even if `f` had panicked.
-        struct PutBackOnDrop<'a, T: LambdaL> {
-            cell: &'a ScopedCell<T>,
-            value: Option<<T as ApplyL<'static>>::Out>,
-        }
-
-        impl<'a, T: LambdaL> Drop for PutBackOnDrop<'a, T> {
-            fn drop(&mut self) {
-                self.cell.0.set(self.value.take().unwrap());
-            }
-        }
-
-        let mut put_back_on_drop = PutBackOnDrop {
-            cell: self,
-            value: Some(self.0.replace(unsafe {
-                let erased = mem::transmute_copy(&replacement);
-                mem::forget(replacement);
-                erased
-            })),
-        };
-
-        f(RefMutL(put_back_on_drop.value.as_mut().unwrap()))
-    }
-
-    /// Sets the value in `self` to `value` while running `f`.
-    pub fn set<R>(&self, value: <T as ApplyL<'_>>::Out, f: impl FnOnce() -> R) -> R {
-        self.replace(value, |_| f())
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs
deleted file mode 100644
index 907ad256e4b..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-//! Abstraction for creating `fn` pointers from any callable that *effectively*
-//! has the equivalent of implementing `Default`, even if the compiler neither
-//! provides `Default` nor allows reifying closures (i.e. creating `fn` pointers)
-//! other than those with absolutely no captures.
-//!
-//! More specifically, for a closure-like type to be "effectively `Default`":
-//! * it must be a ZST (zero-sized type): no information contained within, so
-//!   that `Default`'s return value (if it were implemented) is unambiguous
-//! * it must be `Copy`: no captured "unique ZST tokens" or any other similar
-//!   types that would make duplicating values at will unsound
-//!   * combined with the ZST requirement, this confers a kind of "telecopy"
-//!     ability: similar to `Copy`, but without keeping the value around, and
-//!     instead "reconstructing" it (a noop given it's a ZST) when needed
-//! * it must be *provably* inhabited: no captured uninhabited types or any
-//!   other types that cannot be constructed by the user of this abstraction
-//!   * the proof is a value of the closure-like type itself, in a sense the
-//!     "seed" for the "telecopy" process made possible by ZST + `Copy`
-//!   * this requirement is the only reason an abstraction limited to a specific
-//!     usecase is required: ZST + `Copy` can be checked with *at worst* a panic
-//!     at the "attempted `::default()` call" time, but that doesn't guarantee
-//!     that the value can be soundly created, and attempting to use the typical
-//!     "proof ZST token" approach leads yet again to having a ZST + `Copy` type
-//!     that is not proof of anything without a value (i.e. isomorphic to a
-//!     newtype of the type it's trying to prove the inhabitation of)
-//!
-//! A more flexible (and safer) solution to the general problem could exist once
-//! `const`-generic parameters can have type parameters in their types:
-//!
-//! ```rust,ignore (needs future const-generics)
-//! extern "C" fn ffi_wrapper<
-//!     A, R,
-//!     F: Fn(A) -> R,
-//!     const f: F, // <-- this `const`-generic is not yet allowed
-//! >(arg: A) -> R {
-//!     f(arg)
-//! }
-//! ```
-
-use std::mem;
-
-// FIXME(eddyb) this could be `trait` impls except for the `const fn` requirement.
-macro_rules! define_reify_functions {
-    ($(
-        fn $name:ident $(<$($param:ident),*>)?
-            for $(extern $abi:tt)? fn($($arg:ident: $arg_ty:ty),*) -> $ret_ty:ty;
-    )+) => {
-        $(pub const fn $name<
-            $($($param,)*)?
-            F: Fn($($arg_ty),*) -> $ret_ty + Copy
-        >(f: F) -> $(extern $abi)? fn($($arg_ty),*) -> $ret_ty {
-            // FIXME(eddyb) describe the `F` type (e.g. via `type_name::<F>`) once panic
-            // formatting becomes possible in `const fn`.
-            assert!(mem::size_of::<F>() == 0, "selfless_reify: closure must be zero-sized");
-
-            $(extern $abi)? fn wrapper<
-                $($($param,)*)?
-                F: Fn($($arg_ty),*) -> $ret_ty + Copy
-            >($($arg: $arg_ty),*) -> $ret_ty {
-                let f = unsafe {
-                    // SAFETY: `F` satisfies all criteria for "out of thin air"
-                    // reconstructability (see module-level doc comment).
-                    mem::MaybeUninit::<F>::uninit().assume_init()
-                };
-                f($($arg),*)
-            }
-            let _f_proof = f;
-            wrapper::<
-                $($($param,)*)?
-                F
-            >
-        })+
-    }
-}
-
-define_reify_functions! {
-    fn _reify_to_extern_c_fn_unary<A, R> for extern "C" fn(arg: A) -> R;
-
-    // HACK(eddyb) this abstraction is used with `for<'a> fn(BridgeConfig<'a>)
-    // -> T` but that doesn't work with just `reify_to_extern_c_fn_unary`
-    // because of the `fn` pointer type being "higher-ranked" (i.e. the
-    // `for<'a>` binder).
-    // FIXME(eddyb) try to remove the lifetime from `BridgeConfig`, that'd help.
-    fn reify_to_extern_c_fn_hrt_bridge<R> for extern "C" fn(bridge: super::BridgeConfig<'_>) -> R;
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs
deleted file mode 100644
index 6e7a8d8c10d..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-//! Server-side traits.
-
-use super::*;
-
-// FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
-use super::client::HandleStore;
-
-pub trait Types {
-    type FreeFunctions: 'static;
-    type TokenStream: 'static + Clone;
-    type Ident: 'static + Copy + Eq + Hash;
-    type Literal: 'static + Clone;
-    type SourceFile: 'static + Clone;
-    type MultiSpan: 'static;
-    type Diagnostic: 'static;
-    type Span: 'static + Copy + Eq + Hash;
-}
-
-/// Declare an associated fn of one of the traits below, adding necessary
-/// default bodies.
-macro_rules! associated_fn {
-    (fn drop(&mut self, $arg:ident: $arg_ty:ty)) =>
-        (fn drop(&mut self, $arg: $arg_ty) { mem::drop($arg) });
-
-    (fn clone(&mut self, $arg:ident: $arg_ty:ty) -> $ret_ty:ty) =>
-        (fn clone(&mut self, $arg: $arg_ty) -> $ret_ty { $arg.clone() });
-
-    ($($item:tt)*) => ($($item)*;)
-}
-
-macro_rules! declare_server_traits {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
-    }),* $(,)?) => {
-        $(pub trait $name: Types {
-            $(associated_fn!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
-        })*
-
-        pub trait Server: Types $(+ $name)* {
-            fn globals(&mut self) -> ExpnGlobals<Self::Span>;
-        }
-    }
-}
-with_api!(Self, self_, declare_server_traits);
-
-pub(super) struct MarkedTypes<S: Types>(S);
-
-impl<S: Server> Server for MarkedTypes<S> {
-    fn globals(&mut self) -> ExpnGlobals<Self::Span> {
-        <_>::mark(Server::globals(&mut self.0))
-    }
-}
-
-macro_rules! define_mark_types_impls {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
-    }),* $(,)?) => {
-        impl<S: Types> Types for MarkedTypes<S> {
-            $(type $name = Marked<S::$name, client::$name>;)*
-        }
-
-        $(impl<S: $name> $name for MarkedTypes<S> {
-            $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? {
-                <_>::mark($name::$method(&mut self.0, $($arg.unmark()),*))
-            })*
-        })*
-    }
-}
-with_api!(Self, self_, define_mark_types_impls);
-
-struct Dispatcher<S: Types> {
-    handle_store: HandleStore<S>,
-    server: S,
-}
-
-macro_rules! define_dispatcher_impl {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
-    }),* $(,)?) => {
-        // FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
-        pub trait DispatcherTrait {
-            // HACK(eddyb) these are here to allow `Self::$name` to work below.
-            $(type $name;)*
-            fn dispatch(&mut self, buf: Buffer) -> Buffer;
-        }
-
-        impl<S: Server> DispatcherTrait for Dispatcher<MarkedTypes<S>> {
-            $(type $name = <MarkedTypes<S> as Types>::$name;)*
-            fn dispatch(&mut self, mut buf: Buffer) -> Buffer {
-                let Dispatcher { handle_store, server } = self;
-
-                let mut reader = &buf[..];
-                match api_tags::Method::decode(&mut reader, &mut ()) {
-                    $(api_tags::Method::$name(m) => match m {
-                        $(api_tags::$name::$method => {
-                            let mut call_method = || {
-                                reverse_decode!(reader, handle_store; $($arg: $arg_ty),*);
-                                $name::$method(server, $($arg),*)
-                            };
-                            // HACK(eddyb) don't use `panic::catch_unwind` in a panic.
-                            // If client and server happen to use the same `libstd`,
-                            // `catch_unwind` asserts that the panic counter was 0,
-                            // even when the closure passed to it didn't panic.
-                            let r = if thread::panicking() {
-                                Ok(call_method())
-                            } else {
-                                panic::catch_unwind(panic::AssertUnwindSafe(call_method))
-                                    .map_err(PanicMessage::from)
-                            };
-
-                            buf.clear();
-                            r.encode(&mut buf, handle_store);
-                        })*
-                    }),*
-                }
-                buf
-            }
-        }
-    }
-}
-with_api!(Self, self_, define_dispatcher_impl);
-
-pub trait ExecutionStrategy {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer;
-}
-
-pub struct SameThread;
-
-impl ExecutionStrategy for SameThread {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer {
-        let mut dispatch = |buf| dispatcher.dispatch(buf);
-
-        run_client(BridgeConfig {
-            input,
-            dispatch: (&mut dispatch).into(),
-            force_show_panics,
-            _marker: marker::PhantomData,
-        })
-    }
-}
-
-// NOTE(eddyb) Two implementations are provided, the second one is a bit
-// faster but neither is anywhere near as fast as same-thread execution.
-
-pub struct CrossThread1;
-
-impl ExecutionStrategy for CrossThread1 {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer {
-        use std::sync::mpsc::channel;
-
-        let (req_tx, req_rx) = channel();
-        let (res_tx, res_rx) = channel();
-
-        let join_handle = thread::spawn(move || {
-            let mut dispatch = |buf| {
-                req_tx.send(buf).unwrap();
-                res_rx.recv().unwrap()
-            };
-
-            run_client(BridgeConfig {
-                input,
-                dispatch: (&mut dispatch).into(),
-                force_show_panics,
-                _marker: marker::PhantomData,
-            })
-        });
-
-        for b in req_rx {
-            res_tx.send(dispatcher.dispatch(b)).unwrap();
-        }
-
-        join_handle.join().unwrap()
-    }
-}
-
-pub struct CrossThread2;
-
-impl ExecutionStrategy for CrossThread2 {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer {
-        use std::sync::{Arc, Mutex};
-
-        enum State<T> {
-            Req(T),
-            Res(T),
-        }
-
-        let mut state = Arc::new(Mutex::new(State::Res(Buffer::new())));
-
-        let server_thread = thread::current();
-        let state2 = state.clone();
-        let join_handle = thread::spawn(move || {
-            let mut dispatch = |b| {
-                *state2.lock().unwrap() = State::Req(b);
-                server_thread.unpark();
-                loop {
-                    thread::park();
-                    if let State::Res(b) = &mut *state2.lock().unwrap() {
-                        break b.take();
-                    }
-                }
-            };
-
-            let r = run_client(BridgeConfig {
-                input,
-                dispatch: (&mut dispatch).into(),
-                force_show_panics,
-                _marker: marker::PhantomData,
-            });
-
-            // Wake up the server so it can exit the dispatch loop.
-            drop(state2);
-            server_thread.unpark();
-
-            r
-        });
-
-        // Check whether `state2` was dropped, to know when to stop.
-        while Arc::get_mut(&mut state).is_none() {
-            thread::park();
-            let mut b = match &mut *state.lock().unwrap() {
-                State::Req(b) => b.take(),
-                _ => continue,
-            };
-            b = dispatcher.dispatch(b.take());
-            *state.lock().unwrap() = State::Res(b);
-            join_handle.thread().unpark();
-        }
-
-        join_handle.join().unwrap()
-    }
-}
-
-fn run_server<
-    S: Server,
-    I: Encode<HandleStore<MarkedTypes<S>>>,
-    O: for<'a, 's> DecodeMut<'a, 's, HandleStore<MarkedTypes<S>>>,
->(
-    strategy: &impl ExecutionStrategy,
-    handle_counters: &'static client::HandleCounters,
-    server: S,
-    input: I,
-    run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-    force_show_panics: bool,
-) -> Result<O, PanicMessage> {
-    let mut dispatcher =
-        Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) };
-
-    let globals = dispatcher.server.globals();
-
-    let mut buf = Buffer::new();
-    (globals, input).encode(&mut buf, &mut dispatcher.handle_store);
-
-    buf = strategy.run_bridge_and_client(&mut dispatcher, buf, run_client, force_show_panics);
-
-    Result::decode(&mut &buf[..], &mut dispatcher.handle_store)
-}
-
-impl client::Client<super::super::TokenStream, super::super::TokenStream> {
-    pub fn run<S>(
-        &self,
-        strategy: &impl ExecutionStrategy,
-        server: S,
-        input: S::TokenStream,
-        force_show_panics: bool,
-    ) -> Result<S::TokenStream, PanicMessage>
-    where
-        S: Server,
-        S::TokenStream: Default,
-    {
-        let client::Client { get_handle_counters, run, _marker } = *self;
-        run_server(
-            strategy,
-            get_handle_counters(),
-            server,
-            <MarkedTypes<S> as Types>::TokenStream::mark(input),
-            run,
-            force_show_panics,
-        )
-        .map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
-    }
-}
-
-impl
-    client::Client<
-        (super::super::TokenStream, super::super::TokenStream),
-        super::super::TokenStream,
-    >
-{
-    pub fn run<S>(
-        &self,
-        strategy: &impl ExecutionStrategy,
-        server: S,
-        input: S::TokenStream,
-        input2: S::TokenStream,
-        force_show_panics: bool,
-    ) -> Result<S::TokenStream, PanicMessage>
-    where
-        S: Server,
-        S::TokenStream: Default,
-    {
-        let client::Client { get_handle_counters, run, _marker } = *self;
-        run_server(
-            strategy,
-            get_handle_counters(),
-            server,
-            (
-                <MarkedTypes<S> as Types>::TokenStream::mark(input),
-                <MarkedTypes<S> as Types>::TokenStream::mark(input2),
-            ),
-            run,
-            force_show_panics,
-        )
-        .map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs
deleted file mode 100644
index 3fade2dc4f9..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-//! lib-proc-macro diagnostic
-//!
-//! Copy from <https://github.com/rust-lang/rust/blob/e45d9973b2665897a768312e971b82cc62633103/src/libproc_macro/diagnostic.rs>
-//! augmented with removing unstable features
-
-use super::Span;
-
-/// An enum representing a diagnostic level.
-#[derive(Copy, Clone, Debug)]
-#[non_exhaustive]
-pub enum Level {
-    /// An error.
-    Error,
-    /// A warning.
-    Warning,
-    /// A note.
-    Note,
-    /// A help message.
-    Help,
-}
-
-/// Trait implemented by types that can be converted into a set of `Span`s.
-pub trait MultiSpan {
-    /// Converts `self` into a `Vec<Span>`.
-    fn into_spans(self) -> Vec<Span>;
-}
-
-impl MultiSpan for Span {
-    fn into_spans(self) -> Vec<Span> {
-        vec![self]
-    }
-}
-
-impl MultiSpan for Vec<Span> {
-    fn into_spans(self) -> Vec<Span> {
-        self
-    }
-}
-
-impl<'a> MultiSpan for &'a [Span] {
-    fn into_spans(self) -> Vec<Span> {
-        self.to_vec()
-    }
-}
-
-/// A structure representing a diagnostic message and associated children
-/// messages.
-#[derive(Clone, Debug)]
-pub struct Diagnostic {
-    level: Level,
-    message: String,
-    spans: Vec<Span>,
-    children: Vec<Diagnostic>,
-}
-
-macro_rules! diagnostic_child_methods {
-    ($spanned:ident, $regular:ident, $level:expr) => {
-        #[doc = concat!("Adds a new child diagnostics message to `self` with the [`",
-                        stringify!($level), "`] level, and the given `spans` and `message`.")]
-        pub fn $spanned<S, T>(mut self, spans: S, message: T) -> Diagnostic
-        where
-            S: MultiSpan,
-            T: Into<String>,
-        {
-            self.children.push(Diagnostic::spanned(spans, $level, message));
-            self
-        }
-
-        #[doc = concat!("Adds a new child diagnostic message to `self` with the [`",
-                        stringify!($level), "`] level, and the given `message`.")]
-        pub fn $regular<T: Into<String>>(mut self, message: T) -> Diagnostic {
-            self.children.push(Diagnostic::new($level, message));
-            self
-        }
-    };
-}
-
-/// Iterator over the children diagnostics of a `Diagnostic`.
-#[derive(Debug, Clone)]
-pub struct Children<'a>(std::slice::Iter<'a, Diagnostic>);
-
-impl<'a> Iterator for Children<'a> {
-    type Item = &'a Diagnostic;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        self.0.next()
-    }
-}
-
-impl Diagnostic {
-    /// Creates a new diagnostic with the given `level` and `message`.
-    pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
-        Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
-    }
-
-    /// Creates a new diagnostic with the given `level` and `message` pointing to
-    /// the given set of `spans`.
-    pub fn spanned<S, T>(spans: S, level: Level, message: T) -> Diagnostic
-    where
-        S: MultiSpan,
-        T: Into<String>,
-    {
-        Diagnostic { level, message: message.into(), spans: spans.into_spans(), children: vec![] }
-    }
-
-    diagnostic_child_methods!(span_error, error, Level::Error);
-    diagnostic_child_methods!(span_warning, warning, Level::Warning);
-    diagnostic_child_methods!(span_note, note, Level::Note);
-    diagnostic_child_methods!(span_help, help, Level::Help);
-
-    /// Returns the diagnostic `level` for `self`.
-    pub fn level(&self) -> Level {
-        self.level
-    }
-
-    /// Sets the level in `self` to `level`.
-    pub fn set_level(&mut self, level: Level) {
-        self.level = level;
-    }
-
-    /// Returns the message in `self`.
-    pub fn message(&self) -> &str {
-        &self.message
-    }
-
-    /// Sets the message in `self` to `message`.
-    pub fn set_message<T: Into<String>>(&mut self, message: T) {
-        self.message = message.into();
-    }
-
-    /// Returns the `Span`s in `self`.
-    pub fn spans(&self) -> &[Span] {
-        &self.spans
-    }
-
-    /// Sets the `Span`s in `self` to `spans`.
-    pub fn set_spans<S: MultiSpan>(&mut self, spans: S) {
-        self.spans = spans.into_spans();
-    }
-
-    /// Returns an iterator over the children diagnostics of `self`.
-    pub fn children(&self) -> Children<'_> {
-        Children(self.children.iter())
-    }
-
-    /// Emit the diagnostic.
-    pub fn emit(self) {
-        fn to_internal(spans: Vec<Span>) -> super::bridge::client::MultiSpan {
-            let mut multi_span = super::bridge::client::MultiSpan::new();
-            for span in spans {
-                multi_span.push(span.0);
-            }
-            multi_span
-        }
-
-        let mut diag = super::bridge::client::Diagnostic::new(
-            self.level,
-            &self.message[..],
-            to_internal(self.spans),
-        );
-        for c in self.children {
-            diag.sub(c.level, &c.message[..], to_internal(c.spans));
-        }
-        diag.emit();
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
deleted file mode 100644
index be62c73ef32..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
+++ /dev/null
@@ -1,1125 +0,0 @@
-//! A support library for macro authors when defining new macros.
-//!
-//! This library, provided by the standard distribution, provides the types
-//! consumed in the interfaces of procedurally defined macro definitions such as
-//! function-like macros `#[proc_macro]`, macro attributes `#[proc_macro_attribute]` and
-//! custom derive attributes`#[proc_macro_derive]`.
-//!
-//! See [the book] for more.
-//!
-//! [the book]: ../book/ch19-06-macros.html#procedural-macros-for-generating-code-from-attributes
-
-#[doc(hidden)]
-pub mod bridge;
-
-mod diagnostic;
-
-pub use diagnostic::{Diagnostic, Level, MultiSpan};
-
-use std::cmp::Ordering;
-use std::ops::RangeBounds;
-use std::path::PathBuf;
-use std::str::FromStr;
-use std::{error, fmt, iter, mem};
-
-/// Determines whether proc_macro has been made accessible to the currently
-/// running program.
-///
-/// The proc_macro crate is only intended for use inside the implementation of
-/// procedural macros. All the functions in this crate panic if invoked from
-/// outside of a procedural macro, such as from a build script or unit test or
-/// ordinary Rust binary.
-///
-/// With consideration for Rust libraries that are designed to support both
-/// macro and non-macro use cases, `proc_macro::is_available()` provides a
-/// non-panicking way to detect whether the infrastructure required to use the
-/// API of proc_macro is presently available. Returns true if invoked from
-/// inside of a procedural macro, false if invoked from any other binary.
-pub fn is_available() -> bool {
-    bridge::client::is_available()
-}
-
-/// The main type provided by this crate, representing an abstract stream of
-/// tokens, or, more specifically, a sequence of token trees.
-/// The type provide interfaces for iterating over those token trees and, conversely,
-/// collecting a number of token trees into one stream.
-///
-/// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
-/// and `#[proc_macro_derive]` definitions.
-#[derive(Clone)]
-pub struct TokenStream(Option<bridge::client::TokenStream>);
-
-/// Error returned from `TokenStream::from_str`.
-#[non_exhaustive]
-#[derive(Debug)]
-pub struct LexError;
-
-impl fmt::Display for LexError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("cannot parse string into token stream")
-    }
-}
-
-impl error::Error for LexError {}
-
-/// Error returned from `TokenStream::expand_expr`.
-#[non_exhaustive]
-#[derive(Debug)]
-pub struct ExpandError;
-
-impl fmt::Display for ExpandError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("macro expansion failed")
-    }
-}
-
-impl error::Error for ExpandError {}
-
-impl TokenStream {
-    /// Returns an empty `TokenStream` containing no token trees.
-    pub fn new() -> TokenStream {
-        TokenStream(None)
-    }
-
-    /// Checks if this `TokenStream` is empty.
-    pub fn is_empty(&self) -> bool {
-        self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true)
-    }
-
-    /// Parses this `TokenStream` as an expression and attempts to expand any
-    /// macros within it. Returns the expanded `TokenStream`.
-    ///
-    /// Currently only expressions expanding to literals will succeed, although
-    /// this may be relaxed in the future.
-    ///
-    /// NOTE: In error conditions, `expand_expr` may leave macros unexpanded,
-    /// report an error, failing compilation, and/or return an `Err(..)`. The
-    /// specific behavior for any error condition, and what conditions are
-    /// considered errors, is unspecified and may change in the future.
-    pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
-        let stream = self.0.as_ref().ok_or(ExpandError)?;
-        match bridge::client::TokenStream::expand_expr(stream) {
-            Ok(stream) => Ok(TokenStream(Some(stream))),
-            Err(_) => Err(ExpandError),
-        }
-    }
-}
-
-/// Attempts to break the string into tokens and parse those tokens into a token stream.
-/// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
-/// or characters not existing in the language.
-/// All tokens in the parsed stream get `Span::call_site()` spans.
-///
-/// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
-/// change these errors into `LexError`s later.
-impl FromStr for TokenStream {
-    type Err = LexError;
-
-    fn from_str(src: &str) -> Result<TokenStream, LexError> {
-        Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src))))
-    }
-}
-
-/// Prints the token stream as a string that is supposed to be losslessly convertible back
-/// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters and negative numeric literals.
-impl fmt::Display for TokenStream {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-/// Prints token in a form convenient for debugging.
-impl fmt::Debug for TokenStream {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("TokenStream ")?;
-        f.debug_list().entries(self.clone()).finish()
-    }
-}
-
-impl Default for TokenStream {
-    fn default() -> Self {
-        TokenStream::new()
-    }
-}
-
-pub use quote::{quote, quote_span};
-
-fn tree_to_bridge_tree(
-    tree: TokenTree,
-) -> bridge::TokenTree<
-    bridge::client::TokenStream,
-    bridge::client::Span,
-    bridge::client::Ident,
-    bridge::client::Literal,
-> {
-    match tree {
-        TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
-        TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
-        TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
-        TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0),
-    }
-}
-
-/// Creates a token stream containing a single token tree.
-impl From<TokenTree> for TokenStream {
-    fn from(tree: TokenTree) -> TokenStream {
-        TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree))))
-    }
-}
-
-/// Non-generic helper for implementing `FromIterator<TokenStream>` and
-/// `Extend<TokenStream>` with less monomorphization in calling crates.
-struct ConcatStreamsHelper {
-    streams: Vec<bridge::client::TokenStream>,
-}
-
-impl ConcatStreamsHelper {
-    fn new(capacity: usize) -> Self {
-        ConcatStreamsHelper { streams: Vec::with_capacity(capacity) }
-    }
-
-    fn push(&mut self, stream: TokenStream) {
-        if let Some(stream) = stream.0 {
-            self.streams.push(stream);
-        }
-    }
-
-    fn build(mut self) -> TokenStream {
-        if self.streams.len() <= 1 {
-            TokenStream(self.streams.pop())
-        } else {
-            TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams)))
-        }
-    }
-
-    fn append_to(mut self, stream: &mut TokenStream) {
-        if self.streams.is_empty() {
-            return;
-        }
-        let base = stream.0.take();
-        if base.is_none() && self.streams.len() == 1 {
-            stream.0 = self.streams.pop();
-        } else {
-            stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams));
-        }
-    }
-}
-
-/// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
-        trees.into_iter().map(TokenStream::from).collect()
-    }
-}
-
-/// A "flattening" operation on token streams, collects token trees
-/// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
-        let iter = streams.into_iter();
-        let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
-        iter.for_each(|stream| builder.push(stream));
-        builder.build()
-    }
-}
-
-impl Extend<TokenTree> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
-        self.extend(trees.into_iter().map(TokenStream::from));
-    }
-}
-
-impl Extend<TokenStream> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
-        // FIXME(eddyb) Use an optimized implementation if/when possible.
-        *self = iter::once(mem::replace(self, Self::new())).chain(streams).collect();
-    }
-}
-
-/// Public implementation details for the `TokenStream` type, such as iterators.
-pub mod token_stream {
-    use super::{bridge, Group, Ident, Literal, Punct, TokenStream, TokenTree};
-
-    /// An iterator over `TokenStream`'s `TokenTree`s.
-    /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
-    /// and returns whole groups as token trees.
-    #[derive(Clone)]
-    pub struct IntoIter(
-        std::vec::IntoIter<
-            bridge::TokenTree<
-                bridge::client::TokenStream,
-                bridge::client::Span,
-                bridge::client::Ident,
-                bridge::client::Literal,
-            >,
-        >,
-    );
-
-    impl Iterator for IntoIter {
-        type Item = TokenTree;
-
-        fn next(&mut self) -> Option<TokenTree> {
-            self.0.next().map(|tree| match tree {
-                bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
-                bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
-                bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
-                bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
-            })
-        }
-    }
-
-    impl IntoIterator for TokenStream {
-        type Item = TokenTree;
-        type IntoIter = IntoIter;
-
-        fn into_iter(self) -> IntoIter {
-            IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter())
-        }
-    }
-}
-
-#[doc(hidden)]
-mod quote;
-
-/// A region of source code, along with macro expansion information.
-#[derive(Copy, Clone)]
-pub struct Span(bridge::client::Span);
-
-macro_rules! diagnostic_method {
-    ($name:ident, $level:expr) => {
-        /// Creates a new `Diagnostic` with the given `message` at the span
-        /// `self`.
-        pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
-            Diagnostic::spanned(self, $level, message)
-        }
-    };
-}
-
-impl Span {
-    /// A span that resolves at the macro definition site.
-    pub fn def_site() -> Span {
-        Span(bridge::client::Span::def_site())
-    }
-
-    /// The span of the invocation of the current procedural macro.
-    /// Identifiers created with this span will be resolved as if they were written
-    /// directly at the macro call location (call-site hygiene) and other code
-    /// at the macro call site will be able to refer to them as well.
-    pub fn call_site() -> Span {
-        Span(bridge::client::Span::call_site())
-    }
-
-    /// A span that represents `macro_rules` hygiene, and sometimes resolves at the macro
-    /// definition site (local variables, labels, `$crate`) and sometimes at the macro
-    /// call site (everything else).
-    /// The span location is taken from the call-site.
-    pub fn mixed_site() -> Span {
-        Span(bridge::client::Span::mixed_site())
-    }
-
-    /// The original source file into which this span points.
-    pub fn source_file(&self) -> SourceFile {
-        SourceFile(self.0.source_file())
-    }
-
-    /// The `Span` for the tokens in the previous macro expansion from which
-    /// `self` was generated from, if any.
-    pub fn parent(&self) -> Option<Span> {
-        self.0.parent().map(Span)
-    }
-
-    /// The span for the origin source code that `self` was generated from. If
-    /// this `Span` wasn't generated from other macro expansions then the return
-    /// value is the same as `*self`.
-    pub fn source(&self) -> Span {
-        Span(self.0.source())
-    }
-
-    /// Gets the starting line/column in the source file for this span.
-    pub fn start(&self) -> LineColumn {
-        self.0.start().add_1_to_column()
-    }
-
-    /// Gets the ending line/column in the source file for this span.
-    pub fn end(&self) -> LineColumn {
-        self.0.end().add_1_to_column()
-    }
-
-    /// Creates an empty span pointing to directly before this span.
-    pub fn before(&self) -> Span {
-        Span(self.0.before())
-    }
-
-    /// Creates an empty span pointing to directly after this span.
-    pub fn after(&self) -> Span {
-        Span(self.0.after())
-    }
-
-    /// Creates a new span encompassing `self` and `other`.
-    ///
-    /// Returns `None` if `self` and `other` are from different files.
-    pub fn join(&self, other: Span) -> Option<Span> {
-        self.0.join(other.0).map(Span)
-    }
-
-    /// Creates a new span with the same line/column information as `self` but
-    /// that resolves symbols as though it were at `other`.
-    pub fn resolved_at(&self, other: Span) -> Span {
-        Span(self.0.resolved_at(other.0))
-    }
-
-    /// Creates a new span with the same name resolution behavior as `self` but
-    /// with the line/column information of `other`.
-    pub fn located_at(&self, other: Span) -> Span {
-        other.resolved_at(*self)
-    }
-
-    /// Compares to spans to see if they're equal.
-    pub fn eq(&self, other: &Span) -> bool {
-        self.0 == other.0
-    }
-
-    /// Returns the source text behind a span. This preserves the original source
-    /// code, including spaces and comments. It only returns a result if the span
-    /// corresponds to real source code.
-    ///
-    /// Note: The observable result of a macro should only rely on the tokens and
-    /// not on this source text. The result of this function is a best effort to
-    /// be used for diagnostics only.
-    pub fn source_text(&self) -> Option<String> {
-        self.0.source_text()
-    }
-
-    // Used by the implementation of `Span::quote`
-    #[doc(hidden)]
-    pub fn save_span(&self) -> usize {
-        self.0.save_span()
-    }
-
-    // Used by the implementation of `Span::quote`
-    #[doc(hidden)]
-    pub fn recover_proc_macro_span(id: usize) -> Span {
-        Span(bridge::client::Span::recover_proc_macro_span(id))
-    }
-
-    diagnostic_method!(error, Level::Error);
-    diagnostic_method!(warning, Level::Warning);
-    diagnostic_method!(note, Level::Note);
-    diagnostic_method!(help, Level::Help);
-}
-
-/// Prints a span in a form convenient for debugging.
-impl fmt::Debug for Span {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-/// A line-column pair representing the start or end of a `Span`.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct LineColumn {
-    /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
-    pub line: usize,
-    /// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
-    /// file on which the span starts or ends (inclusive).
-    pub column: usize,
-}
-
-impl LineColumn {
-    fn add_1_to_column(self) -> Self {
-        LineColumn { line: self.line, column: self.column + 1 }
-    }
-}
-
-impl Ord for LineColumn {
-    fn cmp(&self, other: &Self) -> Ordering {
-        self.line.cmp(&other.line).then(self.column.cmp(&other.column))
-    }
-}
-
-impl PartialOrd for LineColumn {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-/// The source file of a given `Span`.
-#[derive(Clone)]
-pub struct SourceFile(bridge::client::SourceFile);
-
-impl SourceFile {
-    /// Gets the path to this source file.
-    ///
-    /// ### Note
-    /// If the code span associated with this `SourceFile` was generated by an external macro, this
-    /// macro, this might not be an actual path on the filesystem. Use [`is_real`] to check.
-    ///
-    /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
-    /// the command line, the path as given might not actually be valid.
-    ///
-    /// [`is_real`]: Self::is_real
-    pub fn path(&self) -> PathBuf {
-        PathBuf::from(self.0.path())
-    }
-
-    /// Returns `true` if this source file is a real source file, and not generated by an external
-    /// macro's expansion.
-    pub fn is_real(&self) -> bool {
-        // This is a hack until intercrate spans are implemented and we can have real source files
-        // for spans generated in external macros.
-        // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
-        self.0.is_real()
-    }
-}
-
-impl fmt::Debug for SourceFile {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("SourceFile")
-            .field("path", &self.path())
-            .field("is_real", &self.is_real())
-            .finish()
-    }
-}
-
-impl PartialEq for SourceFile {
-    fn eq(&self, other: &Self) -> bool {
-        self.0.eq(&other.0)
-    }
-}
-
-impl Eq for SourceFile {}
-
-/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
-#[derive(Clone)]
-pub enum TokenTree {
-    /// A token stream surrounded by bracket delimiters.
-    Group(Group),
-    /// An identifier.
-    Ident(Ident),
-    /// A single punctuation character (`+`, `,`, `$`, etc.).
-    Punct(Punct),
-    /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
-    Literal(Literal),
-}
-
-impl TokenTree {
-    /// Returns the span of this tree, delegating to the `span` method of
-    /// the contained token or a delimited stream.
-    pub fn span(&self) -> Span {
-        match *self {
-            TokenTree::Group(ref t) => t.span(),
-            TokenTree::Ident(ref t) => t.span(),
-            TokenTree::Punct(ref t) => t.span(),
-            TokenTree::Literal(ref t) => t.span(),
-        }
-    }
-
-    /// Configures the span for *only this token*.
-    ///
-    /// Note that if this token is a `Group` then this method will not configure
-    /// the span of each of the internal tokens, this will simply delegate to
-    /// the `set_span` method of each variant.
-    pub fn set_span(&mut self, span: Span) {
-        match *self {
-            TokenTree::Group(ref mut t) => t.set_span(span),
-            TokenTree::Ident(ref mut t) => t.set_span(span),
-            TokenTree::Punct(ref mut t) => t.set_span(span),
-            TokenTree::Literal(ref mut t) => t.set_span(span),
-        }
-    }
-}
-
-/// Prints token tree in a form convenient for debugging.
-impl fmt::Debug for TokenTree {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // Each of these has the name in the struct type in the derived debug,
-        // so don't bother with an extra layer of indirection
-        match *self {
-            TokenTree::Group(ref tt) => tt.fmt(f),
-            TokenTree::Ident(ref tt) => tt.fmt(f),
-            TokenTree::Punct(ref tt) => tt.fmt(f),
-            TokenTree::Literal(ref tt) => tt.fmt(f),
-        }
-    }
-}
-
-impl From<Group> for TokenTree {
-    fn from(g: Group) -> TokenTree {
-        TokenTree::Group(g)
-    }
-}
-
-impl From<Ident> for TokenTree {
-    fn from(g: Ident) -> TokenTree {
-        TokenTree::Ident(g)
-    }
-}
-
-impl From<Punct> for TokenTree {
-    fn from(g: Punct) -> TokenTree {
-        TokenTree::Punct(g)
-    }
-}
-
-impl From<Literal> for TokenTree {
-    fn from(g: Literal) -> TokenTree {
-        TokenTree::Literal(g)
-    }
-}
-
-/// Prints the token tree as a string that is supposed to be losslessly convertible back
-/// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters and negative numeric literals.
-impl fmt::Display for TokenTree {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-/// A delimited token stream.
-///
-/// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
-#[derive(Clone)]
-pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
-
-/// Describes how a sequence of token trees is delimited.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Delimiter {
-    /// `( ... )`
-    Parenthesis,
-    /// `{ ... }`
-    Brace,
-    /// `[ ... ]`
-    Bracket,
-    /// `Ø ... Ø`
-    /// An invisible delimiter, that may, for example, appear around tokens coming from a
-    /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
-    /// `$var * 3` where `$var` is `1 + 2`.
-    /// Invisible delimiters might not survive roundtrip of a token stream through a string.
-    None,
-}
-
-impl Group {
-    /// Creates a new `Group` with the given delimiter and token stream.
-    ///
-    /// This constructor will set the span for this group to
-    /// `Span::call_site()`. To change the span you can use the `set_span`
-    /// method below.
-    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
-        Group(bridge::Group {
-            delimiter,
-            stream: stream.0,
-            span: bridge::DelimSpan::from_single(Span::call_site().0),
-        })
-    }
-
-    /// Returns the delimiter of this `Group`
-    pub fn delimiter(&self) -> Delimiter {
-        self.0.delimiter
-    }
-
-    /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
-    ///
-    /// Note that the returned token stream does not include the delimiter
-    /// returned above.
-    pub fn stream(&self) -> TokenStream {
-        TokenStream(self.0.stream.clone())
-    }
-
-    /// Returns the span for the delimiters of this token stream, spanning the
-    /// entire `Group`.
-    ///
-    /// ```text
-    /// pub fn span(&self) -> Span {
-    ///            ^^^^^^^
-    /// ```
-    pub fn span(&self) -> Span {
-        Span(self.0.span.entire)
-    }
-
-    /// Returns the span pointing to the opening delimiter of this group.
-    ///
-    /// ```text
-    /// pub fn span_open(&self) -> Span {
-    ///                 ^
-    /// ```
-    pub fn span_open(&self) -> Span {
-        Span(self.0.span.open)
-    }
-
-    /// Returns the span pointing to the closing delimiter of this group.
-    ///
-    /// ```text
-    /// pub fn span_close(&self) -> Span {
-    ///                        ^
-    /// ```
-    pub fn span_close(&self) -> Span {
-        Span(self.0.span.close)
-    }
-
-    /// Configures the span for this `Group`'s delimiters, but not its internal
-    /// tokens.
-    ///
-    /// This method will **not** set the span of all the internal tokens spanned
-    /// by this group, but rather it will only set the span of the delimiter
-    /// tokens at the level of the `Group`.
-    pub fn set_span(&mut self, span: Span) {
-        self.0.span = bridge::DelimSpan::from_single(span.0);
-    }
-}
-
-/// Prints the group as a string that should be losslessly convertible back
-/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters.
-impl fmt::Display for Group {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Group {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Group")
-            .field("delimiter", &self.delimiter())
-            .field("stream", &self.stream())
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-/// A `Punct` is a single punctuation character such as `+`, `-` or `#`.
-///
-/// Multi-character operators like `+=` are represented as two instances of `Punct` with different
-/// forms of `Spacing` returned.
-#[derive(Clone)]
-pub struct Punct(bridge::Punct<bridge::client::Span>);
-
-/// Describes whether a `Punct` is followed immediately by another `Punct` ([`Spacing::Joint`]) or
-/// by a different token or whitespace ([`Spacing::Alone`]).
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Spacing {
-    /// A `Punct` is not immediately followed by another `Punct`.
-    /// E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`.
-    Alone,
-    /// A `Punct` is immediately followed by another `Punct`.
-    /// E.g. `+` is `Joint` in `+=` and `++`.
-    ///
-    /// Additionally, single quote `'` can join with identifiers to form lifetimes: `'ident`.
-    Joint,
-}
-
-impl Punct {
-    /// Creates a new `Punct` from the given character and spacing.
-    /// The `ch` argument must be a valid punctuation character permitted by the language,
-    /// otherwise the function will panic.
-    ///
-    /// The returned `Punct` will have the default span of `Span::call_site()`
-    /// which can be further configured with the `set_span` method below.
-    pub fn new(ch: char, spacing: Spacing) -> Punct {
-        const LEGAL_CHARS: &[char] = &[
-            '=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
-            ':', '#', '$', '?', '\'',
-        ];
-        if !LEGAL_CHARS.contains(&ch) {
-            panic!("unsupported character `{:?}`", ch);
-        }
-        Punct(bridge::Punct {
-            ch: ch as u8,
-            joint: spacing == Spacing::Joint,
-            span: Span::call_site().0,
-        })
-    }
-
-    /// Returns the value of this punctuation character as `char`.
-    pub fn as_char(&self) -> char {
-        self.0.ch as char
-    }
-
-    /// Returns the spacing of this punctuation character, indicating whether it's immediately
-    /// followed by another `Punct` in the token stream, so they can potentially be combined into
-    /// a multi-character operator (`Joint`), or it's followed by some other token or whitespace
-    /// (`Alone`) so the operator has certainly ended.
-    pub fn spacing(&self) -> Spacing {
-        if self.0.joint {
-            Spacing::Joint
-        } else {
-            Spacing::Alone
-        }
-    }
-
-    /// Returns the span for this punctuation character.
-    pub fn span(&self) -> Span {
-        Span(self.0.span)
-    }
-
-    /// Configure the span for this punctuation character.
-    pub fn set_span(&mut self, span: Span) {
-        self.0.span = span.0;
-    }
-}
-
-/// Prints the punctuation character as a string that should be losslessly convertible
-/// back into the same character.
-impl fmt::Display for Punct {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Punct {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Punct")
-            .field("ch", &self.as_char())
-            .field("spacing", &self.spacing())
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-impl PartialEq<char> for Punct {
-    fn eq(&self, rhs: &char) -> bool {
-        self.as_char() == *rhs
-    }
-}
-
-impl PartialEq<Punct> for char {
-    fn eq(&self, rhs: &Punct) -> bool {
-        *self == rhs.as_char()
-    }
-}
-
-/// An identifier (`ident`).
-#[derive(Clone)]
-pub struct Ident(bridge::client::Ident);
-
-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 (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.
-    ///
-    /// As of this time `Span::call_site()` explicitly opts-in to "call-site" hygiene
-    /// meaning that identifiers created with this span will be resolved as if they were written
-    /// directly at the location of the macro call, and other code at the macro call site will be
-    /// able to refer to them as well.
-    ///
-    /// Later spans like `Span::def_site()` will allow to opt-in to "definition-site" hygiene
-    /// meaning that identifiers created with this span will be resolved at the location of the
-    /// macro definition and other code at the macro call site will not be able to refer to them.
-    ///
-    /// Due to the current importance of hygiene this constructor, unlike other
-    /// tokens, requires a `Span` to be specified at construction.
-    pub fn new(string: &str, span: Span) -> Ident {
-        Ident(bridge::client::Ident::new(string, span.0, false))
-    }
-
-    /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
-    /// 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.
-    pub fn new_raw(string: &str, span: Span) -> Ident {
-        Ident(bridge::client::Ident::new(string, span.0, true))
-    }
-
-    /// Returns the span of this `Ident`, encompassing the entire string returned
-    /// by [`to_string`](Self::to_string).
-    pub fn span(&self) -> Span {
-        Span(self.0.span())
-    }
-
-    /// Configures the span of this `Ident`, possibly changing its hygiene context.
-    pub fn set_span(&mut self, span: Span) {
-        self.0 = self.0.with_span(span.0);
-    }
-}
-
-/// Prints the identifier as a string that should be losslessly convertible
-/// back into the same identifier.
-impl fmt::Display for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Ident")
-            .field("ident", &self.to_string())
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-/// A literal string (`"hello"`), byte string (`b"hello"`),
-/// character (`'a'`), byte character (`b'a'`), an integer or floating point number
-/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
-/// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
-#[derive(Clone)]
-pub struct Literal(bridge::client::Literal);
-
-macro_rules! suffixed_int_literals {
-    ($($name:ident => $kind:ident,)*) => ($(
-        /// Creates a new suffixed integer literal with the specified value.
-        ///
-        /// This function will create an integer like `1u32` where the integer
-        /// value specified is the first part of the token and the integral is
-        /// also suffixed at the end.
-        /// Literals created from negative numbers might not survive round-trips through
-        /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-        ///
-        /// Literals created through this method have the `Span::call_site()`
-        /// span by default, which can be configured with the `set_span` method
-        /// below.
-        pub fn $name(n: $kind) -> Literal {
-            Literal(bridge::client::Literal::typed_integer(&n.to_string(), stringify!($kind)))
-        }
-    )*)
-}
-
-macro_rules! unsuffixed_int_literals {
-    ($($name:ident => $kind:ident,)*) => ($(
-        /// Creates a new unsuffixed integer literal with the specified value.
-        ///
-        /// This function will create an integer like `1` where the integer
-        /// value specified is the first part of the token. No suffix is
-        /// specified on this token, meaning that invocations like
-        /// `Literal::i8_unsuffixed(1)` are equivalent to
-        /// `Literal::u32_unsuffixed(1)`.
-        /// Literals created from negative numbers might not survive rountrips through
-        /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-        ///
-        /// Literals created through this method have the `Span::call_site()`
-        /// span by default, which can be configured with the `set_span` method
-        /// below.
-        pub fn $name(n: $kind) -> Literal {
-            Literal(bridge::client::Literal::integer(&n.to_string()))
-        }
-    )*)
-}
-
-impl Literal {
-    suffixed_int_literals! {
-        u8_suffixed => u8,
-        u16_suffixed => u16,
-        u32_suffixed => u32,
-        u64_suffixed => u64,
-        u128_suffixed => u128,
-        usize_suffixed => usize,
-        i8_suffixed => i8,
-        i16_suffixed => i16,
-        i32_suffixed => i32,
-        i64_suffixed => i64,
-        i128_suffixed => i128,
-        isize_suffixed => isize,
-    }
-
-    unsuffixed_int_literals! {
-        u8_unsuffixed => u8,
-        u16_unsuffixed => u16,
-        u32_unsuffixed => u32,
-        u64_unsuffixed => u64,
-        u128_unsuffixed => u128,
-        usize_unsuffixed => usize,
-        i8_unsuffixed => i8,
-        i16_unsuffixed => i16,
-        i32_unsuffixed => i32,
-        i64_unsuffixed => i64,
-        i128_unsuffixed => i128,
-        isize_unsuffixed => isize,
-    }
-
-    /// Creates a new unsuffixed floating-point literal.
-    ///
-    /// This constructor is similar to those like `Literal::i8_unsuffixed` where
-    /// the float's value is emitted directly into the token but no suffix is
-    /// used, so it may be inferred to be a `f64` later in the compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f32_unsuffixed(n: f32) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        let mut repr = n.to_string();
-        if !repr.contains('.') {
-            repr.push_str(".0");
-        }
-        Literal(bridge::client::Literal::float(&repr))
-    }
-
-    /// Creates a new suffixed floating-point literal.
-    ///
-    /// This constructor will create a literal like `1.0f32` where the value
-    /// specified is the preceding part of the token and `f32` is the suffix of
-    /// the token. This token will always be inferred to be an `f32` in the
-    /// compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f32_suffixed(n: f32) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        Literal(bridge::client::Literal::f32(&n.to_string()))
-    }
-
-    /// Creates a new unsuffixed floating-point literal.
-    ///
-    /// This constructor is similar to those like `Literal::i8_unsuffixed` where
-    /// the float's value is emitted directly into the token but no suffix is
-    /// used, so it may be inferred to be a `f64` later in the compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f64_unsuffixed(n: f64) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        let mut repr = n.to_string();
-        if !repr.contains('.') {
-            repr.push_str(".0");
-        }
-        Literal(bridge::client::Literal::float(&repr))
-    }
-
-    /// Creates a new suffixed floating-point literal.
-    ///
-    /// This constructor will create a literal like `1.0f64` where the value
-    /// specified is the preceding part of the token and `f64` is the suffix of
-    /// the token. This token will always be inferred to be an `f64` in the
-    /// compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f64_suffixed(n: f64) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        Literal(bridge::client::Literal::f64(&n.to_string()))
-    }
-
-    /// String literal.
-    pub fn string(string: &str) -> Literal {
-        Literal(bridge::client::Literal::string(string))
-    }
-
-    /// Character literal.
-    pub fn character(ch: char) -> Literal {
-        Literal(bridge::client::Literal::character(ch))
-    }
-
-    /// Byte string literal.
-    pub fn byte_string(bytes: &[u8]) -> Literal {
-        Literal(bridge::client::Literal::byte_string(bytes))
-    }
-
-    /// Returns the span encompassing this literal.
-    pub fn span(&self) -> Span {
-        Span(self.0.span())
-    }
-
-    /// Configures the span associated for this literal.
-    pub fn set_span(&mut self, span: Span) {
-        self.0.set_span(span.0);
-    }
-
-    /// Returns a `Span` that is a subset of `self.span()` containing only the
-    /// source bytes in range `range`. Returns `None` if the would-be trimmed
-    /// span is outside the bounds of `self`.
-    // FIXME(SergioBenitez): check that the byte range starts and ends at a
-    // UTF-8 boundary of the source. otherwise, it's likely that a panic will
-    // occur elsewhere when the source text is printed.
-    // FIXME(SergioBenitez): there is no way for the user to know what
-    // `self.span()` actually maps to, so this method can currently only be
-    // called blindly. For example, `to_string()` for the character 'c' returns
-    // "'\u{63}'"; there is no way for the user to know whether the source text
-    // was 'c' or whether it was '\u{63}'.
-    pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
-        self.0.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
-    }
-}
-
-/// Parse a single literal from its stringified representation.
-///
-/// In order to parse successfully, the input string must not contain anything
-/// but the literal token. Specifically, it must not contain whitespace or
-/// comments in addition to the literal.
-///
-/// The resulting literal token will have a `Span::call_site()` span.
-///
-/// NOTE: some errors may cause panics instead of returning `LexError`. We
-/// reserve the right to change these errors into `LexError`s later.
-impl FromStr for Literal {
-    type Err = LexError;
-
-    fn from_str(src: &str) -> Result<Self, LexError> {
-        match bridge::client::Literal::from_str(src) {
-            Ok(literal) => Ok(Literal(literal)),
-            Err(()) => Err(LexError),
-        }
-    }
-}
-
-/// Prints the literal as a string that should be losslessly convertible
-/// back into the same literal (except for possible rounding for floating point literals).
-impl fmt::Display for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-/// Tracked access to environment variables.
-pub mod tracked_env {
-    use std::env::{self, VarError};
-    use std::ffi::OsStr;
-
-    /// Retrieve an environment variable and add it to build dependency info.
-    /// Build system executing the compiler will know that the variable was accessed during
-    /// compilation, and will be able to rerun the build when the value of that variable changes.
-    /// Besides the dependency tracking this function should be equivalent to `env::var` from the
-    /// standard library, except that the argument must be UTF-8.
-    pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
-        let key: &str = key.as_ref();
-        let value = env::var(key);
-        super::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
-        value
-    }
-}
-
-/// Tracked access to additional files.
-pub mod tracked_path {
-
-    /// Track a file explicitly.
-    ///
-    /// Commonly used for tracking asset preprocessing.
-    pub fn path<P: AsRef<str>>(path: P) {
-        let path: &str = path.as_ref();
-        super::bridge::client::FreeFunctions::track_path(path);
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs
deleted file mode 100644
index 39309faa412..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-//! # Quasiquoter
-//! This file contains the implementation internals of the quasiquoter provided by `quote!`.
-
-//! This quasiquoter uses macros 2.0 hygiene to reliably access
-//! items from `proc_macro`, to build a `proc_macro::TokenStream`.
-
-use super::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
-
-macro_rules! quote_tt {
-    (($($t:tt)*)) => { Group::new(Delimiter::Parenthesis, quote!($($t)*)) };
-    ([$($t:tt)*]) => { Group::new(Delimiter::Bracket, quote!($($t)*)) };
-    ({$($t:tt)*}) => { Group::new(Delimiter::Brace, quote!($($t)*)) };
-    (,) => { Punct::new(',', Spacing::Alone) };
-    (.) => { Punct::new('.', Spacing::Alone) };
-    (;) => { Punct::new(';', Spacing::Alone) };
-    (!) => { Punct::new('!', Spacing::Alone) };
-    (<) => { Punct::new('<', Spacing::Alone) };
-    (>) => { Punct::new('>', Spacing::Alone) };
-    (&) => { Punct::new('&', Spacing::Alone) };
-    (=) => { Punct::new('=', Spacing::Alone) };
-    ($i:ident) => { Ident::new(stringify!($i), Span::def_site()) };
-}
-
-macro_rules! quote_ts {
-    ((@ $($t:tt)*)) => { $($t)* };
-    (::) => {
-        [
-            TokenTree::from(Punct::new(':', Spacing::Joint)),
-            TokenTree::from(Punct::new(':', Spacing::Alone)),
-        ].iter()
-            .cloned()
-            .map(|mut x| {
-                x.set_span(Span::def_site());
-                x
-            })
-            .collect::<TokenStream>()
-    };
-    ($t:tt) => { TokenTree::from(quote_tt!($t)) };
-}
-
-/// Simpler version of the real `quote!` macro, implemented solely
-/// through `macro_rules`, for bootstrapping the real implementation
-/// (see the `quote` function), which does not have access to the
-/// real `quote!` macro due to the `proc_macro` crate not being
-/// able to depend on itself.
-///
-/// Note: supported tokens are a subset of the real `quote!`, but
-/// unquoting is different: instead of `$x`, this uses `(@ expr)`.
-macro_rules! quote {
-    () => { TokenStream::new() };
-    ($($t:tt)*) => {
-        [
-            $(TokenStream::from(quote_ts!($t)),)*
-        ].iter().cloned().collect::<TokenStream>()
-    };
-}
-
-/// Quote a `TokenStream` into a `TokenStream`.
-/// This is the actual implementation of the `quote!()` proc macro.
-///
-/// It is loaded by the compiler in `register_builtin_macros`.
-pub fn quote(stream: TokenStream) -> TokenStream {
-    if stream.is_empty() {
-        return quote!(super::TokenStream::new());
-    }
-    let proc_macro_crate = quote!(crate);
-    let mut after_dollar = false;
-    let tokens = stream
-        .into_iter()
-        .filter_map(|tree| {
-            if after_dollar {
-                after_dollar = false;
-                match tree {
-                    TokenTree::Ident(_) => {
-                        return Some(quote!(Into::<super::TokenStream>::into(
-                        Clone::clone(&(@ tree))),));
-                    }
-                    TokenTree::Punct(ref tt) if tt.as_char() == '$' => {}
-                    _ => panic!("`$` must be followed by an ident or `$` in `quote!`"),
-                }
-            } else if let TokenTree::Punct(ref tt) = tree {
-                if tt.as_char() == '$' {
-                    after_dollar = true;
-                    return None;
-                }
-            }
-
-            Some(quote!(super::TokenStream::from((@ match tree {
-                TokenTree::Punct(tt) => quote!(super::TokenTree::Punct(super::Punct::new(
-                    (@ TokenTree::from(Literal::character(tt.as_char()))),
-                    (@ match tt.spacing() {
-                        Spacing::Alone => quote!(super::Spacing::Alone),
-                        Spacing::Joint => quote!(super::Spacing::Joint),
-                    }),
-                ))),
-                TokenTree::Group(tt) => quote!(super::TokenTree::Group(super::Group::new(
-                    (@ match tt.delimiter() {
-                        Delimiter::Parenthesis => quote!(super::Delimiter::Parenthesis),
-                        Delimiter::Brace => quote!(super::Delimiter::Brace),
-                        Delimiter::Bracket => quote!(super::Delimiter::Bracket),
-                        Delimiter::None => quote!(super::Delimiter::None),
-                    }),
-                    (@ quote(tt.stream())),
-                ))),
-                TokenTree::Ident(tt) => quote!(super::TokenTree::Ident(super::Ident::new(
-                    (@ TokenTree::from(Literal::string(&tt.to_string()))),
-                    (@ quote_span(proc_macro_crate.clone(), tt.span())),
-                ))),
-                TokenTree::Literal(tt) => quote!(super::TokenTree::Literal({
-                    let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string())))
-                        .parse::<super::TokenStream>()
-                        .unwrap()
-                        .into_iter();
-                    if let (Some(super::TokenTree::Literal(mut lit)), None) =
-                        (iter.next(), iter.next())
-                    {
-                        lit.set_span((@ quote_span(proc_macro_crate.clone(), tt.span())));
-                        lit
-                    } else {
-                        unreachable!()
-                    }
-                }))
-            })),))
-        })
-        .collect::<TokenStream>();
-
-    if after_dollar {
-        panic!("unexpected trailing `$` in `quote!`");
-    }
-
-    quote!([(@ tokens)].iter().cloned().collect::<super::TokenStream>())
-}
-
-/// Quote a `Span` into a `TokenStream`.
-/// This is needed to implement a custom quoter.
-pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream {
-    let id = span.save_span();
-    quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id)))))
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
deleted file mode 100644
index 7e8e67856e9..00000000000
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
+++ /dev/null
@@ -1,792 +0,0 @@
-//! Rustc proc-macro server implementation with tt
-//!
-//! Based on idea from <https://github.com/fedochet/rust-proc-macro-expander>
-//! The lib-proc-macro server backend is `TokenStream`-agnostic, such that
-//! we could provide any TokenStream implementation.
-//! The original idea from fedochet is using proc-macro2 as backend,
-//! we use tt instead for better integration with RA.
-//!
-//! FIXME: No span and source file information is implemented yet
-
-use super::proc_macro::bridge::{self, server};
-
-use std::collections::HashMap;
-use std::hash::Hash;
-use std::iter::FromIterator;
-use std::ops::Bound;
-use std::{ascii, vec::IntoIter};
-
-type Group = tt::Subtree;
-type TokenTree = tt::TokenTree;
-type Punct = tt::Punct;
-type Spacing = tt::Spacing;
-type Literal = tt::Literal;
-type Span = tt::TokenId;
-
-#[derive(Debug, Default, Clone)]
-pub struct TokenStream {
-    pub token_trees: Vec<TokenTree>,
-}
-
-impl TokenStream {
-    pub fn new() -> Self {
-        TokenStream::default()
-    }
-
-    pub fn with_subtree(subtree: tt::Subtree) -> Self {
-        if subtree.delimiter.is_some() {
-            TokenStream { token_trees: vec![TokenTree::Subtree(subtree)] }
-        } else {
-            TokenStream { token_trees: subtree.token_trees }
-        }
-    }
-
-    pub fn into_subtree(self) -> tt::Subtree {
-        tt::Subtree { delimiter: None, token_trees: self.token_trees }
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.token_trees.is_empty()
-    }
-}
-
-/// Creates a token stream containing a single token tree.
-impl From<TokenTree> for TokenStream {
-    fn from(tree: TokenTree) -> TokenStream {
-        TokenStream { token_trees: vec![tree] }
-    }
-}
-
-/// Collects a number of token trees into a single stream.
-impl FromIterator<TokenTree> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
-        trees.into_iter().map(TokenStream::from).collect()
-    }
-}
-
-/// A "flattening" operation on token streams, collects token trees
-/// from multiple token streams into a single stream.
-impl FromIterator<TokenStream> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
-        let mut builder = TokenStreamBuilder::new();
-        streams.into_iter().for_each(|stream| builder.push(stream));
-        builder.build()
-    }
-}
-
-impl Extend<TokenTree> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
-        self.extend(trees.into_iter().map(TokenStream::from));
-    }
-}
-
-impl Extend<TokenStream> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
-        for item in streams {
-            for tkn in item {
-                match tkn {
-                    tt::TokenTree::Subtree(subtree) if subtree.delimiter.is_none() => {
-                        self.token_trees.extend(subtree.token_trees);
-                    }
-                    _ => {
-                        self.token_trees.push(tkn);
-                    }
-                }
-            }
-        }
-    }
-}
-
-#[derive(Clone)]
-pub struct SourceFile {
-    // FIXME stub
-}
-
-type Level = super::proc_macro::Level;
-type LineColumn = super::proc_macro::LineColumn;
-
-/// A structure representing a diagnostic message and associated children
-/// messages.
-#[derive(Clone, Debug)]
-pub struct Diagnostic {
-    level: Level,
-    message: String,
-    spans: Vec<Span>,
-    children: Vec<Diagnostic>,
-}
-
-impl Diagnostic {
-    /// Creates a new diagnostic with the given `level` and `message`.
-    pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
-        Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
-    }
-}
-
-// Rustc Server Ident has to be `Copyable`
-// We use a stub here for bypassing
-#[derive(Hash, Eq, PartialEq, Copy, Clone)]
-pub struct IdentId(u32);
-
-#[derive(Clone, Hash, Eq, PartialEq)]
-struct IdentData(tt::Ident);
-
-#[derive(Default)]
-struct IdentInterner {
-    idents: HashMap<IdentData, u32>,
-    ident_data: Vec<IdentData>,
-}
-
-impl IdentInterner {
-    fn intern(&mut self, data: &IdentData) -> u32 {
-        if let Some(index) = self.idents.get(data) {
-            return *index;
-        }
-
-        let index = self.idents.len() as u32;
-        self.ident_data.push(data.clone());
-        self.idents.insert(data.clone(), index);
-        index
-    }
-
-    fn get(&self, index: u32) -> &IdentData {
-        &self.ident_data[index as usize]
-    }
-
-    #[allow(unused)]
-    fn get_mut(&mut self, index: u32) -> &mut IdentData {
-        self.ident_data.get_mut(index as usize).expect("Should be consistent")
-    }
-}
-
-pub struct TokenStreamBuilder {
-    acc: TokenStream,
-}
-
-/// Public implementation details for the `TokenStream` type, such as iterators.
-pub mod token_stream {
-    use std::str::FromStr;
-
-    use super::{TokenStream, TokenTree};
-
-    /// An iterator over `TokenStream`'s `TokenTree`s.
-    /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
-    /// and returns whole groups as token trees.
-    impl IntoIterator for TokenStream {
-        type Item = TokenTree;
-        type IntoIter = super::IntoIter<TokenTree>;
-
-        fn into_iter(self) -> Self::IntoIter {
-            self.token_trees.into_iter()
-        }
-    }
-
-    type LexError = String;
-
-    /// Attempts to break the string into tokens and parse those tokens into a token stream.
-    /// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
-    /// or characters not existing in the language.
-    /// All tokens in the parsed stream get `Span::call_site()` spans.
-    ///
-    /// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
-    /// change these errors into `LexError`s later.
-    impl FromStr for TokenStream {
-        type Err = LexError;
-
-        fn from_str(src: &str) -> Result<TokenStream, LexError> {
-            let (subtree, _token_map) =
-                mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?;
-
-            let subtree = subtree_replace_token_ids_with_unspecified(subtree);
-            Ok(TokenStream::with_subtree(subtree))
-        }
-    }
-
-    impl ToString for TokenStream {
-        fn to_string(&self) -> String {
-            tt::pretty(&self.token_trees)
-        }
-    }
-
-    fn subtree_replace_token_ids_with_unspecified(subtree: tt::Subtree) -> tt::Subtree {
-        tt::Subtree {
-            delimiter: subtree
-                .delimiter
-                .map(|d| tt::Delimiter { id: tt::TokenId::unspecified(), ..d }),
-            token_trees: subtree
-                .token_trees
-                .into_iter()
-                .map(token_tree_replace_token_ids_with_unspecified)
-                .collect(),
-        }
-    }
-
-    fn token_tree_replace_token_ids_with_unspecified(tt: tt::TokenTree) -> tt::TokenTree {
-        match tt {
-            tt::TokenTree::Leaf(leaf) => {
-                tt::TokenTree::Leaf(leaf_replace_token_ids_with_unspecified(leaf))
-            }
-            tt::TokenTree::Subtree(subtree) => {
-                tt::TokenTree::Subtree(subtree_replace_token_ids_with_unspecified(subtree))
-            }
-        }
-    }
-
-    fn leaf_replace_token_ids_with_unspecified(leaf: tt::Leaf) -> tt::Leaf {
-        match leaf {
-            tt::Leaf::Literal(lit) => {
-                tt::Leaf::Literal(tt::Literal { id: tt::TokenId::unspecified(), ..lit })
-            }
-            tt::Leaf::Punct(punct) => {
-                tt::Leaf::Punct(tt::Punct { id: tt::TokenId::unspecified(), ..punct })
-            }
-            tt::Leaf::Ident(ident) => {
-                tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), ..ident })
-            }
-        }
-    }
-}
-
-impl TokenStreamBuilder {
-    fn new() -> TokenStreamBuilder {
-        TokenStreamBuilder { acc: TokenStream::new() }
-    }
-
-    fn push(&mut self, stream: TokenStream) {
-        self.acc.extend(stream.into_iter())
-    }
-
-    fn build(self) -> TokenStream {
-        self.acc
-    }
-}
-
-pub struct FreeFunctions;
-
-#[derive(Clone)]
-pub struct TokenStreamIter {
-    trees: IntoIter<TokenTree>,
-}
-
-#[derive(Default)]
-pub struct RustAnalyzer {
-    ident_interner: IdentInterner,
-    // FIXME: store span information here.
-}
-
-impl server::Types for RustAnalyzer {
-    type FreeFunctions = FreeFunctions;
-    type TokenStream = TokenStream;
-    type Ident = IdentId;
-    type Literal = Literal;
-    type SourceFile = SourceFile;
-    type Diagnostic = Diagnostic;
-    type Span = Span;
-    type MultiSpan = Vec<Span>;
-}
-
-impl server::FreeFunctions for RustAnalyzer {
-    fn track_env_var(&mut self, _var: &str, _value: Option<&str>) {
-        // FIXME: track env var accesses
-        // https://github.com/rust-lang/rust/pull/71858
-    }
-    fn track_path(&mut self, _path: &str) {}
-}
-
-impl server::TokenStream for RustAnalyzer {
-    fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
-        stream.is_empty()
-    }
-    fn from_str(&mut self, src: &str) -> Self::TokenStream {
-        use std::str::FromStr;
-
-        Self::TokenStream::from_str(src).expect("cannot parse string")
-    }
-    fn to_string(&mut self, stream: &Self::TokenStream) -> String {
-        stream.to_string()
-    }
-    fn from_token_tree(
-        &mut self,
-        tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>,
-    ) -> Self::TokenStream {
-        match tree {
-            bridge::TokenTree::Group(group) => {
-                let group = Group {
-                    delimiter: delim_to_internal(group.delimiter),
-                    token_trees: match group.stream {
-                        Some(stream) => stream.into_iter().collect(),
-                        None => Vec::new(),
-                    },
-                };
-                let tree = TokenTree::from(group);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-
-            bridge::TokenTree::Ident(IdentId(index)) => {
-                let IdentData(ident) = self.ident_interner.get(index).clone();
-                let ident: tt::Ident = ident;
-                let leaf = tt::Leaf::from(ident);
-                let tree = TokenTree::from(leaf);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-
-            bridge::TokenTree::Literal(literal) => {
-                let leaf = tt::Leaf::from(literal);
-                let tree = TokenTree::from(leaf);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-
-            bridge::TokenTree::Punct(p) => {
-                let punct = tt::Punct {
-                    char: p.ch as char,
-                    spacing: if p.joint { Spacing::Joint } else { Spacing::Alone },
-                    id: p.span,
-                };
-                let leaf = tt::Leaf::from(punct);
-                let tree = TokenTree::from(leaf);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-        }
-    }
-
-    fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
-        Ok(self_.clone())
-    }
-
-    fn concat_trees(
-        &mut self,
-        base: Option<Self::TokenStream>,
-        trees: Vec<bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>>,
-    ) -> Self::TokenStream {
-        let mut builder = TokenStreamBuilder::new();
-        if let Some(base) = base {
-            builder.push(base);
-        }
-        for tree in trees {
-            builder.push(self.from_token_tree(tree));
-        }
-        builder.build()
-    }
-
-    fn concat_streams(
-        &mut self,
-        base: Option<Self::TokenStream>,
-        streams: Vec<Self::TokenStream>,
-    ) -> Self::TokenStream {
-        let mut builder = TokenStreamBuilder::new();
-        if let Some(base) = base {
-            builder.push(base);
-        }
-        for stream in streams {
-            builder.push(stream);
-        }
-        builder.build()
-    }
-
-    fn into_trees(
-        &mut self,
-        stream: Self::TokenStream,
-    ) -> Vec<bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>> {
-        stream
-            .into_iter()
-            .map(|tree| match tree {
-                tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
-                    bridge::TokenTree::Ident(IdentId(self.ident_interner.intern(&IdentData(ident))))
-                }
-                tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => bridge::TokenTree::Literal(lit),
-                tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {
-                    bridge::TokenTree::Punct(bridge::Punct {
-                        ch: punct.char as u8,
-                        joint: punct.spacing == Spacing::Joint,
-                        span: punct.id,
-                    })
-                }
-                tt::TokenTree::Subtree(subtree) => bridge::TokenTree::Group(bridge::Group {
-                    delimiter: delim_to_external(subtree.delimiter),
-                    stream: if subtree.token_trees.is_empty() {
-                        None
-                    } else {
-                        Some(subtree.token_trees.into_iter().collect())
-                    },
-                    span: bridge::DelimSpan::from_single(
-                        subtree.delimiter.map_or(Span::unspecified(), |del| del.id),
-                    ),
-                }),
-            })
-            .collect()
-    }
-}
-
-fn delim_to_internal(d: bridge::Delimiter) -> Option<tt::Delimiter> {
-    let kind = match d {
-        bridge::Delimiter::Parenthesis => tt::DelimiterKind::Parenthesis,
-        bridge::Delimiter::Brace => tt::DelimiterKind::Brace,
-        bridge::Delimiter::Bracket => tt::DelimiterKind::Bracket,
-        bridge::Delimiter::None => return None,
-    };
-    Some(tt::Delimiter { id: tt::TokenId::unspecified(), kind })
-}
-
-fn delim_to_external(d: Option<tt::Delimiter>) -> bridge::Delimiter {
-    match d.map(|it| it.kind) {
-        Some(tt::DelimiterKind::Parenthesis) => bridge::Delimiter::Parenthesis,
-        Some(tt::DelimiterKind::Brace) => bridge::Delimiter::Brace,
-        Some(tt::DelimiterKind::Bracket) => bridge::Delimiter::Bracket,
-        None => bridge::Delimiter::None,
-    }
-}
-
-fn spacing_to_internal(spacing: bridge::Spacing) -> Spacing {
-    match spacing {
-        bridge::Spacing::Alone => Spacing::Alone,
-        bridge::Spacing::Joint => Spacing::Joint,
-    }
-}
-
-fn spacing_to_external(spacing: Spacing) -> bridge::Spacing {
-    match spacing {
-        Spacing::Alone => bridge::Spacing::Alone,
-        Spacing::Joint => bridge::Spacing::Joint,
-    }
-}
-
-impl server::Ident for RustAnalyzer {
-    fn new(&mut self, string: &str, span: Self::Span, _is_raw: bool) -> Self::Ident {
-        IdentId(self.ident_interner.intern(&IdentData(tt::Ident { text: string.into(), id: span })))
-    }
-
-    fn span(&mut self, ident: Self::Ident) -> Self::Span {
-        self.ident_interner.get(ident.0).0.id
-    }
-    fn with_span(&mut self, ident: Self::Ident, span: Self::Span) -> Self::Ident {
-        let data = self.ident_interner.get(ident.0);
-        let new = IdentData(tt::Ident { id: span, ..data.0.clone() });
-        IdentId(self.ident_interner.intern(&new))
-    }
-}
-
-impl server::Literal for RustAnalyzer {
-    fn debug_kind(&mut self, _literal: &Self::Literal) -> String {
-        // r-a: debug_kind and suffix are unsupported; corresponding client code has been changed to not call these.
-        // They must still be present to be ABI-compatible and work with upstream proc_macro.
-        "".to_owned()
-    }
-    fn from_str(&mut self, s: &str) -> Result<Self::Literal, ()> {
-        Ok(Literal { text: s.into(), id: tt::TokenId::unspecified() })
-    }
-    fn symbol(&mut self, literal: &Self::Literal) -> String {
-        literal.text.to_string()
-    }
-    fn suffix(&mut self, _literal: &Self::Literal) -> Option<String> {
-        None
-    }
-
-    fn to_string(&mut self, literal: &Self::Literal) -> String {
-        literal.to_string()
-    }
-
-    fn integer(&mut self, n: &str) -> Self::Literal {
-        let n = match n.parse::<i128>() {
-            Ok(n) => n.to_string(),
-            Err(_) => n.parse::<u128>().unwrap().to_string(),
-        };
-        Literal { text: n.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn typed_integer(&mut self, n: &str, kind: &str) -> Self::Literal {
-        macro_rules! def_suffixed_integer {
-            ($kind:ident, $($ty:ty),*) => {
-                match $kind {
-                    $(
-                        stringify!($ty) => {
-                            let n: $ty = n.parse().unwrap();
-                            format!(concat!("{}", stringify!($ty)), n)
-                        }
-                    )*
-                    _ => unimplemented!("unknown args for typed_integer: n {}, kind {}", n, $kind),
-                }
-            }
-        }
-
-        let text = def_suffixed_integer! {kind, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize};
-
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn float(&mut self, n: &str) -> Self::Literal {
-        let n: f64 = n.parse().unwrap();
-        let mut text = f64::to_string(&n);
-        if !text.contains('.') {
-            text += ".0"
-        }
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn f32(&mut self, n: &str) -> Self::Literal {
-        let n: f32 = n.parse().unwrap();
-        let text = format!("{}f32", n);
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn f64(&mut self, n: &str) -> Self::Literal {
-        let n: f64 = n.parse().unwrap();
-        let text = format!("{}f64", n);
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn string(&mut self, string: &str) -> Self::Literal {
-        let mut escaped = String::new();
-        for ch in string.chars() {
-            escaped.extend(ch.escape_debug());
-        }
-        Literal { text: format!("\"{}\"", escaped).into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn character(&mut self, ch: char) -> Self::Literal {
-        Literal { text: format!("'{}'", ch).into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal {
-        let string = bytes
-            .iter()
-            .cloned()
-            .flat_map(ascii::escape_default)
-            .map(Into::<char>::into)
-            .collect::<String>();
-
-        Literal { text: format!("b\"{}\"", string).into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn span(&mut self, literal: &Self::Literal) -> Self::Span {
-        literal.id
-    }
-
-    fn set_span(&mut self, literal: &mut Self::Literal, span: Self::Span) {
-        literal.id = span;
-    }
-
-    fn subspan(
-        &mut self,
-        _literal: &Self::Literal,
-        _start: Bound<usize>,
-        _end: Bound<usize>,
-    ) -> Option<Self::Span> {
-        // FIXME handle span
-        None
-    }
-}
-
-impl server::SourceFile for RustAnalyzer {
-    // FIXME these are all stubs
-    fn eq(&mut self, _file1: &Self::SourceFile, _file2: &Self::SourceFile) -> bool {
-        true
-    }
-    fn path(&mut self, _file: &Self::SourceFile) -> String {
-        String::new()
-    }
-    fn is_real(&mut self, _file: &Self::SourceFile) -> bool {
-        true
-    }
-}
-
-impl server::Diagnostic for RustAnalyzer {
-    fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
-        let mut diag = Diagnostic::new(level, msg);
-        diag.spans = spans;
-        diag
-    }
-
-    fn sub(
-        &mut self,
-        _diag: &mut Self::Diagnostic,
-        _level: Level,
-        _msg: &str,
-        _spans: Self::MultiSpan,
-    ) {
-        // FIXME handle diagnostic
-        //
-    }
-
-    fn emit(&mut self, _diag: Self::Diagnostic) {
-        // FIXME handle diagnostic
-        // diag.emit()
-    }
-}
-
-impl server::Span for RustAnalyzer {
-    fn debug(&mut self, span: Self::Span) -> String {
-        format!("{:?}", span.0)
-    }
-    fn source_file(&mut self, _span: Self::Span) -> Self::SourceFile {
-        SourceFile {}
-    }
-    fn save_span(&mut self, _span: Self::Span) -> usize {
-        // FIXME stub
-        0
-    }
-    fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
-        // FIXME stub
-        tt::TokenId::unspecified()
-    }
-    /// Recent feature, not yet in the proc_macro
-    ///
-    /// See PR:
-    /// https://github.com/rust-lang/rust/pull/55780
-    fn source_text(&mut self, _span: Self::Span) -> Option<String> {
-        None
-    }
-
-    fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
-        // FIXME handle span
-        None
-    }
-    fn source(&mut self, span: Self::Span) -> Self::Span {
-        // FIXME handle span
-        span
-    }
-    fn start(&mut self, _span: Self::Span) -> LineColumn {
-        // FIXME handle span
-        LineColumn { line: 0, column: 0 }
-    }
-    fn end(&mut self, _span: Self::Span) -> LineColumn {
-        // FIXME handle span
-        LineColumn { line: 0, column: 0 }
-    }
-    fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
-        // Just return the first span again, because some macros will unwrap the result.
-        Some(first)
-    }
-    fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
-        // FIXME handle span
-        tt::TokenId::unspecified()
-    }
-
-    fn after(&mut self, _self_: Self::Span) -> Self::Span {
-        tt::TokenId::unspecified()
-    }
-
-    fn before(&mut self, _self_: Self::Span) -> Self::Span {
-        tt::TokenId::unspecified()
-    }
-}
-
-impl server::MultiSpan for RustAnalyzer {
-    fn new(&mut self) -> Self::MultiSpan {
-        // FIXME handle span
-        vec![]
-    }
-
-    fn push(&mut self, other: &mut Self::MultiSpan, span: Self::Span) {
-        //TODP
-        other.push(span)
-    }
-}
-
-impl server::Server for RustAnalyzer {
-    fn globals(&mut self) -> bridge::ExpnGlobals<Self::Span> {
-        bridge::ExpnGlobals {
-            def_site: Span::unspecified(),
-            call_site: Span::unspecified(),
-            mixed_site: Span::unspecified(),
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::super::proc_macro::bridge::server::Literal;
-    use super::*;
-
-    #[test]
-    fn test_ra_server_literals() {
-        let mut srv = RustAnalyzer { ident_interner: IdentInterner::default() };
-        assert_eq!(srv.integer("1234").text, "1234");
-
-        assert_eq!(srv.typed_integer("12", "u8").text, "12u8");
-        assert_eq!(srv.typed_integer("255", "u16").text, "255u16");
-        assert_eq!(srv.typed_integer("1234", "u32").text, "1234u32");
-        assert_eq!(srv.typed_integer("15846685", "u64").text, "15846685u64");
-        assert_eq!(srv.typed_integer("15846685258", "u128").text, "15846685258u128");
-        assert_eq!(srv.typed_integer("156788984", "usize").text, "156788984usize");
-        assert_eq!(srv.typed_integer("127", "i8").text, "127i8");
-        assert_eq!(srv.typed_integer("255", "i16").text, "255i16");
-        assert_eq!(srv.typed_integer("1234", "i32").text, "1234i32");
-        assert_eq!(srv.typed_integer("15846685", "i64").text, "15846685i64");
-        assert_eq!(srv.typed_integer("15846685258", "i128").text, "15846685258i128");
-        assert_eq!(srv.float("0").text, "0.0");
-        assert_eq!(srv.float("15684.5867").text, "15684.5867");
-        assert_eq!(srv.f32("15684.58").text, "15684.58f32");
-        assert_eq!(srv.f64("15684.58").text, "15684.58f64");
-
-        assert_eq!(srv.string("hello_world").text, "\"hello_world\"");
-        assert_eq!(srv.character('c').text, "'c'");
-        assert_eq!(srv.byte_string(b"1234586\x88").text, "b\"1234586\\x88\"");
-
-        // u128::max
-        assert_eq!(
-            srv.integer("340282366920938463463374607431768211455").text,
-            "340282366920938463463374607431768211455"
-        );
-        // i128::min
-        assert_eq!(
-            srv.integer("-170141183460469231731687303715884105728").text,
-            "-170141183460469231731687303715884105728"
-        );
-    }
-
-    #[test]
-    fn test_ra_server_to_string() {
-        let s = TokenStream {
-            token_trees: vec![
-                tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                    text: "struct".into(),
-                    id: tt::TokenId::unspecified(),
-                })),
-                tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                    text: "T".into(),
-                    id: tt::TokenId::unspecified(),
-                })),
-                tt::TokenTree::Subtree(tt::Subtree {
-                    delimiter: Some(tt::Delimiter {
-                        id: tt::TokenId::unspecified(),
-                        kind: tt::DelimiterKind::Brace,
-                    }),
-                    token_trees: vec![],
-                }),
-            ],
-        };
-
-        assert_eq!(s.to_string(), "struct T {}");
-    }
-
-    #[test]
-    fn test_ra_server_from_str() {
-        use std::str::FromStr;
-        let subtree_paren_a = tt::TokenTree::Subtree(tt::Subtree {
-            delimiter: Some(tt::Delimiter {
-                id: tt::TokenId::unspecified(),
-                kind: tt::DelimiterKind::Parenthesis,
-            }),
-            token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                text: "a".into(),
-                id: tt::TokenId::unspecified(),
-            }))],
-        });
-
-        let t1 = TokenStream::from_str("(a)").unwrap();
-        assert_eq!(t1.token_trees.len(), 1);
-        assert_eq!(t1.token_trees[0], subtree_paren_a);
-
-        let t2 = TokenStream::from_str("(a);").unwrap();
-        assert_eq!(t2.token_trees.len(), 2);
-        assert_eq!(t2.token_trees[0], subtree_paren_a);
-
-        let underscore = TokenStream::from_str("_").unwrap();
-        assert_eq!(
-            underscore.token_trees[0],
-            tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                text: "_".into(),
-                id: tt::TokenId::unspecified(),
-            }))
-        );
-    }
-}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
index 46882845a80..52eb7ce17d6 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
@@ -20,7 +20,7 @@ use token_stream::TokenStreamBuilder;
 mod symbol;
 pub use symbol::*;
 
-use std::{iter::FromIterator, ops::Bound};
+use std::ops::Bound;
 
 type Group = tt::Subtree;
 type TokenTree = tt::TokenTree;
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
index 705d09ea945..f7d3a30919e 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
@@ -25,7 +25,6 @@
 
 mod abi_1_58;
 mod abi_1_63;
-mod abi_1_64;
 #[cfg(feature = "sysroot-abi")]
 mod abi_sysroot;
 
@@ -34,12 +33,11 @@ include!(concat!(env!("OUT_DIR"), "/rustc_version.rs"));
 
 // Used by `test/utils.rs`
 #[cfg(test)]
-pub(crate) use abi_1_64::TokenStream as TestTokenStream;
+pub(crate) use abi_1_63::TokenStream as TestTokenStream;
 
 use super::dylib::LoadProcMacroDylibError;
 pub(crate) use abi_1_58::Abi as Abi_1_58;
 pub(crate) use abi_1_63::Abi as Abi_1_63;
-pub(crate) use abi_1_64::Abi as Abi_1_64;
 #[cfg(feature = "sysroot-abi")]
 pub(crate) use abi_sysroot::Abi as Abi_Sysroot;
 use libloading::Library;
@@ -58,7 +56,6 @@ impl PanicMessage {
 pub(crate) enum Abi {
     Abi1_58(Abi_1_58),
     Abi1_63(Abi_1_63),
-    Abi1_64(Abi_1_64),
     #[cfg(feature = "sysroot-abi")]
     AbiSysroot(Abi_Sysroot),
 }
@@ -120,10 +117,6 @@ impl Abi {
                 let inner = unsafe { Abi_1_63::from_lib(lib, symbol_name) }?;
                 Ok(Abi::Abi1_63(inner))
             }
-            (1, 64..) => {
-                let inner = unsafe { Abi_1_64::from_lib(lib, symbol_name) }?;
-                Ok(Abi::Abi1_64(inner))
-            }
             _ => Err(LoadProcMacroDylibError::UnsupportedABI),
         }
     }
@@ -137,7 +130,6 @@ impl Abi {
         match self {
             Self::Abi1_58(abi) => abi.expand(macro_name, macro_body, attributes),
             Self::Abi1_63(abi) => abi.expand(macro_name, macro_body, attributes),
-            Self::Abi1_64(abi) => abi.expand(macro_name, macro_body, attributes),
             #[cfg(feature = "sysroot-abi")]
             Self::AbiSysroot(abi) => abi.expand(macro_name, macro_body, attributes),
         }
@@ -147,7 +139,6 @@ impl Abi {
         match self {
             Self::Abi1_58(abi) => abi.list_macros(),
             Self::Abi1_63(abi) => abi.list_macros(),
-            Self::Abi1_64(abi) => abi.list_macros(),
             #[cfg(feature = "sysroot-abi")]
             Self::AbiSysroot(abi) => abi.list_macros(),
         }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
index 2b6c070fece..7aba74e5396 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
@@ -1,7 +1,6 @@
 //! Handles dynamic library loading for proc macro
 
 use std::{
-    convert::TryInto,
     fmt,
     fs::File,
     io,
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
index 07222907f08..6339d56d017 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
@@ -19,7 +19,7 @@ fn test_derive_error() {
         expect![[r##"
             SUBTREE $
               IDENT   compile_error 4294967295
-              PUNCH   ! [alone] 4294967295
+              PUNCH   ! [joint] 4294967295
               SUBTREE () 4294967295
                 LITERAL "#[derive(DeriveError)] struct S ;" 4294967295
               PUNCH   ; [alone] 4294967295"##]],
@@ -109,7 +109,7 @@ fn test_fn_like_macro_clone_literals() {
               PUNCH   , [alone] 4294967295
               LITERAL 2_u32 4294967295
               PUNCH   , [alone] 4294967295
-              PUNCH   - [alone] 4294967295
+              PUNCH   - [joint] 4294967295
               LITERAL 4i64 4294967295
               PUNCH   , [alone] 4294967295
               LITERAL 3.14f32 4294967295
@@ -130,7 +130,7 @@ fn test_attr_macro() {
         expect![[r##"
             SUBTREE $
               IDENT   compile_error 4294967295
-              PUNCH   ! [alone] 4294967295
+              PUNCH   ! [joint] 4294967295
               SUBTREE () 4294967295
                 LITERAL "#[attr_error(some arguments)] mod m {}" 4294967295
               PUNCH   ; [alone] 4294967295"##]],
diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
index ee7f8339a76..84e772d1684 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
@@ -12,6 +12,7 @@ use cargo_metadata::{camino::Utf8Path, Message};
 use la_arena::ArenaMap;
 use paths::AbsPathBuf;
 use rustc_hash::FxHashMap;
+use semver::Version;
 use serde::Deserialize;
 
 use crate::{cfg_flag::CfgFlag, CargoConfig, CargoWorkspace, Package};
@@ -77,9 +78,32 @@ impl WorkspaceBuildScripts {
         config: &CargoConfig,
         workspace: &CargoWorkspace,
         progress: &dyn Fn(String),
+        toolchain: &Option<Version>,
     ) -> io::Result<WorkspaceBuildScripts> {
-        let mut cmd = Self::build_command(config);
+        const RUST_1_62: Version = Version::new(1, 62, 0);
 
+        match Self::run_(Self::build_command(config), config, workspace, progress) {
+            Ok(WorkspaceBuildScripts { error: Some(error), .. })
+                if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
+            {
+                // building build scripts failed, attempt to build with --keep-going so
+                // that we potentially get more build data
+                let mut cmd = Self::build_command(config);
+                cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
+                let mut res = Self::run_(cmd, config, workspace, progress)?;
+                res.error = Some(error);
+                Ok(res)
+            }
+            res => res,
+        }
+    }
+
+    fn run_(
+        mut cmd: Command,
+        config: &CargoConfig,
+        workspace: &CargoWorkspace,
+        progress: &dyn Fn(String),
+    ) -> io::Result<WorkspaceBuildScripts> {
         if config.wrap_rustc_in_build_scripts {
             // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
             // that to compile only proc macros and build scripts during the initial
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index e304a59c018..8d0fa757c2e 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -28,6 +28,7 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGr
         rustc: None,
         rustc_cfg: Vec::new(),
         cfg_overrides,
+        toolchain: None,
     };
     to_crate_graph(project_workspace)
 }
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index b144006b44e..daabb299f76 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -12,6 +12,7 @@ use base_db::{
 use cfg::{CfgDiff, CfgOptions};
 use paths::{AbsPath, AbsPathBuf};
 use rustc_hash::{FxHashMap, FxHashSet};
+use semver::Version;
 use stdx::always;
 
 use crate::{
@@ -77,6 +78,7 @@ pub enum ProjectWorkspace {
         /// different target.
         rustc_cfg: Vec<CfgFlag>,
         cfg_overrides: CfgOverrides,
+        toolchain: Option<Version>,
     },
     /// Project workspace was manually specified using a `rust-project.json` file.
     Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
@@ -105,6 +107,7 @@ impl fmt::Debug for ProjectWorkspace {
                 rustc,
                 rustc_cfg,
                 cfg_overrides,
+                toolchain,
             } => f
                 .debug_struct("Cargo")
                 .field("root", &cargo.workspace_root().file_name())
@@ -116,6 +119,7 @@ impl fmt::Debug for ProjectWorkspace {
                 )
                 .field("n_rustc_cfg", &rustc_cfg.len())
                 .field("n_cfg_overrides", &cfg_overrides.len())
+                .field("toolchain", &toolchain)
                 .finish(),
             ProjectWorkspace::Json { project, sysroot, rustc_cfg } => {
                 let mut debug_struct = f.debug_struct("Json");
@@ -160,6 +164,9 @@ impl ProjectWorkspace {
                     cmd.arg("--version");
                     cmd
                 })?;
+                let toolchain = cargo_version
+                    .get("cargo ".len()..)
+                    .and_then(|it| Version::parse(it.split_whitespace().next()?).ok());
 
                 let meta = CargoWorkspace::fetch_metadata(
                     &cargo_toml,
@@ -169,9 +176,9 @@ impl ProjectWorkspace {
                 )
                 .with_context(|| {
                     format!(
-                        "Failed to read Cargo metadata from Cargo.toml file {}, {}",
+                        "Failed to read Cargo metadata from Cargo.toml file {}, {:?}",
                         cargo_toml.display(),
-                        cargo_version
+                        toolchain
                     )
                 })?;
                 let cargo = CargoWorkspace::new(meta);
@@ -219,6 +226,7 @@ impl ProjectWorkspace {
                     rustc,
                     rustc_cfg,
                     cfg_overrides,
+                    toolchain,
                 }
             }
         };
@@ -271,8 +279,8 @@ impl ProjectWorkspace {
         progress: &dyn Fn(String),
     ) -> Result<WorkspaceBuildScripts> {
         match self {
-            ProjectWorkspace::Cargo { cargo, .. } => {
-                WorkspaceBuildScripts::run(config, cargo, progress).with_context(|| {
+            ProjectWorkspace::Cargo { cargo, toolchain, .. } => {
+                WorkspaceBuildScripts::run(config, cargo, progress, toolchain).with_context(|| {
                     format!("Failed to run build scripts for {}", &cargo.workspace_root().display())
                 })
             }
@@ -320,6 +328,7 @@ impl ProjectWorkspace {
                 rustc_cfg: _,
                 cfg_overrides: _,
                 build_scripts,
+                toolchain: _,
             } => {
                 cargo
                     .packages()
@@ -425,6 +434,7 @@ impl ProjectWorkspace {
                 rustc_cfg,
                 cfg_overrides,
                 build_scripts,
+                toolchain: _,
             } => cargo_to_crate_graph(
                 rustc_cfg.clone(),
                 cfg_overrides,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
index 2f6d4706d87..38e9c7dd7e1 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/rustc_wrapper.rs
@@ -17,6 +17,11 @@ pub(crate) fn run_rustc_skipping_cargo_checking(
     rustc_executable: OsString,
     args: Vec<OsString>,
 ) -> io::Result<ExitCode> {
+    // `CARGO_CFG_TARGET_ARCH` is only set by cargo when executing build scripts
+    // We don't want to exit out checks unconditionally with success if a build
+    // script tries to invoke checks themselves
+    // See https://github.com/rust-lang/rust-analyzer/issues/12973 for context
+    let not_invoked_by_build_script = std::env::var_os("CARGO_CFG_TARGET_ARCH").is_none();
     let is_cargo_check = args.iter().any(|arg| {
         let arg = arg.to_string_lossy();
         // `cargo check` invokes `rustc` with `--emit=metadata` argument.
@@ -29,7 +34,7 @@ pub(crate) fn run_rustc_skipping_cargo_checking(
         //            The default output filename is CRATE_NAME.rmeta.
         arg.starts_with("--emit=") && arg.contains("metadata") && !arg.contains("link")
     });
-    if is_cargo_check {
+    if not_invoked_by_build_script && is_cargo_check {
         return Ok(ExitCode(Some(0)));
     }
     run_rustc(rustc_executable, args)
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
index 52511ceb580..247007db0a7 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -43,7 +43,7 @@ impl flags::Diagnostics {
                 println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id));
                 for diagnostic in analysis
                     .diagnostics(
-                        &DiagnosticsConfig::default(),
+                        &DiagnosticsConfig::test_sample(),
                         AssistResolveStrategy::None,
                         file_id,
                     )
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
index 19907ebddb6..080e2fb4438 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
@@ -10,6 +10,10 @@ xflags::xflags! {
     src "./src/cli/flags.rs"
 
     /// LSP server for the Rust programming language.
+    ///
+    /// Subcommands and their flags do not provide any stability guarantees and may be removed or
+    /// changed without notice. Top-level flags that are not are marked as [Unstable] provide
+    /// backwards-compatibility and may be relied on.
     cmd rust-analyzer {
         /// Verbosity level, can be repeated multiple times.
         repeated -v, --verbose
@@ -21,7 +25,7 @@ xflags::xflags! {
         /// Flush log records to the file immediately.
         optional --no-log-buffering
 
-        /// Wait until a debugger is attached to (requires debug build).
+        /// [Unstable] Wait until a debugger is attached to (requires debug build).
         optional --wait-dbg
 
         default cmd lsp-server {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index ac0fdf85a77..1629c1dd328 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -881,6 +881,7 @@ impl Config {
                 ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
                 ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
             },
+            insert_use: self.insert_use_config(),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
index cff4bd7f66a..74689fd8757 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -512,7 +512,7 @@ fn clippy_code_description(code: Option<&str>) -> Option<lsp_types::CodeDescript
 #[cfg(test)]
 #[cfg(not(windows))]
 mod tests {
-    use std::{convert::TryInto, path::Path};
+    use std::path::Path;
 
     use crate::{config::Config, global_state::GlobalState};
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
index 47daa732d5d..943d043bc19 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
@@ -1320,8 +1320,7 @@ pub(crate) fn publish_diagnostics(
                 .unwrap(),
             }),
             source: Some("rust-analyzer".to_string()),
-            // https://github.com/rust-lang/rust-analyzer/issues/11404
-            message: if !d.message.is_empty() { d.message } else { " ".to_string() },
+            message: d.message,
             related_information: None,
             tags: if d.unused { Some(vec![DiagnosticTag::UNNECESSARY]) } else { None },
             data: None,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index b504c248782..77419998249 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -9,6 +9,7 @@ use std::{
 
 use always_assert::always;
 use crossbeam_channel::{select, Receiver};
+use flycheck::FlycheckHandle;
 use ide_db::base_db::{SourceDatabase, SourceDatabaseExt, VfsPath};
 use itertools::Itertools;
 use lsp_server::{Connection, Notification, Request};
@@ -205,81 +206,14 @@ impl GlobalState {
                 }
                 lsp_server::Message::Response(resp) => self.complete_request(resp),
             },
-            Event::Task(mut task) => {
+            Event::Task(task) => {
                 let _p = profile::span("GlobalState::handle_event/task");
                 let mut prime_caches_progress = Vec::new();
-                loop {
-                    match task {
-                        Task::Response(response) => self.respond(response),
-                        Task::Retry(req) => self.on_request(req),
-                        Task::Diagnostics(diagnostics_per_file) => {
-                            for (file_id, diagnostics) in diagnostics_per_file {
-                                self.diagnostics.set_native_diagnostics(file_id, diagnostics)
-                            }
-                        }
-                        Task::PrimeCaches(progress) => match progress {
-                            PrimeCachesProgress::Begin => prime_caches_progress.push(progress),
-                            PrimeCachesProgress::Report(_) => {
-                                match prime_caches_progress.last_mut() {
-                                    Some(last @ PrimeCachesProgress::Report(_)) => {
-                                        // Coalesce subsequent update events.
-                                        *last = progress;
-                                    }
-                                    _ => prime_caches_progress.push(progress),
-                                }
-                            }
-                            PrimeCachesProgress::End { .. } => prime_caches_progress.push(progress),
-                        },
-                        Task::FetchWorkspace(progress) => {
-                            let (state, msg) = match progress {
-                                ProjectWorkspaceProgress::Begin => (Progress::Begin, None),
-                                ProjectWorkspaceProgress::Report(msg) => {
-                                    (Progress::Report, Some(msg))
-                                }
-                                ProjectWorkspaceProgress::End(workspaces) => {
-                                    self.fetch_workspaces_queue.op_completed(workspaces);
 
-                                    let old = Arc::clone(&self.workspaces);
-                                    self.switch_workspaces("fetched workspace".to_string());
-                                    let workspaces_updated = !Arc::ptr_eq(&old, &self.workspaces);
-
-                                    if self.config.run_build_scripts() && workspaces_updated {
-                                        self.fetch_build_data_queue
-                                            .request_op(format!("workspace updated"));
-                                    }
-
-                                    (Progress::End, None)
-                                }
-                            };
-
-                            self.report_progress("Fetching", state, msg, None);
-                        }
-                        Task::FetchBuildData(progress) => {
-                            let (state, msg) = match progress {
-                                BuildDataProgress::Begin => (Some(Progress::Begin), None),
-                                BuildDataProgress::Report(msg) => {
-                                    (Some(Progress::Report), Some(msg))
-                                }
-                                BuildDataProgress::End(build_data_result) => {
-                                    self.fetch_build_data_queue.op_completed(build_data_result);
-
-                                    self.switch_workspaces("fetched build data".to_string());
-
-                                    (Some(Progress::End), None)
-                                }
-                            };
-
-                            if let Some(state) = state {
-                                self.report_progress("Loading", state, msg, None);
-                            }
-                        }
-                    }
-
-                    // Coalesce multiple task events into one loop turn
-                    task = match self.task_pool.receiver.try_recv() {
-                        Ok(task) => task,
-                        Err(_) => break,
-                    };
+                self.handle_task(&mut prime_caches_progress, task);
+                // Coalesce multiple task events into one loop turn
+                while let Ok(task) = self.task_pool.receiver.try_recv() {
+                    self.handle_task(&mut prime_caches_progress, task);
                 }
 
                 for progress in prime_caches_progress {
@@ -326,119 +260,20 @@ impl GlobalState {
                     self.report_progress("Indexing", state, message, Some(fraction));
                 }
             }
-            Event::Vfs(mut task) => {
+            Event::Vfs(message) => {
                 let _p = profile::span("GlobalState::handle_event/vfs");
-                loop {
-                    match task {
-                        vfs::loader::Message::Loaded { files } => {
-                            let vfs = &mut self.vfs.write().0;
-                            for (path, contents) in files {
-                                let path = VfsPath::from(path);
-                                if !self.mem_docs.contains(&path) {
-                                    vfs.set_file_contents(path, contents);
-                                }
-                            }
-                        }
-                        vfs::loader::Message::Progress { n_total, n_done, config_version } => {
-                            always!(config_version <= self.vfs_config_version);
-
-                            self.vfs_progress_config_version = config_version;
-                            self.vfs_progress_n_total = n_total;
-                            self.vfs_progress_n_done = n_done;
-
-                            let state = if n_done == 0 {
-                                Progress::Begin
-                            } else if n_done < n_total {
-                                Progress::Report
-                            } else {
-                                assert_eq!(n_done, n_total);
-                                Progress::End
-                            };
-                            self.report_progress(
-                                "Roots Scanned",
-                                state,
-                                Some(format!("{}/{}", n_done, n_total)),
-                                Some(Progress::fraction(n_done, n_total)),
-                            )
-                        }
-                    }
-                    // Coalesce many VFS event into a single loop turn
-                    task = match self.loader.receiver.try_recv() {
-                        Ok(task) => task,
-                        Err(_) => break,
-                    }
+                self.handle_vfs_msg(message);
+                // Coalesce many VFS event into a single loop turn
+                while let Ok(message) = self.loader.receiver.try_recv() {
+                    self.handle_vfs_msg(message);
                 }
             }
-            Event::Flycheck(mut task) => {
+            Event::Flycheck(message) => {
                 let _p = profile::span("GlobalState::handle_event/flycheck");
-                loop {
-                    match task {
-                        flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
-                            let snap = self.snapshot();
-                            let diagnostics =
-                                crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
-                                    &self.config.diagnostics_map(),
-                                    &diagnostic,
-                                    &workspace_root,
-                                    &snap,
-                                );
-                            for diag in diagnostics {
-                                match url_to_file_id(&self.vfs.read().0, &diag.url) {
-                                    Ok(file_id) => self.diagnostics.add_check_diagnostic(
-                                        id,
-                                        file_id,
-                                        diag.diagnostic,
-                                        diag.fix,
-                                    ),
-                                    Err(err) => {
-                                        tracing::error!(
-                                            "File with cargo diagnostic not found in VFS: {}",
-                                            err
-                                        );
-                                    }
-                                };
-                            }
-                        }
-
-                        flycheck::Message::Progress { id, progress } => {
-                            let (state, message) = match progress {
-                                flycheck::Progress::DidStart => {
-                                    self.diagnostics.clear_check(id);
-                                    (Progress::Begin, None)
-                                }
-                                flycheck::Progress::DidCheckCrate(target) => {
-                                    (Progress::Report, Some(target))
-                                }
-                                flycheck::Progress::DidCancel => (Progress::End, None),
-                                flycheck::Progress::DidFinish(result) => {
-                                    if let Err(err) = result {
-                                        self.show_and_log_error(
-                                            "cargo check failed".to_string(),
-                                            Some(err.to_string()),
-                                        );
-                                    }
-                                    (Progress::End, None)
-                                }
-                            };
-
-                            // When we're running multiple flychecks, we have to include a disambiguator in
-                            // the title, or the editor complains. Note that this is a user-facing string.
-                            let title = if self.flycheck.len() == 1 {
-                                match self.config.flycheck() {
-                                    Some(config) => format!("{}", config),
-                                    None => "cargo check".to_string(),
-                                }
-                            } else {
-                                format!("cargo check (#{})", id + 1)
-                            };
-                            self.report_progress(&title, state, message, None);
-                        }
-                    }
-                    // Coalesce many flycheck updates into a single loop turn
-                    task = match self.flycheck_receiver.try_recv() {
-                        Ok(task) => task,
-                        Err(_) => break,
-                    }
+                self.handle_flycheck_msg(message);
+                // Coalesce many flycheck updates into a single loop turn
+                while let Ok(message) = self.flycheck_receiver.try_recv() {
+                    self.handle_flycheck_msg(message);
                 }
             }
         }
@@ -447,13 +282,13 @@ impl GlobalState {
         let memdocs_added_or_removed = self.mem_docs.take_changes();
 
         if self.is_quiescent() {
-            if !was_quiescent
-                && !self.fetch_workspaces_queue.op_requested()
-                && !self.fetch_build_data_queue.op_requested()
-            {
-                for flycheck in &self.flycheck {
-                    flycheck.update();
-                }
+            let became_quiescent = !(was_quiescent
+                || self.fetch_workspaces_queue.op_requested()
+                || self.fetch_build_data_queue.op_requested());
+
+            if became_quiescent {
+                // Project has loaded properly, kick off initial flycheck
+                self.flycheck.iter().for_each(FlycheckHandle::update);
                 if self.config.prefill_caches() {
                     self.prime_caches_queue.request_op("became quiescent".to_string());
                 }
@@ -492,28 +327,15 @@ impl GlobalState {
                     continue;
                 }
 
-                let url = file_id_to_url(&self.vfs.read().0, file_id);
-                let mut diagnostics =
+                let uri = file_id_to_url(&self.vfs.read().0, file_id);
+                let diagnostics =
                     self.diagnostics.diagnostics_for(file_id).cloned().collect::<Vec<_>>();
-                // https://github.com/rust-lang/rust-analyzer/issues/11404
-                for d in &mut diagnostics {
-                    if d.message.is_empty() {
-                        d.message = " ".to_string();
-                    }
-                    if let Some(rds) = d.related_information.as_mut() {
-                        for rd in rds {
-                            if rd.message.is_empty() {
-                                rd.message = " ".to_string();
-                            }
-                        }
-                    }
-                }
-                let version = from_proto::vfs_path(&url)
+                let version = from_proto::vfs_path(&uri)
                     .map(|path| self.mem_docs.get(&path).map(|it| it.version))
                     .unwrap_or_default();
 
                 self.send_notification::<lsp_types::notification::PublishDiagnostics>(
-                    lsp_types::PublishDiagnosticsParams { uri: url, diagnostics, version },
+                    lsp_types::PublishDiagnosticsParams { uri, diagnostics, version },
                 );
             }
         }
@@ -575,11 +397,171 @@ impl GlobalState {
         Ok(())
     }
 
+    fn handle_task(&mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task) {
+        match task {
+            Task::Response(response) => self.respond(response),
+            Task::Retry(req) => self.on_request(req),
+            Task::Diagnostics(diagnostics_per_file) => {
+                for (file_id, diagnostics) in diagnostics_per_file {
+                    self.diagnostics.set_native_diagnostics(file_id, diagnostics)
+                }
+            }
+            Task::PrimeCaches(progress) => match progress {
+                PrimeCachesProgress::Begin => prime_caches_progress.push(progress),
+                PrimeCachesProgress::Report(_) => {
+                    match prime_caches_progress.last_mut() {
+                        Some(last @ PrimeCachesProgress::Report(_)) => {
+                            // Coalesce subsequent update events.
+                            *last = progress;
+                        }
+                        _ => prime_caches_progress.push(progress),
+                    }
+                }
+                PrimeCachesProgress::End { .. } => prime_caches_progress.push(progress),
+            },
+            Task::FetchWorkspace(progress) => {
+                let (state, msg) = match progress {
+                    ProjectWorkspaceProgress::Begin => (Progress::Begin, None),
+                    ProjectWorkspaceProgress::Report(msg) => (Progress::Report, Some(msg)),
+                    ProjectWorkspaceProgress::End(workspaces) => {
+                        self.fetch_workspaces_queue.op_completed(workspaces);
+
+                        let old = Arc::clone(&self.workspaces);
+                        self.switch_workspaces("fetched workspace".to_string());
+                        let workspaces_updated = !Arc::ptr_eq(&old, &self.workspaces);
+
+                        if self.config.run_build_scripts() && workspaces_updated {
+                            self.fetch_build_data_queue.request_op(format!("workspace updated"));
+                        }
+
+                        (Progress::End, None)
+                    }
+                };
+
+                self.report_progress("Fetching", state, msg, None);
+            }
+            Task::FetchBuildData(progress) => {
+                let (state, msg) = match progress {
+                    BuildDataProgress::Begin => (Some(Progress::Begin), None),
+                    BuildDataProgress::Report(msg) => (Some(Progress::Report), Some(msg)),
+                    BuildDataProgress::End(build_data_result) => {
+                        self.fetch_build_data_queue.op_completed(build_data_result);
+
+                        self.switch_workspaces("fetched build data".to_string());
+
+                        (Some(Progress::End), None)
+                    }
+                };
+
+                if let Some(state) = state {
+                    self.report_progress("Loading", state, msg, None);
+                }
+            }
+        }
+    }
+
+    fn handle_vfs_msg(&mut self, message: vfs::loader::Message) {
+        match message {
+            vfs::loader::Message::Loaded { files } => {
+                let vfs = &mut self.vfs.write().0;
+                for (path, contents) in files {
+                    let path = VfsPath::from(path);
+                    if !self.mem_docs.contains(&path) {
+                        vfs.set_file_contents(path, contents);
+                    }
+                }
+            }
+            vfs::loader::Message::Progress { n_total, n_done, config_version } => {
+                always!(config_version <= self.vfs_config_version);
+
+                self.vfs_progress_config_version = config_version;
+                self.vfs_progress_n_total = n_total;
+                self.vfs_progress_n_done = n_done;
+
+                let state = if n_done == 0 {
+                    Progress::Begin
+                } else if n_done < n_total {
+                    Progress::Report
+                } else {
+                    assert_eq!(n_done, n_total);
+                    Progress::End
+                };
+                self.report_progress(
+                    "Roots Scanned",
+                    state,
+                    Some(format!("{}/{}", n_done, n_total)),
+                    Some(Progress::fraction(n_done, n_total)),
+                )
+            }
+        }
+    }
+
+    fn handle_flycheck_msg(&mut self, message: flycheck::Message) {
+        match message {
+            flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
+                let snap = self.snapshot();
+                let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
+                    &self.config.diagnostics_map(),
+                    &diagnostic,
+                    &workspace_root,
+                    &snap,
+                );
+                for diag in diagnostics {
+                    match url_to_file_id(&self.vfs.read().0, &diag.url) {
+                        Ok(file_id) => self.diagnostics.add_check_diagnostic(
+                            id,
+                            file_id,
+                            diag.diagnostic,
+                            diag.fix,
+                        ),
+                        Err(err) => {
+                            tracing::error!("File with cargo diagnostic not found in VFS: {}", err);
+                        }
+                    };
+                }
+            }
+
+            flycheck::Message::Progress { id, progress } => {
+                let (state, message) = match progress {
+                    flycheck::Progress::DidStart => {
+                        self.diagnostics.clear_check(id);
+                        (Progress::Begin, None)
+                    }
+                    flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
+                    flycheck::Progress::DidCancel => (Progress::End, None),
+                    flycheck::Progress::DidFinish(result) => {
+                        if let Err(err) = result {
+                            self.show_and_log_error(
+                                "cargo check failed".to_string(),
+                                Some(err.to_string()),
+                            );
+                        }
+                        (Progress::End, None)
+                    }
+                };
+
+                // When we're running multiple flychecks, we have to include a disambiguator in
+                // the title, or the editor complains. Note that this is a user-facing string.
+                let title = if self.flycheck.len() == 1 {
+                    match self.config.flycheck() {
+                        Some(config) => format!("{}", config),
+                        None => "cargo check".to_string(),
+                    }
+                } else {
+                    format!("cargo check (#{})", id + 1)
+                };
+                self.report_progress(&title, state, message, None);
+            }
+        }
+    }
+
+    /// Registers and handles a request. This should only be called once per incoming request.
     fn on_new_request(&mut self, request_received: Instant, req: Request) {
         self.register_request(&req, request_received);
         self.on_request(req);
     }
 
+    /// Handles a request.
     fn on_request(&mut self, req: Request) {
         if self.shutdown_requested {
             self.respond(lsp_server::Response::new_err(
@@ -670,6 +652,7 @@ impl GlobalState {
             .finish();
     }
 
+    /// Handles an incoming notification.
     fn on_notification(&mut self, not: Notification) -> Result<()> {
         NotificationDispatcher { not: Some(not), global_state: self }
             .on::<lsp_types::notification::Cancel>(|this, params| {
@@ -743,6 +726,8 @@ impl GlobalState {
                 let mut updated = false;
                 if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
                     let (vfs, _) = &*this.vfs.read();
+
+                    // Trigger flychecks for all workspaces that depend on the saved file
                     if let Some(file_id) = vfs.file_id(&vfs_path) {
                         let analysis = this.analysis_host.analysis();
                         // Crates containing or depending on the saved file
@@ -800,6 +785,8 @@ impl GlobalState {
                             }
                         }
                     }
+
+                    // Re-fetch workspaces if a workspace related file has changed
                     if let Some(abs_path) = vfs_path.as_path() {
                         if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) {
                             this.fetch_workspaces_queue
@@ -807,6 +794,8 @@ impl GlobalState {
                         }
                     }
                 }
+
+                // No specific flycheck was triggered, so let's trigger all of them.
                 if !updated {
                     for flycheck in &this.flycheck {
                         flycheck.update();
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index 49ccad71a10..ceb2a6d703d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -219,6 +219,7 @@ impl GlobalState {
                     cfg_overrides,
 
                     build_scripts: _,
+                    toolchain: _,
                 } => Some((cargo, sysroot, rustc, rustc_cfg, cfg_overrides)),
                 _ => None,
             };
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
index 7f4fa57fa1e..e7115b0732e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
@@ -1386,7 +1386,7 @@ fn main() {
     #[test]
     #[cfg(target_os = "windows")]
     fn test_lowercase_drive_letter() {
-        use std::{convert::TryInto, path::Path};
+        use std::path::Path;
 
         let url = url_from_abs_path(Path::new("C:\\Test").try_into().unwrap());
         assert_eq!(url.to_string(), "file:///c:/Test");
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs
index a687ba0b77a..8f7b3fb6008 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/operators.rs
@@ -111,10 +111,10 @@ impl fmt::Display for BinaryOp {
             BinaryOp::ArithOp(op) => fmt::Display::fmt(op, f),
             BinaryOp::CmpOp(op) => fmt::Display::fmt(op, f),
             BinaryOp::Assignment { op } => {
-                f.write_str("=")?;
                 if let Some(op) = op {
                     fmt::Display::fmt(op, f)?;
                 }
+                f.write_str("=")?;
                 Ok(())
             }
         }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs b/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs
index 256999fe09c..7c7a60d6299 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/fuzz.rs
@@ -2,10 +2,7 @@
 //!
 //! We don't normally run fuzzying, so this is hopelessly bitrotten :(
 
-use std::{
-    convert::TryInto,
-    str::{self, FromStr},
-};
+use std::str::{self, FromStr};
 
 use text_edit::Indel;
 
diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json
index 0436681b1a0..3ff4b6897a1 100644
--- a/src/tools/rust-analyzer/editors/code/package-lock.json
+++ b/src/tools/rust-analyzer/editors/code/package-lock.json
@@ -1,8 +1,3956 @@
 {
     "name": "rust-analyzer",
     "version": "0.5.0-dev",
-    "lockfileVersion": 1,
+    "lockfileVersion": 2,
     "requires": true,
+    "packages": {
+        "": {
+            "name": "rust-analyzer",
+            "version": "0.5.0-dev",
+            "license": "MIT OR Apache-2.0",
+            "dependencies": {
+                "d3": "^7.6.1",
+                "d3-graphviz": "^4.1.1",
+                "vscode-languageclient": "^8.0.0-next.14"
+            },
+            "devDependencies": {
+                "@types/node": "~16.11.7",
+                "@types/vscode": "~1.66.0",
+                "@typescript-eslint/eslint-plugin": "^5.30.5",
+                "@typescript-eslint/parser": "^5.30.5",
+                "@vscode/test-electron": "^2.1.5",
+                "cross-env": "^7.0.3",
+                "esbuild": "^0.14.48",
+                "eslint": "^8.19.0",
+                "eslint-config-prettier": "^8.5.0",
+                "ovsx": "^0.5.1",
+                "prettier": "^2.7.1",
+                "tslib": "^2.4.0",
+                "typescript": "^4.7.4",
+                "vsce": "^2.9.2"
+            },
+            "engines": {
+                "vscode": "^1.66.0"
+            }
+        },
+        "node_modules/@eslint/eslintrc": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
+            "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+            "dev": true,
+            "dependencies": {
+                "ajv": "^6.12.4",
+                "debug": "^4.3.2",
+                "espree": "^9.3.2",
+                "globals": "^13.15.0",
+                "ignore": "^5.2.0",
+                "import-fresh": "^3.2.1",
+                "js-yaml": "^4.1.0",
+                "minimatch": "^3.1.2",
+                "strip-json-comments": "^3.1.1"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/@hpcc-js/wasm": {
+            "version": "1.12.8",
+            "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-1.12.8.tgz",
+            "integrity": "sha512-n4q9ARKco2hpCLsuVaW6Az3cDVaua7B3DSONHkc49WtEzgY/btvcDG5Zr1P6PZDv0sQ7oPnAi9Y+W2DI++MgcQ==",
+            "dependencies": {
+                "yargs": "^17.3.1"
+            },
+            "bin": {
+                "dot-wasm": "bin/cli.js"
+            }
+        },
+        "node_modules/@humanwhocodes/config-array": {
+            "version": "0.9.5",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
+            "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+            "dev": true,
+            "dependencies": {
+                "@humanwhocodes/object-schema": "^1.2.1",
+                "debug": "^4.1.1",
+                "minimatch": "^3.0.4"
+            },
+            "engines": {
+                "node": ">=10.10.0"
+            }
+        },
+        "node_modules/@humanwhocodes/object-schema": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+            "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+            "dev": true
+        },
+        "node_modules/@nodelib/fs.scandir": {
+            "version": "2.1.5",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+            "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+            "dev": true,
+            "dependencies": {
+                "@nodelib/fs.stat": "2.0.5",
+                "run-parallel": "^1.1.9"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@nodelib/fs.stat": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+            "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+            "dev": true,
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@nodelib/fs.walk": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+            "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+            "dev": true,
+            "dependencies": {
+                "@nodelib/fs.scandir": "2.1.5",
+                "fastq": "^1.6.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@tootallnate/once": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+            "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/@types/json-schema": {
+            "version": "7.0.11",
+            "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+            "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+            "dev": true
+        },
+        "node_modules/@types/node": {
+            "version": "16.11.43",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.43.tgz",
+            "integrity": "sha512-GqWykok+3uocgfAJM8imbozrqLnPyTrpFlrryURQlw1EesPUCx5XxTiucWDSFF9/NUEXDuD4bnvHm8xfVGWTpQ==",
+            "dev": true
+        },
+        "node_modules/@types/vscode": {
+            "version": "1.66.0",
+            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.66.0.tgz",
+            "integrity": "sha512-ZfJck4M7nrGasfs4A4YbUoxis3Vu24cETw3DERsNYtDZmYSYtk6ljKexKFKhImO/ZmY6ZMsmegu2FPkXoUFImA==",
+            "dev": true
+        },
+        "node_modules/@typescript-eslint/eslint-plugin": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.5.tgz",
+            "integrity": "sha512-lftkqRoBvc28VFXEoRgyZuztyVUQ04JvUnATSPtIRFAccbXTWL6DEtXGYMcbg998kXw1NLUJm7rTQ9eUt+q6Ig==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/scope-manager": "5.30.5",
+                "@typescript-eslint/type-utils": "5.30.5",
+                "@typescript-eslint/utils": "5.30.5",
+                "debug": "^4.3.4",
+                "functional-red-black-tree": "^1.0.1",
+                "ignore": "^5.2.0",
+                "regexpp": "^3.2.0",
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "@typescript-eslint/parser": "^5.0.0",
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/parser": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.5.tgz",
+            "integrity": "sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/scope-manager": "5.30.5",
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/typescript-estree": "5.30.5",
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/scope-manager": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz",
+            "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/visitor-keys": "5.30.5"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@typescript-eslint/type-utils": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.5.tgz",
+            "integrity": "sha512-k9+ejlv1GgwN1nN7XjVtyCgE0BTzhzT1YsQF0rv4Vfj2U9xnslBgMYYvcEYAFVdvhuEscELJsB7lDkN7WusErw==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/utils": "5.30.5",
+                "debug": "^4.3.4",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "*"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/types": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz",
+            "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==",
+            "dev": true,
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@typescript-eslint/typescript-estree": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz",
+            "integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/visitor-keys": "5.30.5",
+                "debug": "^4.3.4",
+                "globby": "^11.1.0",
+                "is-glob": "^4.0.3",
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/utils": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.5.tgz",
+            "integrity": "sha512-o4SSUH9IkuA7AYIfAvatldovurqTAHrfzPApOZvdUq01hHojZojCFXx06D/aFpKCgWbMPRdJBWAC3sWp3itwTA==",
+            "dev": true,
+            "dependencies": {
+                "@types/json-schema": "^7.0.9",
+                "@typescript-eslint/scope-manager": "5.30.5",
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/typescript-estree": "5.30.5",
+                "eslint-scope": "^5.1.1",
+                "eslint-utils": "^3.0.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            }
+        },
+        "node_modules/@typescript-eslint/visitor-keys": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz",
+            "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/types": "5.30.5",
+                "eslint-visitor-keys": "^3.3.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@vscode/test-electron": {
+            "version": "2.1.5",
+            "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.5.tgz",
+            "integrity": "sha512-O/ioqFpV+RvKbRykX2ItYPnbcZ4Hk5V0rY4uhQjQTLhGL9WZUvS7exzuYQCCI+ilSqJpctvxq2llTfGXf9UnnA==",
+            "dev": true,
+            "dependencies": {
+                "http-proxy-agent": "^4.0.1",
+                "https-proxy-agent": "^5.0.0",
+                "rimraf": "^3.0.2",
+                "unzipper": "^0.10.11"
+            },
+            "engines": {
+                "node": ">=8.9.3"
+            }
+        },
+        "node_modules/acorn": {
+            "version": "8.7.1",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
+            "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+            "dev": true,
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/acorn-jsx": {
+            "version": "5.3.2",
+            "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+            "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+            "dev": true,
+            "peerDependencies": {
+                "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            }
+        },
+        "node_modules/agent-base": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+            "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+            "dev": true,
+            "dependencies": {
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/ajv": {
+            "version": "6.12.6",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+            "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+            "dev": true,
+            "dependencies": {
+                "fast-deep-equal": "^3.1.1",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.4.1",
+                "uri-js": "^4.2.2"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/epoberezkin"
+            }
+        },
+        "node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ansi-styles": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+            "dependencies": {
+                "color-convert": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+            }
+        },
+        "node_modules/argparse": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+            "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+            "dev": true
+        },
+        "node_modules/array-union": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+            "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/azure-devops-node-api": {
+            "version": "11.2.0",
+            "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz",
+            "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==",
+            "dev": true,
+            "dependencies": {
+                "tunnel": "0.0.6",
+                "typed-rest-client": "^1.8.4"
+            }
+        },
+        "node_modules/balanced-match": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+        },
+        "node_modules/base64-js": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+            "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/big-integer": {
+            "version": "1.6.51",
+            "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
+            "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/binary": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
+            "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==",
+            "dev": true,
+            "dependencies": {
+                "buffers": "~0.1.1",
+                "chainsaw": "~0.1.0"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/bl": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+            "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+            "dev": true,
+            "dependencies": {
+                "buffer": "^5.5.0",
+                "inherits": "^2.0.4",
+                "readable-stream": "^3.4.0"
+            }
+        },
+        "node_modules/bl/node_modules/readable-stream": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+            "dev": true,
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/bluebird": {
+            "version": "3.4.7",
+            "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
+            "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
+            "dev": true
+        },
+        "node_modules/boolbase": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+            "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+            "dev": true
+        },
+        "node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/braces": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+            "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+            "dev": true,
+            "dependencies": {
+                "fill-range": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/buffer": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+            "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "dependencies": {
+                "base64-js": "^1.3.1",
+                "ieee754": "^1.1.13"
+            }
+        },
+        "node_modules/buffer-crc32": {
+            "version": "0.2.13",
+            "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+            "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+            "dev": true,
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/buffer-indexof-polyfill": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
+            "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/buffers": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
+            "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.2.0"
+            }
+        },
+        "node_modules/call-bind": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+            "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+            "dev": true,
+            "dependencies": {
+                "function-bind": "^1.1.1",
+                "get-intrinsic": "^1.0.2"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/callsites": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+            "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/chainsaw": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
+            "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==",
+            "dev": true,
+            "dependencies": {
+                "traverse": ">=0.3.0 <0.4"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/chalk": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+            "dev": true,
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/chalk?sponsor=1"
+            }
+        },
+        "node_modules/cheerio": {
+            "version": "1.0.0-rc.12",
+            "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+            "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+            "dev": true,
+            "dependencies": {
+                "cheerio-select": "^2.1.0",
+                "dom-serializer": "^2.0.0",
+                "domhandler": "^5.0.3",
+                "domutils": "^3.0.1",
+                "htmlparser2": "^8.0.1",
+                "parse5": "^7.0.0",
+                "parse5-htmlparser2-tree-adapter": "^7.0.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+            }
+        },
+        "node_modules/cheerio-select": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+            "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+            "dev": true,
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-select": "^5.1.0",
+                "css-what": "^6.1.0",
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.3",
+                "domutils": "^3.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/chownr": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+            "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+            "dev": true
+        },
+        "node_modules/ci-info": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+            "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+            "dev": true
+        },
+        "node_modules/cliui": {
+            "version": "7.0.4",
+            "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+            "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+            "dependencies": {
+                "string-width": "^4.2.0",
+                "strip-ansi": "^6.0.0",
+                "wrap-ansi": "^7.0.0"
+            }
+        },
+        "node_modules/color-convert": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "dependencies": {
+                "color-name": "~1.1.4"
+            },
+            "engines": {
+                "node": ">=7.0.0"
+            }
+        },
+        "node_modules/color-name": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+        },
+        "node_modules/commander": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+            "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/concat-map": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+            "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+        },
+        "node_modules/core-util-is": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+            "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+            "dev": true
+        },
+        "node_modules/cross-env": {
+            "version": "7.0.3",
+            "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+            "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+            "dev": true,
+            "dependencies": {
+                "cross-spawn": "^7.0.1"
+            },
+            "bin": {
+                "cross-env": "src/bin/cross-env.js",
+                "cross-env-shell": "src/bin/cross-env-shell.js"
+            },
+            "engines": {
+                "node": ">=10.14",
+                "npm": ">=6",
+                "yarn": ">=1"
+            }
+        },
+        "node_modules/cross-spawn": {
+            "version": "7.0.3",
+            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+            "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+            "dev": true,
+            "dependencies": {
+                "path-key": "^3.1.0",
+                "shebang-command": "^2.0.0",
+                "which": "^2.0.1"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/css-select": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+            "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+            "dev": true,
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-what": "^6.1.0",
+                "domhandler": "^5.0.2",
+                "domutils": "^3.0.1",
+                "nth-check": "^2.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/css-what": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+            "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/d3": {
+            "version": "7.6.1",
+            "resolved": "https://registry.npmjs.org/d3/-/d3-7.6.1.tgz",
+            "integrity": "sha512-txMTdIHFbcpLx+8a0IFhZsbp+PfBBPt8yfbmukZTQFroKuFqIwqswF0qE5JXWefylaAVpSXFoKm3yP+jpNLFLw==",
+            "dependencies": {
+                "d3-array": "3",
+                "d3-axis": "3",
+                "d3-brush": "3",
+                "d3-chord": "3",
+                "d3-color": "3",
+                "d3-contour": "4",
+                "d3-delaunay": "6",
+                "d3-dispatch": "3",
+                "d3-drag": "3",
+                "d3-dsv": "3",
+                "d3-ease": "3",
+                "d3-fetch": "3",
+                "d3-force": "3",
+                "d3-format": "3",
+                "d3-geo": "3",
+                "d3-hierarchy": "3",
+                "d3-interpolate": "3",
+                "d3-path": "3",
+                "d3-polygon": "3",
+                "d3-quadtree": "3",
+                "d3-random": "3",
+                "d3-scale": "4",
+                "d3-scale-chromatic": "3",
+                "d3-selection": "3",
+                "d3-shape": "3",
+                "d3-time": "3",
+                "d3-time-format": "4",
+                "d3-timer": "3",
+                "d3-transition": "3",
+                "d3-zoom": "3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-array": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.0.tgz",
+            "integrity": "sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==",
+            "dependencies": {
+                "internmap": "1 - 2"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-axis": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
+            "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-brush": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+            "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-drag": "2 - 3",
+                "d3-interpolate": "1 - 3",
+                "d3-selection": "3",
+                "d3-transition": "3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-brush/node_modules/d3-selection": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+            "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-chord": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
+            "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
+            "dependencies": {
+                "d3-path": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-color": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+            "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-contour": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.0.tgz",
+            "integrity": "sha512-7aQo0QHUTu/Ko3cP9YK9yUTxtoDEiDGwnBHyLxG5M4vqlBkO/uixMRele3nfsfj6UXOcuReVpVXzAboGraYIJw==",
+            "dependencies": {
+                "d3-array": "^3.2.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-delaunay": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.2.tgz",
+            "integrity": "sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==",
+            "dependencies": {
+                "delaunator": "5"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-dispatch": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
+            "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-drag": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
+            "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-selection": "3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-drag/node_modules/d3-selection": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+            "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-dsv": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
+            "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+            "dependencies": {
+                "commander": "7",
+                "iconv-lite": "0.6",
+                "rw": "1"
+            },
+            "bin": {
+                "csv2json": "bin/dsv2json.js",
+                "csv2tsv": "bin/dsv2dsv.js",
+                "dsv2dsv": "bin/dsv2dsv.js",
+                "dsv2json": "bin/dsv2json.js",
+                "json2csv": "bin/json2dsv.js",
+                "json2dsv": "bin/json2dsv.js",
+                "json2tsv": "bin/json2dsv.js",
+                "tsv2csv": "bin/dsv2dsv.js",
+                "tsv2json": "bin/dsv2json.js"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-ease": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+            "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-fetch": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
+            "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
+            "dependencies": {
+                "d3-dsv": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-force": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
+            "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-quadtree": "1 - 3",
+                "d3-timer": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-format": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+            "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-geo": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.0.1.tgz",
+            "integrity": "sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA==",
+            "dependencies": {
+                "d3-array": "2.5.0 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-graphviz": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-4.1.1.tgz",
+            "integrity": "sha512-s0IVbKf8rs4eJI2xo5Umr7nXDX/LEZw/x2WtKxmlyQxR0qUY49UiLhBNOX7VDHZywMle43NKEXnU6fn22fpJvQ==",
+            "dependencies": {
+                "@hpcc-js/wasm": "1.12.8",
+                "d3-dispatch": "^2.0.0",
+                "d3-format": "^2.0.0",
+                "d3-interpolate": "^2.0.1",
+                "d3-path": "^2.0.0",
+                "d3-timer": "^2.0.0",
+                "d3-transition": "^2.0.0",
+                "d3-zoom": "^2.0.0"
+            },
+            "peerDependencies": {
+                "d3-selection": "^2.0.0"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-color": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
+            "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-dispatch": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
+            "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-drag": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz",
+            "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
+            "dependencies": {
+                "d3-dispatch": "1 - 2",
+                "d3-selection": "2"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-ease": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz",
+            "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-format": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
+            "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-interpolate": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
+            "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
+            "dependencies": {
+                "d3-color": "1 - 2"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
+            "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-timer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz",
+            "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-transition": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz",
+            "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
+            "dependencies": {
+                "d3-color": "1 - 2",
+                "d3-dispatch": "1 - 2",
+                "d3-ease": "1 - 2",
+                "d3-interpolate": "1 - 2",
+                "d3-timer": "1 - 2"
+            },
+            "peerDependencies": {
+                "d3-selection": "2"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-zoom": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz",
+            "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==",
+            "dependencies": {
+                "d3-dispatch": "1 - 2",
+                "d3-drag": "2",
+                "d3-interpolate": "1 - 2",
+                "d3-selection": "2",
+                "d3-transition": "2"
+            }
+        },
+        "node_modules/d3-hierarchy": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+            "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-interpolate": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+            "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+            "dependencies": {
+                "d3-color": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-path": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz",
+            "integrity": "sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-polygon": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
+            "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-quadtree": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
+            "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-random": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+            "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-scale": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+            "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+            "dependencies": {
+                "d3-array": "2.10.0 - 3",
+                "d3-format": "1 - 3",
+                "d3-interpolate": "1.2.0 - 3",
+                "d3-time": "2.1.1 - 3",
+                "d3-time-format": "2 - 4"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-scale-chromatic": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+            "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+            "dependencies": {
+                "d3-color": "1 - 3",
+                "d3-interpolate": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-selection": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz",
+            "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA=="
+        },
+        "node_modules/d3-shape": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.1.0.tgz",
+            "integrity": "sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==",
+            "dependencies": {
+                "d3-path": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-time": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.0.0.tgz",
+            "integrity": "sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ==",
+            "dependencies": {
+                "d3-array": "2 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-time-format": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+            "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+            "dependencies": {
+                "d3-time": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-timer": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+            "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-transition": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
+            "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
+            "dependencies": {
+                "d3-color": "1 - 3",
+                "d3-dispatch": "1 - 3",
+                "d3-ease": "1 - 3",
+                "d3-interpolate": "1 - 3",
+                "d3-timer": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "peerDependencies": {
+                "d3-selection": "2 - 3"
+            }
+        },
+        "node_modules/d3-zoom": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
+            "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-drag": "2 - 3",
+                "d3-interpolate": "1 - 3",
+                "d3-selection": "2 - 3",
+                "d3-transition": "2 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3/node_modules/d3-selection": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+            "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/debug": {
+            "version": "4.3.4",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "dev": true,
+            "dependencies": {
+                "ms": "2.1.2"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/decompress-response": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+            "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+            "dev": true,
+            "dependencies": {
+                "mimic-response": "^3.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/deep-extend": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+            "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/deep-is": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+            "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+            "dev": true
+        },
+        "node_modules/delaunator": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
+            "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
+            "dependencies": {
+                "robust-predicates": "^3.0.0"
+            }
+        },
+        "node_modules/detect-libc": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
+            "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/dir-glob": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+            "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+            "dev": true,
+            "dependencies": {
+                "path-type": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/doctrine": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+            "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+            "dev": true,
+            "dependencies": {
+                "esutils": "^2.0.2"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/dom-serializer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+            "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+            "dev": true,
+            "dependencies": {
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.2",
+                "entities": "^4.2.0"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+            }
+        },
+        "node_modules/domelementtype": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+            "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ]
+        },
+        "node_modules/domhandler": {
+            "version": "5.0.3",
+            "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+            "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+            "dev": true,
+            "dependencies": {
+                "domelementtype": "^2.3.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domhandler?sponsor=1"
+            }
+        },
+        "node_modules/domutils": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+            "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+            "dev": true,
+            "dependencies": {
+                "dom-serializer": "^2.0.0",
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domutils?sponsor=1"
+            }
+        },
+        "node_modules/duplexer2": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+            "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+            "dev": true,
+            "dependencies": {
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+        },
+        "node_modules/end-of-stream": {
+            "version": "1.4.4",
+            "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+            "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+            "dev": true,
+            "dependencies": {
+                "once": "^1.4.0"
+            }
+        },
+        "node_modules/entities": {
+            "version": "4.3.1",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz",
+            "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
+        "node_modules/esbuild": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.48.tgz",
+            "integrity": "sha512-w6N1Yn5MtqK2U1/WZTX9ZqUVb8IOLZkZ5AdHkT6x3cHDMVsYWC7WPdiLmx19w3i4Rwzy5LqsEMtVihG3e4rFzA==",
+            "dev": true,
+            "hasInstallScript": true,
+            "bin": {
+                "esbuild": "bin/esbuild"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "optionalDependencies": {
+                "esbuild-android-64": "0.14.48",
+                "esbuild-android-arm64": "0.14.48",
+                "esbuild-darwin-64": "0.14.48",
+                "esbuild-darwin-arm64": "0.14.48",
+                "esbuild-freebsd-64": "0.14.48",
+                "esbuild-freebsd-arm64": "0.14.48",
+                "esbuild-linux-32": "0.14.48",
+                "esbuild-linux-64": "0.14.48",
+                "esbuild-linux-arm": "0.14.48",
+                "esbuild-linux-arm64": "0.14.48",
+                "esbuild-linux-mips64le": "0.14.48",
+                "esbuild-linux-ppc64le": "0.14.48",
+                "esbuild-linux-riscv64": "0.14.48",
+                "esbuild-linux-s390x": "0.14.48",
+                "esbuild-netbsd-64": "0.14.48",
+                "esbuild-openbsd-64": "0.14.48",
+                "esbuild-sunos-64": "0.14.48",
+                "esbuild-windows-32": "0.14.48",
+                "esbuild-windows-64": "0.14.48",
+                "esbuild-windows-arm64": "0.14.48"
+            }
+        },
+        "node_modules/esbuild-android-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.48.tgz",
+            "integrity": "sha512-3aMjboap/kqwCUpGWIjsk20TtxVoKck8/4Tu19rubh7t5Ra0Yrpg30Mt1QXXlipOazrEceGeWurXKeFJgkPOUg==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "android"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-android-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.48.tgz",
+            "integrity": "sha512-vptI3K0wGALiDq+EvRuZotZrJqkYkN5282iAfcffjI5lmGG9G1ta/CIVauhY42MBXwEgDJkweiDcDMRLzBZC4g==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "android"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-darwin-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.48.tgz",
+            "integrity": "sha512-gGQZa4+hab2Va/Zww94YbshLuWteyKGD3+EsVon8EWTWhnHFRm5N9NbALNbwi/7hQ/hM1Zm4FuHg+k6BLsl5UA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-darwin-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.48.tgz",
+            "integrity": "sha512-bFjnNEXjhZT+IZ8RvRGNJthLWNHV5JkCtuOFOnjvo5pC0sk2/QVk0Qc06g2PV3J0TcU6kaPC3RN9yy9w2PSLEA==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-freebsd-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.48.tgz",
+            "integrity": "sha512-1NOlwRxmOsnPcWOGTB10JKAkYSb2nue0oM1AfHWunW/mv3wERfJmnYlGzL3UAOIUXZqW8GeA2mv+QGwq7DToqA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "freebsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-freebsd-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.48.tgz",
+            "integrity": "sha512-gXqKdO8wabVcYtluAbikDH2jhXp+Klq5oCD5qbVyUG6tFiGhrC9oczKq3vIrrtwcxDQqK6+HDYK8Zrd4bCA9Gw==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "freebsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-32": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.48.tgz",
+            "integrity": "sha512-ghGyDfS289z/LReZQUuuKq9KlTiTspxL8SITBFQFAFRA/IkIvDpnZnCAKTCjGXAmUqroMQfKJXMxyjJA69c/nQ==",
+            "cpu": [
+                "ia32"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.48.tgz",
+            "integrity": "sha512-vni3p/gppLMVZLghI7oMqbOZdGmLbbKR23XFARKnszCIBpEMEDxOMNIKPmMItQrmH/iJrL1z8Jt2nynY0bE1ug==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-arm": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.48.tgz",
+            "integrity": "sha512-+VfSV7Akh1XUiDNXgqgY1cUP1i2vjI+BmlyXRfVz5AfV3jbpde8JTs5Q9sYgaoq5cWfuKfoZB/QkGOI+QcL1Tw==",
+            "cpu": [
+                "arm"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.48.tgz",
+            "integrity": "sha512-3CFsOlpoxlKPRevEHq8aAntgYGYkE1N9yRYAcPyng/p4Wyx0tPR5SBYsxLKcgPB9mR8chHEhtWYz6EZ+H199Zw==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-mips64le": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.48.tgz",
+            "integrity": "sha512-cs0uOiRlPp6ymknDnjajCgvDMSsLw5mST2UXh+ZIrXTj2Ifyf2aAP3Iw4DiqgnyYLV2O/v/yWBJx+WfmKEpNLA==",
+            "cpu": [
+                "mips64el"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-ppc64le": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.48.tgz",
+            "integrity": "sha512-+2F0vJMkuI0Wie/wcSPDCqXvSFEELH7Jubxb7mpWrA/4NpT+/byjxDz0gG6R1WJoeDefcrMfpBx4GFNN1JQorQ==",
+            "cpu": [
+                "ppc64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-riscv64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.48.tgz",
+            "integrity": "sha512-BmaK/GfEE+5F2/QDrIXteFGKnVHGxlnK9MjdVKMTfvtmudjY3k2t8NtlY4qemKSizc+QwyombGWTBDc76rxePA==",
+            "cpu": [
+                "riscv64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-s390x": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.48.tgz",
+            "integrity": "sha512-tndw/0B9jiCL+KWKo0TSMaUm5UWBLsfCKVdbfMlb3d5LeV9WbijZ8Ordia8SAYv38VSJWOEt6eDCdOx8LqkC4g==",
+            "cpu": [
+                "s390x"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-netbsd-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.48.tgz",
+            "integrity": "sha512-V9hgXfwf/T901Lr1wkOfoevtyNkrxmMcRHyticybBUHookznipMOHoF41Al68QBsqBxnITCEpjjd4yAos7z9Tw==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "netbsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-openbsd-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.48.tgz",
+            "integrity": "sha512-+IHf4JcbnnBl4T52egorXMatil/za0awqzg2Vy6FBgPcBpisDWT2sVz/tNdrK9kAqj+GZG/jZdrOkj7wsrNTKA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "openbsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-sunos-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.48.tgz",
+            "integrity": "sha512-77m8bsr5wOpOWbGi9KSqDphcq6dFeJyun8TA+12JW/GAjyfTwVtOnN8DOt6DSPUfEV+ltVMNqtXUeTeMAxl5KA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "sunos"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-windows-32": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.48.tgz",
+            "integrity": "sha512-EPgRuTPP8vK9maxpTGDe5lSoIBHGKO/AuxDncg5O3NkrPeLNdvvK8oywB0zGaAZXxYWfNNSHskvvDgmfVTguhg==",
+            "cpu": [
+                "ia32"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-windows-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.48.tgz",
+            "integrity": "sha512-YmpXjdT1q0b8ictSdGwH3M8VCoqPpK1/UArze3X199w6u8hUx3V8BhAi1WjbsfDYRBanVVtduAhh2sirImtAvA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-windows-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.48.tgz",
+            "integrity": "sha512-HHaOMCsCXp0rz5BT2crTka6MPWVno121NKApsGs/OIW5QC0ggC69YMGs1aJct9/9FSUF4A1xNE/cLvgB5svR4g==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/escalade": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+            "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/escape-string-regexp": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+            "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/eslint": {
+            "version": "8.19.0",
+            "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz",
+            "integrity": "sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==",
+            "dev": true,
+            "dependencies": {
+                "@eslint/eslintrc": "^1.3.0",
+                "@humanwhocodes/config-array": "^0.9.2",
+                "ajv": "^6.10.0",
+                "chalk": "^4.0.0",
+                "cross-spawn": "^7.0.2",
+                "debug": "^4.3.2",
+                "doctrine": "^3.0.0",
+                "escape-string-regexp": "^4.0.0",
+                "eslint-scope": "^7.1.1",
+                "eslint-utils": "^3.0.0",
+                "eslint-visitor-keys": "^3.3.0",
+                "espree": "^9.3.2",
+                "esquery": "^1.4.0",
+                "esutils": "^2.0.2",
+                "fast-deep-equal": "^3.1.3",
+                "file-entry-cache": "^6.0.1",
+                "functional-red-black-tree": "^1.0.1",
+                "glob-parent": "^6.0.1",
+                "globals": "^13.15.0",
+                "ignore": "^5.2.0",
+                "import-fresh": "^3.0.0",
+                "imurmurhash": "^0.1.4",
+                "is-glob": "^4.0.0",
+                "js-yaml": "^4.1.0",
+                "json-stable-stringify-without-jsonify": "^1.0.1",
+                "levn": "^0.4.1",
+                "lodash.merge": "^4.6.2",
+                "minimatch": "^3.1.2",
+                "natural-compare": "^1.4.0",
+                "optionator": "^0.9.1",
+                "regexpp": "^3.2.0",
+                "strip-ansi": "^6.0.1",
+                "strip-json-comments": "^3.1.0",
+                "text-table": "^0.2.0",
+                "v8-compile-cache": "^2.0.3"
+            },
+            "bin": {
+                "eslint": "bin/eslint.js"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://opencollective.com/eslint"
+            }
+        },
+        "node_modules/eslint-config-prettier": {
+            "version": "8.5.0",
+            "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
+            "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
+            "dev": true,
+            "bin": {
+                "eslint-config-prettier": "bin/cli.js"
+            },
+            "peerDependencies": {
+                "eslint": ">=7.0.0"
+            }
+        },
+        "node_modules/eslint-scope": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+            "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+            "dev": true,
+            "dependencies": {
+                "esrecurse": "^4.3.0",
+                "estraverse": "^4.1.1"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/eslint-utils": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+            "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+            "dev": true,
+            "dependencies": {
+                "eslint-visitor-keys": "^2.0.0"
+            },
+            "engines": {
+                "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/mysticatea"
+            },
+            "peerDependencies": {
+                "eslint": ">=5"
+            }
+        },
+        "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+            "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/eslint-visitor-keys": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+            "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+            "dev": true,
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/eslint/node_modules/eslint-scope": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+            "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+            "dev": true,
+            "dependencies": {
+                "esrecurse": "^4.3.0",
+                "estraverse": "^5.2.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/eslint/node_modules/estraverse": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/espree": {
+            "version": "9.3.2",
+            "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
+            "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+            "dev": true,
+            "dependencies": {
+                "acorn": "^8.7.1",
+                "acorn-jsx": "^5.3.2",
+                "eslint-visitor-keys": "^3.3.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/esquery": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+            "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+            "dev": true,
+            "dependencies": {
+                "estraverse": "^5.1.0"
+            },
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/esquery/node_modules/estraverse": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esrecurse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+            "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+            "dev": true,
+            "dependencies": {
+                "estraverse": "^5.2.0"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esrecurse/node_modules/estraverse": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/estraverse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esutils": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/expand-template": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+            "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/fast-deep-equal": {
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+            "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+            "dev": true
+        },
+        "node_modules/fast-glob": {
+            "version": "3.2.11",
+            "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+            "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+            "dev": true,
+            "dependencies": {
+                "@nodelib/fs.stat": "^2.0.2",
+                "@nodelib/fs.walk": "^1.2.3",
+                "glob-parent": "^5.1.2",
+                "merge2": "^1.3.0",
+                "micromatch": "^4.0.4"
+            },
+            "engines": {
+                "node": ">=8.6.0"
+            }
+        },
+        "node_modules/fast-glob/node_modules/glob-parent": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+            "dev": true,
+            "dependencies": {
+                "is-glob": "^4.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/fast-json-stable-stringify": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+            "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+            "dev": true
+        },
+        "node_modules/fast-levenshtein": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+            "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+            "dev": true
+        },
+        "node_modules/fastq": {
+            "version": "1.13.0",
+            "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+            "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+            "dev": true,
+            "dependencies": {
+                "reusify": "^1.0.4"
+            }
+        },
+        "node_modules/fd-slicer": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+            "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+            "dev": true,
+            "dependencies": {
+                "pend": "~1.2.0"
+            }
+        },
+        "node_modules/file-entry-cache": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+            "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+            "dev": true,
+            "dependencies": {
+                "flat-cache": "^3.0.4"
+            },
+            "engines": {
+                "node": "^10.12.0 || >=12.0.0"
+            }
+        },
+        "node_modules/fill-range": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+            "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+            "dev": true,
+            "dependencies": {
+                "to-regex-range": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/flat-cache": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+            "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+            "dev": true,
+            "dependencies": {
+                "flatted": "^3.1.0",
+                "rimraf": "^3.0.2"
+            },
+            "engines": {
+                "node": "^10.12.0 || >=12.0.0"
+            }
+        },
+        "node_modules/flatted": {
+            "version": "3.2.6",
+            "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz",
+            "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
+            "dev": true
+        },
+        "node_modules/follow-redirects": {
+            "version": "1.15.1",
+            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
+            "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "individual",
+                    "url": "https://github.com/sponsors/RubenVerborgh"
+                }
+            ],
+            "engines": {
+                "node": ">=4.0"
+            },
+            "peerDependenciesMeta": {
+                "debug": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/fs-constants": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+            "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+            "dev": true
+        },
+        "node_modules/fs.realpath": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+            "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+            "dev": true
+        },
+        "node_modules/fstream": {
+            "version": "1.0.12",
+            "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+            "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+            "dev": true,
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "inherits": "~2.0.0",
+                "mkdirp": ">=0.5 0",
+                "rimraf": "2"
+            },
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/fstream/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/function-bind": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+            "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+            "dev": true
+        },
+        "node_modules/functional-red-black-tree": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+            "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
+            "dev": true
+        },
+        "node_modules/get-caller-file": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+            "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+            "engines": {
+                "node": "6.* || 8.* || >= 10.*"
+            }
+        },
+        "node_modules/get-intrinsic": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+            "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+            "dev": true,
+            "dependencies": {
+                "function-bind": "^1.1.1",
+                "has": "^1.0.3",
+                "has-symbols": "^1.0.3"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/github-from-package": {
+            "version": "0.0.0",
+            "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+            "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+            "dev": true
+        },
+        "node_modules/glob": {
+            "version": "7.2.3",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+            "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+            "dev": true,
+            "dependencies": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^3.1.1",
+                "once": "^1.3.0",
+                "path-is-absolute": "^1.0.0"
+            },
+            "engines": {
+                "node": "*"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/glob-parent": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+            "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+            "dev": true,
+            "dependencies": {
+                "is-glob": "^4.0.3"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            }
+        },
+        "node_modules/globals": {
+            "version": "13.16.0",
+            "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz",
+            "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==",
+            "dev": true,
+            "dependencies": {
+                "type-fest": "^0.20.2"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/globby": {
+            "version": "11.1.0",
+            "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+            "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+            "dev": true,
+            "dependencies": {
+                "array-union": "^2.1.0",
+                "dir-glob": "^3.0.1",
+                "fast-glob": "^3.2.9",
+                "ignore": "^5.2.0",
+                "merge2": "^1.4.1",
+                "slash": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/graceful-fs": {
+            "version": "4.2.10",
+            "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+            "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+            "dev": true
+        },
+        "node_modules/has": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+            "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+            "dev": true,
+            "dependencies": {
+                "function-bind": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/has-flag": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+            "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/has-symbols": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+            "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/hosted-git-info": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+            "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+            "dev": true,
+            "dependencies": {
+                "lru-cache": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/htmlparser2": {
+            "version": "8.0.1",
+            "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
+            "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+            "dev": true,
+            "funding": [
+                "https://github.com/fb55/htmlparser2?sponsor=1",
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ],
+            "dependencies": {
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.2",
+                "domutils": "^3.0.1",
+                "entities": "^4.3.0"
+            }
+        },
+        "node_modules/http-proxy-agent": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+            "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+            "dev": true,
+            "dependencies": {
+                "@tootallnate/once": "1",
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/https-proxy-agent": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+            "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+            "dev": true,
+            "dependencies": {
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/iconv-lite": {
+            "version": "0.6.3",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+            "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/ieee754": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+            "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/ignore": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+            "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+            "dev": true,
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/import-fresh": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+            "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+            "dev": true,
+            "dependencies": {
+                "parent-module": "^1.0.0",
+                "resolve-from": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/imurmurhash": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+            "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.8.19"
+            }
+        },
+        "node_modules/inflight": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+            "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+            "dev": true,
+            "dependencies": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "node_modules/inherits": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+            "dev": true
+        },
+        "node_modules/ini": {
+            "version": "1.3.8",
+            "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+            "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+            "dev": true
+        },
+        "node_modules/internmap": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+            "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/is-ci": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+            "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+            "dev": true,
+            "dependencies": {
+                "ci-info": "^2.0.0"
+            },
+            "bin": {
+                "is-ci": "bin.js"
+            }
+        },
+        "node_modules/is-extglob": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+            "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-fullwidth-code-point": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+            "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/is-glob": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+            "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+            "dev": true,
+            "dependencies": {
+                "is-extglob": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-number": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+            "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/isarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+            "dev": true
+        },
+        "node_modules/isexe": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+            "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+            "dev": true
+        },
+        "node_modules/js-yaml": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+            "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+            "dev": true,
+            "dependencies": {
+                "argparse": "^2.0.1"
+            },
+            "bin": {
+                "js-yaml": "bin/js-yaml.js"
+            }
+        },
+        "node_modules/json-schema-traverse": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+            "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+            "dev": true
+        },
+        "node_modules/json-stable-stringify-without-jsonify": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+            "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+            "dev": true
+        },
+        "node_modules/keytar": {
+            "version": "7.9.0",
+            "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
+            "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
+            "dev": true,
+            "hasInstallScript": true,
+            "dependencies": {
+                "node-addon-api": "^4.3.0",
+                "prebuild-install": "^7.0.1"
+            }
+        },
+        "node_modules/leven": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+            "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/levn": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+            "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+            "dev": true,
+            "dependencies": {
+                "prelude-ls": "^1.2.1",
+                "type-check": "~0.4.0"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/linkify-it": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+            "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+            "dev": true,
+            "dependencies": {
+                "uc.micro": "^1.0.1"
+            }
+        },
+        "node_modules/listenercount": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
+            "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==",
+            "dev": true
+        },
+        "node_modules/lodash.merge": {
+            "version": "4.6.2",
+            "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+            "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+            "dev": true
+        },
+        "node_modules/lru-cache": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/markdown-it": {
+            "version": "12.3.2",
+            "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+            "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+            "dev": true,
+            "dependencies": {
+                "argparse": "^2.0.1",
+                "entities": "~2.1.0",
+                "linkify-it": "^3.0.1",
+                "mdurl": "^1.0.1",
+                "uc.micro": "^1.0.5"
+            },
+            "bin": {
+                "markdown-it": "bin/markdown-it.js"
+            }
+        },
+        "node_modules/markdown-it/node_modules/entities": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+            "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+            "dev": true,
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
+        "node_modules/mdurl": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+            "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+            "dev": true
+        },
+        "node_modules/merge2": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+            "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+            "dev": true,
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/micromatch": {
+            "version": "4.0.5",
+            "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+            "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+            "dev": true,
+            "dependencies": {
+                "braces": "^3.0.2",
+                "picomatch": "^2.3.1"
+            },
+            "engines": {
+                "node": ">=8.6"
+            }
+        },
+        "node_modules/mime": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+            "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+            "dev": true,
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/mimic-response": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+            "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/minimatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/minimist": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+            "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+            "dev": true
+        },
+        "node_modules/mkdirp": {
+            "version": "0.5.6",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+            "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+            "dev": true,
+            "dependencies": {
+                "minimist": "^1.2.6"
+            },
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            }
+        },
+        "node_modules/mkdirp-classic": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+            "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+            "dev": true
+        },
+        "node_modules/ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+            "dev": true
+        },
+        "node_modules/mute-stream": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+            "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+            "dev": true
+        },
+        "node_modules/napi-build-utils": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+            "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+            "dev": true
+        },
+        "node_modules/natural-compare": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+            "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+            "dev": true
+        },
+        "node_modules/node-abi": {
+            "version": "3.22.0",
+            "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.22.0.tgz",
+            "integrity": "sha512-u4uAs/4Zzmp/jjsD9cyFYDXeISfUWaAVWshPmDZOFOv4Xl4SbzTXm53I04C2uRueYJ+0t5PEtLH/owbn2Npf/w==",
+            "dev": true,
+            "dependencies": {
+                "semver": "^7.3.5"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/node-addon-api": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+            "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
+            "dev": true
+        },
+        "node_modules/nth-check": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+            "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+            "dev": true,
+            "dependencies": {
+                "boolbase": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/nth-check?sponsor=1"
+            }
+        },
+        "node_modules/object-inspect": {
+            "version": "1.12.2",
+            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+            "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+            "dev": true,
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/once": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+            "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+            "dev": true,
+            "dependencies": {
+                "wrappy": "1"
+            }
+        },
+        "node_modules/optionator": {
+            "version": "0.9.1",
+            "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+            "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+            "dev": true,
+            "dependencies": {
+                "deep-is": "^0.1.3",
+                "fast-levenshtein": "^2.0.6",
+                "levn": "^0.4.1",
+                "prelude-ls": "^1.2.1",
+                "type-check": "^0.4.0",
+                "word-wrap": "^1.2.3"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/ovsx": {
+            "version": "0.5.1",
+            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.5.1.tgz",
+            "integrity": "sha512-3OWq0l7DuVHi2bd2aQe5+QVQlFIqvrcw3/2vGXL404L6Tr+R4QHtzfnYYghv8CCa85xJHjU0RhcaC7pyXkAUbg==",
+            "dev": true,
+            "dependencies": {
+                "commander": "^6.1.0",
+                "follow-redirects": "^1.14.6",
+                "is-ci": "^2.0.0",
+                "leven": "^3.1.0",
+                "tmp": "^0.2.1",
+                "vsce": "^2.6.3"
+            },
+            "bin": {
+                "ovsx": "lib/ovsx"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/ovsx/node_modules/commander": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+            "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/parent-module": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+            "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+            "dev": true,
+            "dependencies": {
+                "callsites": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/parse-semver": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
+            "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==",
+            "dev": true,
+            "dependencies": {
+                "semver": "^5.1.0"
+            }
+        },
+        "node_modules/parse-semver/node_modules/semver": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/parse5": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
+            "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
+            "dev": true,
+            "dependencies": {
+                "entities": "^4.3.0"
+            },
+            "funding": {
+                "url": "https://github.com/inikulin/parse5?sponsor=1"
+            }
+        },
+        "node_modules/parse5-htmlparser2-tree-adapter": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+            "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+            "dev": true,
+            "dependencies": {
+                "domhandler": "^5.0.2",
+                "parse5": "^7.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/inikulin/parse5?sponsor=1"
+            }
+        },
+        "node_modules/path-is-absolute": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/path-key": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+            "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/path-type": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+            "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pend": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+            "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+            "dev": true
+        },
+        "node_modules/picomatch": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+            "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+            "dev": true,
+            "engines": {
+                "node": ">=8.6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/jonschlinkert"
+            }
+        },
+        "node_modules/prebuild-install": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
+            "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+            "dev": true,
+            "dependencies": {
+                "detect-libc": "^2.0.0",
+                "expand-template": "^2.0.3",
+                "github-from-package": "0.0.0",
+                "minimist": "^1.2.3",
+                "mkdirp-classic": "^0.5.3",
+                "napi-build-utils": "^1.0.1",
+                "node-abi": "^3.3.0",
+                "pump": "^3.0.0",
+                "rc": "^1.2.7",
+                "simple-get": "^4.0.0",
+                "tar-fs": "^2.0.0",
+                "tunnel-agent": "^0.6.0"
+            },
+            "bin": {
+                "prebuild-install": "bin.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/prelude-ls": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+            "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/prettier": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
+            "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+            "dev": true,
+            "bin": {
+                "prettier": "bin-prettier.js"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            },
+            "funding": {
+                "url": "https://github.com/prettier/prettier?sponsor=1"
+            }
+        },
+        "node_modules/process-nextick-args": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+            "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+            "dev": true
+        },
+        "node_modules/pump": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+            "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+            "dev": true,
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/punycode": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+            "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/qs": {
+            "version": "6.11.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+            "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+            "dev": true,
+            "dependencies": {
+                "side-channel": "^1.0.4"
+            },
+            "engines": {
+                "node": ">=0.6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/queue-microtask": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+            "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/rc": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+            "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+            "dev": true,
+            "dependencies": {
+                "deep-extend": "^0.6.0",
+                "ini": "~1.3.0",
+                "minimist": "^1.2.0",
+                "strip-json-comments": "~2.0.1"
+            },
+            "bin": {
+                "rc": "cli.js"
+            }
+        },
+        "node_modules/rc/node_modules/strip-json-comments": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+            "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/read": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+            "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
+            "dev": true,
+            "dependencies": {
+                "mute-stream": "~0.0.4"
+            },
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.3",
+                "isarray": "~1.0.0",
+                "process-nextick-args": "~2.0.0",
+                "safe-buffer": "~5.1.1",
+                "string_decoder": "~1.1.1",
+                "util-deprecate": "~1.0.1"
+            }
+        },
+        "node_modules/regexpp": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+            "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/mysticatea"
+            }
+        },
+        "node_modules/require-directory": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+            "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/resolve-from": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+            "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/reusify": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+            "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+            "dev": true,
+            "engines": {
+                "iojs": ">=1.0.0",
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/rimraf": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+            "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/robust-predicates": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz",
+            "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
+        },
+        "node_modules/run-parallel": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+            "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "dependencies": {
+                "queue-microtask": "^1.2.2"
+            }
+        },
+        "node_modules/rw": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+            "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
+        },
+        "node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+            "dev": true
+        },
+        "node_modules/safer-buffer": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+        },
+        "node_modules/sax": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+            "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+            "dev": true
+        },
+        "node_modules/semver": {
+            "version": "7.3.7",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+            "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+            "dependencies": {
+                "lru-cache": "^6.0.0"
+            },
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/setimmediate": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+            "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+            "dev": true
+        },
+        "node_modules/shebang-command": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+            "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+            "dev": true,
+            "dependencies": {
+                "shebang-regex": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/shebang-regex": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+            "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/side-channel": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+            "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.0",
+                "get-intrinsic": "^1.0.2",
+                "object-inspect": "^1.9.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/simple-concat": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+            "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/simple-get": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+            "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "dependencies": {
+                "decompress-response": "^6.0.0",
+                "once": "^1.3.1",
+                "simple-concat": "^1.0.0"
+            }
+        },
+        "node_modules/slash": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+            "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/string_decoder": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+            "dev": true,
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/string-width": {
+            "version": "4.2.3",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+            "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+            "dependencies": {
+                "emoji-regex": "^8.0.0",
+                "is-fullwidth-code-point": "^3.0.0",
+                "strip-ansi": "^6.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/strip-ansi": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+            "dependencies": {
+                "ansi-regex": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/strip-json-comments": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+            "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/supports-color": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+            "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+            "dev": true,
+            "dependencies": {
+                "has-flag": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/tar-fs": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+            "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+            "dev": true,
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "mkdirp-classic": "^0.5.2",
+                "pump": "^3.0.0",
+                "tar-stream": "^2.1.4"
+            }
+        },
+        "node_modules/tar-stream": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+            "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+            "dev": true,
+            "dependencies": {
+                "bl": "^4.0.3",
+                "end-of-stream": "^1.4.1",
+                "fs-constants": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^3.1.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/tar-stream/node_modules/readable-stream": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+            "dev": true,
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/text-table": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+            "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+            "dev": true
+        },
+        "node_modules/tmp": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+            "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+            "dev": true,
+            "dependencies": {
+                "rimraf": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8.17.0"
+            }
+        },
+        "node_modules/to-regex-range": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+            "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+            "dev": true,
+            "dependencies": {
+                "is-number": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/traverse": {
+            "version": "0.3.9",
+            "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
+            "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==",
+            "dev": true,
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/tslib": {
+            "version": "2.4.0",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+            "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+            "dev": true
+        },
+        "node_modules/tsutils": {
+            "version": "3.21.0",
+            "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+            "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+            "dev": true,
+            "dependencies": {
+                "tslib": "^1.8.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            },
+            "peerDependencies": {
+                "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+            }
+        },
+        "node_modules/tsutils/node_modules/tslib": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+            "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+            "dev": true
+        },
+        "node_modules/tunnel": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+            "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+            }
+        },
+        "node_modules/tunnel-agent": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+            "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+            "dev": true,
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/type-check": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+            "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+            "dev": true,
+            "dependencies": {
+                "prelude-ls": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/type-fest": {
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+            "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/typed-rest-client": {
+            "version": "1.8.9",
+            "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.9.tgz",
+            "integrity": "sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g==",
+            "dev": true,
+            "dependencies": {
+                "qs": "^6.9.1",
+                "tunnel": "0.0.6",
+                "underscore": "^1.12.1"
+            }
+        },
+        "node_modules/typescript": {
+            "version": "4.7.4",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
+            "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
+            "dev": true,
+            "bin": {
+                "tsc": "bin/tsc",
+                "tsserver": "bin/tsserver"
+            },
+            "engines": {
+                "node": ">=4.2.0"
+            }
+        },
+        "node_modules/uc.micro": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+            "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+            "dev": true
+        },
+        "node_modules/underscore": {
+            "version": "1.13.4",
+            "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz",
+            "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==",
+            "dev": true
+        },
+        "node_modules/unzipper": {
+            "version": "0.10.11",
+            "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz",
+            "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==",
+            "dev": true,
+            "dependencies": {
+                "big-integer": "^1.6.17",
+                "binary": "~0.3.0",
+                "bluebird": "~3.4.1",
+                "buffer-indexof-polyfill": "~1.0.0",
+                "duplexer2": "~0.1.4",
+                "fstream": "^1.0.12",
+                "graceful-fs": "^4.2.2",
+                "listenercount": "~1.0.1",
+                "readable-stream": "~2.3.6",
+                "setimmediate": "~1.0.4"
+            }
+        },
+        "node_modules/uri-js": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+            "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+            "dev": true,
+            "dependencies": {
+                "punycode": "^2.1.0"
+            }
+        },
+        "node_modules/url-join": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+            "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+            "dev": true
+        },
+        "node_modules/util-deprecate": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+            "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+            "dev": true
+        },
+        "node_modules/v8-compile-cache": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+            "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+            "dev": true
+        },
+        "node_modules/vsce": {
+            "version": "2.9.2",
+            "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.9.2.tgz",
+            "integrity": "sha512-xyLqL4U82BilUX1t6Ym2opQEa2tLGWYjbgB7+ETeNVXlIJz5sWBJjQJSYJVFOKJSpiOtQclolu88cj7oY6vvPQ==",
+            "dev": true,
+            "dependencies": {
+                "azure-devops-node-api": "^11.0.1",
+                "chalk": "^2.4.2",
+                "cheerio": "^1.0.0-rc.9",
+                "commander": "^6.1.0",
+                "glob": "^7.0.6",
+                "hosted-git-info": "^4.0.2",
+                "keytar": "^7.7.0",
+                "leven": "^3.1.0",
+                "markdown-it": "^12.3.2",
+                "mime": "^1.3.4",
+                "minimatch": "^3.0.3",
+                "parse-semver": "^1.1.1",
+                "read": "^1.0.7",
+                "semver": "^5.1.0",
+                "tmp": "^0.2.1",
+                "typed-rest-client": "^1.8.4",
+                "url-join": "^4.0.1",
+                "xml2js": "^0.4.23",
+                "yauzl": "^2.3.1",
+                "yazl": "^2.2.2"
+            },
+            "bin": {
+                "vsce": "vsce"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/vsce/node_modules/ansi-styles": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+            "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+            "dev": true,
+            "dependencies": {
+                "color-convert": "^1.9.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vsce/node_modules/chalk": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+            "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+            "dev": true,
+            "dependencies": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vsce/node_modules/color-convert": {
+            "version": "1.9.3",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+            "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+            "dev": true,
+            "dependencies": {
+                "color-name": "1.1.3"
+            }
+        },
+        "node_modules/vsce/node_modules/color-name": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+            "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+            "dev": true
+        },
+        "node_modules/vsce/node_modules/commander": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+            "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/vsce/node_modules/escape-string-regexp": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+            "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/vsce/node_modules/has-flag": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+            "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vsce/node_modules/semver": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/vsce/node_modules/supports-color": {
+            "version": "5.5.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+            "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+            "dev": true,
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vscode-jsonrpc": {
+            "version": "8.0.0-next.7",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.0-next.7.tgz",
+            "integrity": "sha512-JX/F31LEsims0dAlOTKFE4E+AJMiJvdRSRViifFJSqSN7EzeYyWlfuDchF7g91oRNPZOIWfibTkDf3/UMsQGzQ==",
+            "engines": {
+                "node": ">=14.0.0"
+            }
+        },
+        "node_modules/vscode-languageclient": {
+            "version": "8.0.0-next.14",
+            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.0.0-next.14.tgz",
+            "integrity": "sha512-NqjkOuDTMu8uo+PhoMsV72VO9Gd3wBi/ZpOrkRUOrWKQo7yUdiIw183g8wjH8BImgbK9ZP51HM7TI0ZhCnI1Mw==",
+            "dependencies": {
+                "minimatch": "^3.0.4",
+                "semver": "^7.3.5",
+                "vscode-languageserver-protocol": "3.17.0-next.16"
+            },
+            "engines": {
+                "vscode": "^1.66.0"
+            }
+        },
+        "node_modules/vscode-languageserver-protocol": {
+            "version": "3.17.0-next.16",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.16.tgz",
+            "integrity": "sha512-tx4DnXw9u3N7vw+bx6n2NKp6FoxoNwiP/biH83AS30I2AnTGyLd7afSeH6Oewn2E8jvB7K15bs12sMppkKOVeQ==",
+            "dependencies": {
+                "vscode-jsonrpc": "8.0.0-next.7",
+                "vscode-languageserver-types": "3.17.0-next.9"
+            }
+        },
+        "node_modules/vscode-languageserver-types": {
+            "version": "3.17.0-next.9",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.9.tgz",
+            "integrity": "sha512-9/PeDNPYduaoXRUzYpqmu4ZV9L01HGo0wH9FUt+sSHR7IXwA7xoXBfNUlv8gB9H0D2WwEmMomSy1NmhjKQyn3A=="
+        },
+        "node_modules/which": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+            "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+            "dev": true,
+            "dependencies": {
+                "isexe": "^2.0.0"
+            },
+            "bin": {
+                "node-which": "bin/node-which"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/word-wrap": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+            "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/wrap-ansi": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+            "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+            "dependencies": {
+                "ansi-styles": "^4.0.0",
+                "string-width": "^4.1.0",
+                "strip-ansi": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+            }
+        },
+        "node_modules/wrappy": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+            "dev": true
+        },
+        "node_modules/xml2js": {
+            "version": "0.4.23",
+            "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
+            "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+            "dev": true,
+            "dependencies": {
+                "sax": ">=0.6.0",
+                "xmlbuilder": "~11.0.0"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/xmlbuilder": {
+            "version": "11.0.1",
+            "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+            "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/y18n": {
+            "version": "5.0.8",
+            "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+            "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+        },
+        "node_modules/yargs": {
+            "version": "17.5.1",
+            "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+            "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+            "dependencies": {
+                "cliui": "^7.0.2",
+                "escalade": "^3.1.1",
+                "get-caller-file": "^2.0.5",
+                "require-directory": "^2.1.1",
+                "string-width": "^4.2.3",
+                "y18n": "^5.0.5",
+                "yargs-parser": "^21.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/yargs-parser": {
+            "version": "21.0.1",
+            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
+            "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/yauzl": {
+            "version": "2.10.0",
+            "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+            "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+            "dev": true,
+            "dependencies": {
+                "buffer-crc32": "~0.2.3",
+                "fd-slicer": "~1.1.0"
+            }
+        },
+        "node_modules/yazl": {
+            "version": "2.5.1",
+            "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+            "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+            "dev": true,
+            "dependencies": {
+                "buffer-crc32": "~0.2.3"
+            }
+        }
+    },
     "dependencies": {
         "@eslint/eslintrc": {
             "version": "1.3.0",
@@ -213,7 +4161,8 @@
             "version": "5.3.2",
             "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
             "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-            "dev": true
+            "dev": true,
+            "requires": {}
         },
         "agent-base": {
             "version": "6.0.2",
@@ -1278,7 +5227,8 @@
             "version": "8.5.0",
             "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
             "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
-            "dev": true
+            "dev": true,
+            "requires": {}
         },
         "eslint-scope": {
             "version": "5.1.1",
@@ -2348,6 +6298,15 @@
             "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
             "dev": true
         },
+        "string_decoder": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+            "dev": true,
+            "requires": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
         "string-width": {
             "version": "4.2.3",
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -2358,15 +6317,6 @@
                 "strip-ansi": "^6.0.1"
             }
         },
-        "string_decoder": {
-            "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-            "dev": true,
-            "requires": {
-                "safe-buffer": "~5.1.0"
-            }
-        },
         "strip-ansi": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts
index 8a2dea6b35b..27ab31db8db 100644
--- a/src/tools/rust-analyzer/editors/code/src/client.ts
+++ b/src/tools/rust-analyzer/editors/code/src/client.ts
@@ -105,6 +105,22 @@ export async function createClient(
         traceOutputChannel: traceOutputChannel(),
         outputChannel: outputChannel(),
         middleware: {
+            async handleDiagnostics(uri, diagnostics, next) {
+                // Workaround for https://github.com/microsoft/vscode/issues/155531
+                for (const diagnostic of diagnostics) {
+                    if (!diagnostic.message) {
+                        diagnostic.message = " ";
+                    }
+                    if (diagnostic.relatedInformation) {
+                        for (const relatedInformation of diagnostic.relatedInformation) {
+                            if (!relatedInformation.message) {
+                                relatedInformation.message = " ";
+                            }
+                        }
+                    }
+                }
+                next(uri, diagnostics);
+            },
             async provideHover(
                 document: vscode.TextDocument,
                 position: vscode.Position,
diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts
index bf55329ca1f..1b793bb0b15 100644
--- a/src/tools/rust-analyzer/editors/code/src/commands.ts
+++ b/src/tools/rust-analyzer/editors/code/src/commands.ts
@@ -326,8 +326,22 @@ export function toggleInlayHints(_ctx: Ctx): Cmd {
         const config = vscode.workspace.getConfiguration("editor.inlayHints", {
             languageId: "rust",
         });
-        const value = !config.get("enabled");
-        await config.update("enabled", value, vscode.ConfigurationTarget.Global);
+
+        const value = config.get("enabled");
+        let stringValue;
+        if (typeof value === "string") {
+            stringValue = value;
+        } else {
+            stringValue = value ? "on" : "off";
+        }
+        const nextValues: Record<string, string> = {
+            on: "off",
+            off: "on",
+            onUnlessPressed: "offUnlessPressed",
+            offUnlessPressed: "onUnlessPressed",
+        };
+        const nextValue = nextValues[stringValue] ?? "on";
+        await config.update("enabled", nextValue, vscode.ConfigurationTarget.Global);
     };
 }
 
diff --git a/src/tools/rust-analyzer/lib/la-arena/src/lib.rs b/src/tools/rust-analyzer/lib/la-arena/src/lib.rs
index a3fe59e946e..50e8d06b660 100644
--- a/src/tools/rust-analyzer/lib/la-arena/src/lib.rs
+++ b/src/tools/rust-analyzer/lib/la-arena/src/lib.rs
@@ -6,7 +6,6 @@
 use std::{
     fmt,
     hash::{Hash, Hasher},
-    iter::FromIterator,
     marker::PhantomData,
     ops::{Index, IndexMut, Range, RangeInclusive},
 };
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index a7b73ba78c5..3105882e2d3 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -79,7 +79,7 @@ pub(crate) fn format_expr(
             if let Some(expr_rw) = rewrite_literal(context, l, shape) {
                 Some(expr_rw)
             } else {
-                if let LitKind::StrRaw(_) = l.token.kind {
+                if let LitKind::StrRaw(_) = l.token_lit.kind {
                     Some(context.snippet(l.span).trim().into())
                 } else {
                     None
@@ -1226,7 +1226,7 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) ->
 
 fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -> Option<String> {
     let span = lit.span;
-    let symbol = lit.token.symbol.as_str();
+    let symbol = lit.token_lit.symbol.as_str();
 
     if let Some(symbol_stripped) = symbol.strip_prefix("0x") {
         let hex_lit = match context.config.hex_literal_case() {
@@ -1239,7 +1239,9 @@ fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -
                 format!(
                     "0x{}{}",
                     hex_lit,
-                    lit.token.suffix.map_or(String::new(), |s| s.to_string())
+                    lit.token_lit
+                        .suffix
+                        .map_or(String::new(), |s| s.to_string())
                 ),
                 context.config.max_width(),
                 shape,
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 23db5421910..6efeee98fea 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -3,6 +3,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
 
 use rustc_data_structures::sync::{Lrc, Send};
 use rustc_errors::emitter::{Emitter, EmitterWriter};
+use rustc_errors::translation::Translate;
 use rustc_errors::{ColorConfig, Diagnostic, Handler, Level as DiagnosticLevel};
 use rustc_session::parse::ParseSess as RawParseSess;
 use rustc_span::{
@@ -28,19 +29,24 @@ pub(crate) struct ParseSess {
 /// Emitter which discards every error.
 struct SilentEmitter;
 
-impl Emitter for SilentEmitter {
-    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
-        None
-    }
-    fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
+impl Translate for SilentEmitter {
     fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
         None
     }
+
     fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
         panic!("silent emitter attempted to translate a diagnostic");
     }
 }
 
+impl Emitter for SilentEmitter {
+    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+        None
+    }
+
+    fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
+}
+
 fn silent_emitter() -> Box<dyn Emitter + Send> {
     Box::new(SilentEmitter {})
 }
@@ -62,10 +68,21 @@ impl SilentOnIgnoredFilesEmitter {
     }
 }
 
+impl Translate for SilentOnIgnoredFilesEmitter {
+    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+        self.emitter.fluent_bundle()
+    }
+
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+        self.emitter.fallback_fluent_bundle()
+    }
+}
+
 impl Emitter for SilentOnIgnoredFilesEmitter {
     fn source_map(&self) -> Option<&Lrc<SourceMap>> {
         None
     }
+
     fn emit_diagnostic(&mut self, db: &Diagnostic) {
         if db.level() == DiagnosticLevel::Fatal {
             return self.handle_non_ignoreable_error(db);
@@ -88,14 +105,6 @@ impl Emitter for SilentOnIgnoredFilesEmitter {
         }
         self.handle_non_ignoreable_error(db);
     }
-
-    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
-        self.emitter.fluent_bundle()
-    }
-
-    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
-        self.emitter.fallback_fluent_bundle()
-    }
 }
 
 fn default_handler(
@@ -340,19 +349,24 @@ mod tests {
             num_emitted_errors: Lrc<AtomicU32>,
         }
 
+        impl Translate for TestEmitter {
+            fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+                None
+            }
+
+            fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+                panic!("test emitter attempted to translate a diagnostic");
+            }
+        }
+
         impl Emitter for TestEmitter {
             fn source_map(&self) -> Option<&Lrc<SourceMap>> {
                 None
             }
+
             fn emit_diagnostic(&mut self, _db: &Diagnostic) {
                 self.num_emitted_errors.fetch_add(1, Ordering::Release);
             }
-            fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
-                None
-            }
-            fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
-                panic!("test emitter attempted to translate a diagnostic");
-            }
         }
 
         fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> Diagnostic {
diff --git a/triagebot.toml b/triagebot.toml
index ea654192bbf..8a90bc0e3c1 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -129,6 +129,7 @@ trigger_files = [
 
     # Internal tooling
     "src/etc/htmldocck.py",
+    "src/etc/check_missing_items.py",
     "src/tools/jsondocck",
     "src/tools/rustdoc-gui",
     "src/tools/rustdoc-js",
@@ -138,6 +139,15 @@ exclude_labels = [
     "T-*",
 ]
 
+[autolabel."A-rustdoc-json"]
+trigger_files = [
+    "src/etc/check_missing_items.py",
+    "src/librustdoc/json/",
+    "src/rustdoc-json-types",
+    "src/test/rustdoc-json",
+    "src/tools/jsondocck",
+]
+
 [autolabel."T-compiler"]
 trigger_files = [
     # Source code
@@ -178,6 +188,13 @@ trigger_files = [
     "src/tools/bump-stage0",
 ]
 
+[autolabel."A-translation"]
+trigger_files = [
+    "compiler/rustc_error_messages",
+    "compiler/rustc_errors/src/translation.rs",
+    "compiler/rustc_macros/src/diagnostics"
+]
+
 [notify-zulip."I-prioritize"]
 zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts
 topic = "#{number} {title}"
@@ -342,3 +359,15 @@ cc = ["@rust-lang/rustfmt"]
 [mentions."compiler/rustc_middle/src/mir/syntax.rs"]
 message = "This PR changes MIR"
 cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@davidtwco", "@celinval", "@vakaras"]
+
+[mentions."compiler/rustc_error_messages"]
+message = "`rustc_error_messages` was changed"
+cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@estebank", "@TaKO8Ki"]
+
+[mentions."compiler/rustc_errors/src/translation.rs"]
+message = "`rustc_errors::translation` was changed"
+cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@estebank", "@TaKO8Ki"]
+
+[mentions."compiler/rustc_macros/src/diagnostics"]
+message = "`rustc_macros::diagnostics` was changed"
+cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@estebank", "@TaKO8Ki"]