about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml3
-rw-r--r--Cargo.lock33
-rw-r--r--compiler/rustc_borrowck/src/invalidation.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs9
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs166
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs24
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs3
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs95
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs76
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs29
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs25
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs80
-rw-r--r--compiler/rustc_lint/messages.ftl8
-rw-r--r--compiler/rustc_lint/src/drop_forget_useless.rs26
-rw-r--r--compiler/rustc_lint/src/lints.rs10
-rw-r--r--compiler/rustc_metadata/src/creader.rs10
-rw-r--r--compiler/rustc_metadata/src/locator.rs13
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs4
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs5
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs23
-rw-r--r--compiler/rustc_middle/src/query/mod.rs20
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs23
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs18
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs22
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs12
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs101
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs27
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coverage/debug.rs27
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs29
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs5
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs11
-rw-r--r--compiler/rustc_mir_transform/src/ctfe_limit.rs2
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs12
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs5
-rw-r--r--compiler/rustc_resolve/src/late.rs15
-rw-r--r--compiler/rustc_resolve/src/lib.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs14
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs277
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs55
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs35
-rw-r--r--library/alloc/src/sync.rs25
-rw-r--r--library/alloc/src/vec/in_place_collect.rs9
-rw-r--r--library/core/src/fmt/float.rs12
-rw-r--r--library/core/src/fmt/mod.rs42
-rw-r--r--library/core/src/fmt/num.rs15
-rw-r--r--library/core/src/iter/traits/collect.rs10
-rw-r--r--library/core/src/mem/mod.rs2
-rw-r--r--library/core/src/ptr/mod.rs16
-rw-r--r--library/std/src/path.rs11
-rw-r--r--src/bootstrap/config.rs150
-rw-r--r--src/bootstrap/config/tests.rs77
-rw-r--r--src/bootstrap/flags.rs3
-rw-r--r--src/bootstrap/llvm.rs1
-rw-r--r--src/ci/docker/README.md16
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile30
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig14
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rw-r--r--src/ci/docker/scripts/cross-apt-packages.sh1
-rw-r--r--src/ci/docker/scripts/crosstool-ng-git.sh17
-rw-r--r--src/ci/github-actions/ci.yml3
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/exploit-mitigations.md17
-rw-r--r--src/doc/rustc/src/images/image3.pngbin72412 -> 19069 bytes
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-linux.md2
-rw-r--r--src/etc/completions/x.py.fish15
-rw-r--r--src/etc/completions/x.py.ps115
-rw-r--r--src/etc/completions/x.py.sh90
-rw-r--r--src/librustdoc/html/static/css/settings.css9
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/rustdoc-json-types/Cargo.toml1
-rw-r--r--src/rustdoc-json-types/lib.rs6
-rw-r--r--src/rustdoc-json-types/tests.rs16
-rw-r--r--src/tools/build-manifest/src/main.rs2
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/drop_forget_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs8
-rw-r--r--src/tools/clippy/tests/ui/mem_forget.rs2
-rw-r--r--src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs2
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed16
-rw-r--r--src/tools/clippy/tests/ui/rename.rs8
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr16
-rw-r--r--src/tools/miri/Cargo.lock29
-rw-r--r--src/tools/miri/Cargo.toml1
-rw-r--r--src/tools/miri/cargo-miri/src/arg.rs8
-rw-r--r--src/tools/miri/cargo-miri/src/phases.rs52
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/concurrency/thread.rs17
-rw-r--r--src/tools/miri/src/machine.rs9
-rw-r--r--src/tools/miri/src/shims/backtrace.rs2
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs8
-rw-r--r--src/tools/miri/src/shims/intrinsics/simd.rs13
-rw-r--r--src/tools/miri/src/shims/mod.rs2
-rw-r--r--src/tools/miri/src/shims/time.rs2
-rw-r--r--src/tools/miri/src/shims/tls.rs2
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs2
-rw-r--r--src/tools/miri/src/shims/unix/linux/sync.rs2
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/windows/handle.rs8
-rwxr-xr-xsrc/tools/miri/test-cargo-miri/run-test.py3
-rw-r--r--src/tools/miri/tests/fail/never_say_never.rs6
-rw-r--r--src/tools/miri/tests/fail/never_say_never.stderr4
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit_buffer.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs2
-rw-r--r--src/tools/miri/tests/pass/portable-simd.rs33
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs2
-rw-r--r--tests/assembly/option-nonzero-eq.rs28
-rw-r--r--tests/codegen/drop-in-place-noalias.rs38
-rw-r--r--tests/codegen/issues/issue-111603.rs28
-rw-r--r--tests/codegen/noalias-box-off.rs5
-rw-r--r--tests/codegen/option-nonzero-eq.rs12
-rw-r--r--tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs18
-rw-r--r--tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs31
-rw-r--r--tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs31
-rw-r--r--tests/codegen/tied-features-strength.rs29
-rw-r--r--tests/mir-opt/building/enum_cast.bar.built.after.mir9
-rw-r--r--tests/mir-opt/building/enum_cast.boo.built.after.mir9
-rw-r--r--tests/mir-opt/building/enum_cast.droppy.built.after.mir9
-rw-r--r--tests/mir-opt/building/enum_cast.far.built.after.mir22
-rw-r--r--tests/mir-opt/building/enum_cast.offsetty.built.after.mir26
-rw-r--r--tests/mir-opt/building/enum_cast.rs42
-rw-r--r--tests/mir-opt/building/enum_cast.signy.built.after.mir26
-rw-r--r--tests/mir-opt/building/enum_cast.unsigny.built.after.mir17
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff14
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff14
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.32bit.diff17
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff17
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.32bit.diff22
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff22
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.32bit.diff14
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff14
-rw-r--r--tests/mir-opt/issue_72181_1.f.built.after.mir14
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff14
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff14
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff14
-rw-r--r--tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff11
-rw-r--r--tests/run-make/issue-83045/Makefile2
-rw-r--r--tests/rustdoc-gui/jump-to-def-background.goml6
-rw-r--r--tests/rustdoc-gui/scrape-examples-color.goml6
-rw-r--r--tests/rustdoc-gui/settings.goml4
-rw-r--r--tests/rustdoc-json/assoc_items.rs27
-rw-r--r--tests/rustdoc-json/blanket_impls.rs6
-rw-r--r--tests/rustdoc-json/enums/discriminant/basic.rs12
-rw-r--r--tests/rustdoc-json/enums/discriminant/expr.rs36
-rw-r--r--tests/rustdoc-json/enums/discriminant/limits.rs32
-rw-r--r--tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs18
-rw-r--r--tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs10
-rw-r--r--tests/rustdoc-json/enums/discriminant/struct.rs12
-rw-r--r--tests/rustdoc-json/enums/discriminant/tuple.rs12
-rw-r--r--tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs2
-rw-r--r--tests/rustdoc-json/enums/field_hidden.rs4
-rw-r--r--tests/rustdoc-json/enums/kind.rs28
-rw-r--r--tests/rustdoc-json/enums/struct_field_hidden.rs8
-rw-r--r--tests/rustdoc-json/enums/tuple_fields_hidden.rs80
-rw-r--r--tests/rustdoc-json/enums/use_glob.rs8
-rw-r--r--tests/rustdoc-json/enums/use_variant.rs8
-rw-r--r--tests/rustdoc-json/enums/use_variant_foreign.rs2
-rw-r--r--tests/rustdoc-json/enums/variant_struct.rs8
-rw-r--r--tests/rustdoc-json/enums/variant_tuple_struct.rs8
-rw-r--r--tests/rustdoc-json/fn_pointer/abi.rs14
-rw-r--r--tests/rustdoc-json/fn_pointer/generics.rs15
-rw-r--r--tests/rustdoc-json/fn_pointer/qualifiers.rs14
-rw-r--r--tests/rustdoc-json/fns/abi.rs14
-rw-r--r--tests/rustdoc-json/fns/async_return.rs26
-rw-r--r--tests/rustdoc-json/fns/extern_c_variadic.rs4
-rw-r--r--tests/rustdoc-json/fns/generic_args.rs88
-rw-r--r--tests/rustdoc-json/fns/generic_returns.rs9
-rw-r--r--tests/rustdoc-json/fns/generics.rs29
-rw-r--r--tests/rustdoc-json/fns/pattern_arg.rs4
-rw-r--r--tests/rustdoc-json/fns/qualifiers.rs36
-rw-r--r--tests/rustdoc-json/fns/return_type_alias.rs3
-rw-r--r--tests/rustdoc-json/generic-associated-types/gats.rs36
-rw-r--r--tests/rustdoc-json/glob_import.rs2
-rw-r--r--tests/rustdoc-json/impls/auto.rs3
-rw-r--r--tests/rustdoc-json/impls/foreign_for_local.rs8
-rw-r--r--tests/rustdoc-json/impls/import_from_private.rs16
-rw-r--r--tests/rustdoc-json/impls/local_for_foreign.rs8
-rw-r--r--tests/rustdoc-json/impls/local_for_local.rs8
-rw-r--r--tests/rustdoc-json/impls/local_for_local_primitive.rs7
-rw-r--r--tests/rustdoc-json/impls/local_for_primitive.rs2
-rw-r--r--tests/rustdoc-json/lifetime/longest.rs37
-rw-r--r--tests/rustdoc-json/lifetime/outlives.rs32
-rw-r--r--tests/rustdoc-json/methods/abi.rs28
-rw-r--r--tests/rustdoc-json/methods/qualifiers.rs36
-rw-r--r--tests/rustdoc-json/nested.rs31
-rw-r--r--tests/rustdoc-json/non_lifetime_binders.rs10
-rw-r--r--tests/rustdoc-json/primitives/local_primitive.rs2
-rw-r--r--tests/rustdoc-json/primitives/primitive_impls.rs6
-rw-r--r--tests/rustdoc-json/primitives/primitive_type.rs15
-rw-r--r--tests/rustdoc-json/primitives/use_primitive.rs4
-rw-r--r--tests/rustdoc-json/reexport/doc_inline_external_crate.rs5
-rw-r--r--tests/rustdoc-json/reexport/export_extern_crate_as_self.rs2
-rw-r--r--tests/rustdoc-json/reexport/extern_crate_glob.rs5
-rw-r--r--tests/rustdoc-json/reexport/glob_collision.rs28
-rw-r--r--tests/rustdoc-json/reexport/glob_empty_mod.rs4
-rw-r--r--tests/rustdoc-json/reexport/glob_extern.rs13
-rw-r--r--tests/rustdoc-json/reexport/glob_private.rs20
-rw-r--r--tests/rustdoc-json/reexport/in_root_and_mod.rs4
-rw-r--r--tests/rustdoc-json/reexport/in_root_and_mod_pub.rs16
-rw-r--r--tests/rustdoc-json/reexport/macro.rs5
-rw-r--r--tests/rustdoc-json/reexport/mod_not_included.rs4
-rw-r--r--tests/rustdoc-json/reexport/private_twice_one_inline.rs10
-rw-r--r--tests/rustdoc-json/reexport/private_two_names.rs16
-rw-r--r--tests/rustdoc-json/reexport/reexport_method_from_private_module.rs4
-rw-r--r--tests/rustdoc-json/reexport/rename_private.rs4
-rw-r--r--tests/rustdoc-json/reexport/rename_public.rs11
-rw-r--r--tests/rustdoc-json/reexport/same_name_different_types.rs8
-rw-r--r--tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs12
-rw-r--r--tests/rustdoc-json/reexport/simple_private.rs8
-rw-r--r--tests/rustdoc-json/reexport/simple_public.rs9
-rw-r--r--tests/rustdoc-json/return_private.rs4
-rw-r--r--tests/rustdoc-json/structs/plain_all_pub.rs8
-rw-r--r--tests/rustdoc-json/structs/plain_doc_hidden.rs6
-rw-r--r--tests/rustdoc-json/structs/plain_empty.rs6
-rw-r--r--tests/rustdoc-json/structs/plain_pub_priv.rs6
-rw-r--r--tests/rustdoc-json/structs/tuple.rs4
-rw-r--r--tests/rustdoc-json/structs/tuple_empty.rs2
-rw-r--r--tests/rustdoc-json/structs/tuple_pub_priv.rs8
-rw-r--r--tests/rustdoc-json/structs/unit.rs4
-rw-r--r--tests/rustdoc-json/structs/with_generics.rs14
-rw-r--r--tests/rustdoc-json/structs/with_primitives.rs12
-rw-r--r--tests/rustdoc-json/traits/has_body.rs14
-rw-r--r--tests/rustdoc-json/traits/implementors.rs10
-rw-r--r--tests/rustdoc-json/traits/supertrait.rs16
-rw-r--r--tests/rustdoc-json/traits/trait_alias.rs18
-rw-r--r--tests/rustdoc-json/type/dyn.rs68
-rw-r--r--tests/rustdoc-json/type/extern.rs3
-rw-r--r--tests/rustdoc-json/type/fn_lifetime.rs39
-rw-r--r--tests/rustdoc-json/type/generic_default.rs42
-rw-r--r--tests/rustdoc-json/type/hrtb.rs18
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type.rs13
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type_bound.rs14
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type_projections.rs13
-rw-r--r--tests/rustdoc-json/unions/impl.rs6
-rw-r--r--tests/rustdoc-json/unions/union.rs8
-rw-r--r--tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs10
-rw-r--r--tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr21
-rw-r--r--tests/ui/associated-inherent-types/inference.rs2
-rw-r--r--tests/ui/associated-inherent-types/issue-111879-0.rs14
-rw-r--r--tests/ui/associated-inherent-types/issue-111879-0.stderr8
-rw-r--r--tests/ui/associated-inherent-types/issue-111879-1.rs12
-rw-r--r--tests/ui/associated-inherent-types/issue-111879-1.stderr12
-rw-r--r--tests/ui/async-await/return-type-notation/supertrait-bound.rs11
-rw-r--r--tests/ui/async-await/return-type-notation/supertrait-bound.stderr11
-rw-r--r--tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs2
-rw-r--r--tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs2
-rw-r--r--tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs2
-rw-r--r--tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs2
-rw-r--r--tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs2
-rw-r--r--tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs2
-rw-r--r--tests/ui/consts/const_forget.rs2
-rw-r--r--tests/ui/consts/issue-104155.rs2
-rw-r--r--tests/ui/crate-leading-sep.rs2
-rw-r--r--tests/ui/drop/repeat-drop.rs2
-rw-r--r--tests/ui/dyn-star/param-env-infer.current.stderr18
-rw-r--r--tests/ui/dyn-star/param-env-infer.next.stderr18
-rw-r--r--tests/ui/dyn-star/param-env-infer.rs16
-rw-r--r--tests/ui/error-codes/E0746.fixed18
-rw-r--r--tests/ui/error-codes/E0746.rs2
-rw-r--r--tests/ui/error-codes/E0746.stderr22
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed2
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.rs2
-rw-r--r--tests/ui/generator/drop-env.rs2
-rw-r--r--tests/ui/generator/issue-57017.rs2
-rw-r--r--tests/ui/generator/non-static-is-unpin.rs2
-rw-r--r--tests/ui/generator/resume-arg-size.rs2
-rw-r--r--tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs2
-rw-r--r--tests/ui/illegal-ufcs-drop.fixed2
-rw-r--r--tests/ui/illegal-ufcs-drop.rs2
-rw-r--r--tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs2
-rw-r--r--tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr110
-rw-r--r--tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs4
-rw-r--r--tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr108
-rw-r--r--tests/ui/imports/issue-109148.rs15
-rw-r--r--tests/ui/imports/issue-109148.stderr13
-rw-r--r--tests/ui/issues/issue-18107.stderr12
-rw-r--r--tests/ui/iterators/collect-into-slice.rs6
-rw-r--r--tests/ui/iterators/collect-into-slice.stderr12
-rw-r--r--tests/ui/lint/dropping_copy_types.rs (renamed from tests/ui/lint/drop_copy.rs)2
-rw-r--r--tests/ui/lint/dropping_copy_types.stderr (renamed from tests/ui/lint/drop_copy.stderr)28
-rw-r--r--tests/ui/lint/dropping_references.rs (renamed from tests/ui/lint/drop_ref.rs)2
-rw-r--r--tests/ui/lint/dropping_references.stderr (renamed from tests/ui/lint/drop_ref.stderr)30
-rw-r--r--tests/ui/lint/forgetting_copy_types.rs (renamed from tests/ui/lint/forget_copy.rs)2
-rw-r--r--tests/ui/lint/forgetting_copy_types.stderr (renamed from tests/ui/lint/forget_copy.stderr)24
-rw-r--r--tests/ui/lint/forgetting_references.rs (renamed from tests/ui/lint/forget_ref.rs)2
-rw-r--r--tests/ui/lint/forgetting_references.stderr (renamed from tests/ui/lint/forget_ref.stderr)24
-rw-r--r--tests/ui/liveness/liveness-unused.rs2
-rw-r--r--tests/ui/macros/parse-complex-macro-invoc-op.rs2
-rw-r--r--tests/ui/never_type/never-assign-dead-code.rs2
-rw-r--r--tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs2
-rw-r--r--tests/ui/nll/ty-outlives/projection-body.rs2
-rw-r--r--tests/ui/or-patterns/or-patterns-default-binding-modes.rs4
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs4
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs2
-rw-r--r--tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs2
-rw-r--r--tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs2
-rw-r--r--tests/ui/print_type_sizes/async.rs2
-rw-r--r--tests/ui/print_type_sizes/generator_discr_placement.rs2
-rw-r--r--tests/ui/regions/type-param-outlives-reempty-issue-74429.rs2
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs2
-rw-r--r--tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs2
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.fixed2
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.rs2
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs.rs16
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs.stderr9
-rw-r--r--tests/ui/statics/issue-91050-1.rs2
-rw-r--r--tests/ui/traits/copy-guessing.rs2
-rw-r--r--tests/ui/traits/cycle-cache-err-60010.stderr18
-rw-r--r--tests/ui/traits/impl-evaluation-order.rs2
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs2
-rw-r--r--tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs25
-rw-r--r--tests/ui/traits/new-solver/structural-resolve-field.rs13
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs34
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr24
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr11
-rw-r--r--tests/ui/unsized-locals/issue-67981.rs9
-rw-r--r--tests/ui/unsized-locals/issue-67981.stderr15
-rw-r--r--tests/ui/unsized/box-instead-of-dyn-fn.rs1
-rw-r--r--tests/ui/unsized/box-instead-of-dyn-fn.stderr43
-rw-r--r--tests/ui/unsized/issue-91801.stderr7
-rw-r--r--tests/ui/unsized/issue-91803.stderr9
-rw-r--r--triagebot.toml2
352 files changed, 3359 insertions, 1982 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2d8980fcd1a..b12a0b855e2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -201,6 +201,9 @@ jobs:
           - name: dist-i686-linux
             os: ubuntu-20.04-8core-32gb
             env: {}
+          - name: dist-loongarch64-linux
+            os: ubuntu-20.04-8core-32gb
+            env: {}
           - name: dist-mips-linux
             os: ubuntu-20.04-8core-32gb
             env: {}
diff --git a/Cargo.lock b/Cargo.lock
index 04c804d19a4..d5840513083 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -247,6 +247,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
 name = "bitflags"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -895,6 +904,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "ctrlc"
+version = "3.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7394a21d012ce5c850497fb774b167d81b99f060025fbf06ee92b9848bd97eb2"
+dependencies = [
+ "nix",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
 name = "curl"
 version = "0.4.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2295,6 +2314,7 @@ name = "miri"
 version = "0.1.0"
 dependencies = [
  "colored",
+ "ctrlc",
  "env_logger 0.9.0",
  "getrandom",
  "lazy_static",
@@ -2325,6 +2345,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
 
 [[package]]
+name = "nix"
+version = "0.26.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+ "static_assertions",
+]
+
+[[package]]
 name = "nom"
 version = "7.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4351,6 +4383,7 @@ dependencies = [
 name = "rustdoc-json-types"
 version = "0.1.0"
 dependencies = [
+ "bincode",
  "rustc-hash",
  "serde",
  "serde_json",
diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs
index 863c92acdf4..036391d074d 100644
--- a/compiler/rustc_borrowck/src/invalidation.rs
+++ b/compiler/rustc_borrowck/src/invalidation.rs
@@ -46,7 +46,7 @@ struct InvalidationGenerator<'cx, 'tcx> {
     all_facts: &'cx mut AllFacts,
     location_table: &'cx LocationTable,
     body: &'cx Body<'tcx>,
-    dominators: Dominators<BasicBlock>,
+    dominators: &'cx Dominators<BasicBlock>,
     borrow_set: &'cx BorrowSet<'tcx>,
 }
 
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index eb25d454339..43c4e1a9d6f 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -43,7 +43,6 @@ use rustc_target::abi::FieldIdx;
 
 use either::Either;
 use smallvec::SmallVec;
-use std::cell::OnceCell;
 use std::cell::RefCell;
 use std::collections::BTreeMap;
 use std::ops::Deref;
@@ -331,7 +330,6 @@ fn do_mir_borrowck<'tcx>(
                 used_mut: Default::default(),
                 used_mut_upvars: SmallVec::new(),
                 borrow_set: Rc::clone(&borrow_set),
-                dominators: Default::default(),
                 upvars: Vec::new(),
                 local_names: IndexVec::from_elem(None, &promoted_body.local_decls),
                 region_names: RefCell::default(),
@@ -360,7 +358,6 @@ fn do_mir_borrowck<'tcx>(
         used_mut: Default::default(),
         used_mut_upvars: SmallVec::new(),
         borrow_set: Rc::clone(&borrow_set),
-        dominators: Default::default(),
         upvars,
         local_names,
         region_names: RefCell::default(),
@@ -591,9 +588,6 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
     /// The set of borrows extracted from the MIR
     borrow_set: Rc<BorrowSet<'tcx>>,
 
-    /// Dominators for MIR
-    dominators: OnceCell<Dominators<BasicBlock>>,
-
     /// Information about upvars not necessarily preserved in types or MIR
     upvars: Vec<Upvar<'tcx>>,
 
@@ -2269,7 +2263,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     fn dominators(&self) -> &Dominators<BasicBlock> {
-        self.dominators.get_or_init(|| self.body.basic_blocks.dominators())
+        // `BasicBlocks` computes dominators on-demand and caches them.
+        self.body.basic_blocks.dominators()
     }
 }
 
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 309f23d9226..e9b5c47ce23 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -152,8 +152,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     let guar = ty.error_reported().err().unwrap_or_else(|| {
                         prev.report_mismatch(
                             &OpaqueHiddenType { ty, span: concrete_type.span },
+                            opaque_type_key.def_id,
                             infcx.tcx,
                         )
+                        .emit()
                     });
                     prev.ty = infcx.tcx.ty_error(guar);
                 }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 6a86237d79e..805843e5863 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -10,6 +10,7 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(never_type)]
+#![feature(impl_trait_in_assoc_type)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 994addf12eb..03be0654b50 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -16,7 +16,6 @@ use rustc_session::config::PrintRequest;
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::{MergeFunctions, PanicStrategy};
-use smallvec::{smallvec, SmallVec};
 use std::ffi::{CStr, CString};
 
 use std::path::Path;
@@ -132,6 +131,60 @@ pub fn time_trace_profiler_finish(file_name: &Path) {
     }
 }
 
+pub enum TargetFeatureFoldStrength<'a> {
+    // The feature is only tied when enabling the feature, disabling
+    // this feature shouldn't disable the tied feature.
+    EnableOnly(&'a str),
+    // The feature is tied for both enabling and disabling this feature.
+    Both(&'a str),
+}
+
+impl<'a> TargetFeatureFoldStrength<'a> {
+    fn as_str(&self) -> &'a str {
+        match self {
+            TargetFeatureFoldStrength::EnableOnly(feat) => feat,
+            TargetFeatureFoldStrength::Both(feat) => feat,
+        }
+    }
+}
+
+pub struct LLVMFeature<'a> {
+    pub llvm_feature_name: &'a str,
+    pub dependency: Option<TargetFeatureFoldStrength<'a>>,
+}
+
+impl<'a> LLVMFeature<'a> {
+    pub fn new(llvm_feature_name: &'a str) -> Self {
+        Self { llvm_feature_name, dependency: None }
+    }
+
+    pub fn with_dependency(
+        llvm_feature_name: &'a str,
+        dependency: TargetFeatureFoldStrength<'a>,
+    ) -> Self {
+        Self { llvm_feature_name, dependency: Some(dependency) }
+    }
+
+    pub fn contains(&self, feat: &str) -> bool {
+        self.iter().any(|dep| dep == feat)
+    }
+
+    pub fn iter(&'a self) -> impl Iterator<Item = &'a str> {
+        let dependencies = self.dependency.iter().map(|feat| feat.as_str());
+        std::iter::once(self.llvm_feature_name).chain(dependencies)
+    }
+}
+
+impl<'a> IntoIterator for LLVMFeature<'a> {
+    type Item = &'a str;
+    type IntoIter = impl Iterator<Item = &'a str>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        let dependencies = self.dependency.into_iter().map(|feat| feat.as_str());
+        std::iter::once(self.llvm_feature_name).chain(dependencies)
+    }
+}
+
 // WARNING: the features after applying `to_llvm_features` must be known
 // to LLVM or the feature detection code will walk past the end of the feature
 // array, leading to crashes.
@@ -147,36 +200,65 @@ pub fn time_trace_profiler_finish(file_name: &Path) {
 // Though note that Rust can also be build with an external precompiled version of LLVM
 // which might lead to failures if the oldest tested / supported LLVM version
 // doesn't yet support the relevant intrinsics
-pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> {
+pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
     let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch };
     match (arch, s) {
-        ("x86", "sse4.2") => smallvec!["sse4.2", "crc32"],
-        ("x86", "pclmulqdq") => smallvec!["pclmul"],
-        ("x86", "rdrand") => smallvec!["rdrnd"],
-        ("x86", "bmi1") => smallvec!["bmi"],
-        ("x86", "cmpxchg16b") => smallvec!["cx16"],
-        ("aarch64", "rcpc2") => smallvec!["rcpc-immo"],
-        ("aarch64", "dpb") => smallvec!["ccpp"],
-        ("aarch64", "dpb2") => smallvec!["ccdp"],
-        ("aarch64", "frintts") => smallvec!["fptoint"],
-        ("aarch64", "fcma") => smallvec!["complxnum"],
-        ("aarch64", "pmuv3") => smallvec!["perfmon"],
-        ("aarch64", "paca") => smallvec!["pauth"],
-        ("aarch64", "pacg") => smallvec!["pauth"],
-        // Rust ties fp and neon together. In LLVM neon implicitly enables fp,
-        // but we manually enable neon when a feature only implicitly enables fp
-        ("aarch64", "f32mm") => smallvec!["f32mm", "neon"],
-        ("aarch64", "f64mm") => smallvec!["f64mm", "neon"],
-        ("aarch64", "fhm") => smallvec!["fp16fml", "neon"],
-        ("aarch64", "fp16") => smallvec!["fullfp16", "neon"],
-        ("aarch64", "jsconv") => smallvec!["jsconv", "neon"],
-        ("aarch64", "sve") => smallvec!["sve", "neon"],
-        ("aarch64", "sve2") => smallvec!["sve2", "neon"],
-        ("aarch64", "sve2-aes") => smallvec!["sve2-aes", "neon"],
-        ("aarch64", "sve2-sm4") => smallvec!["sve2-sm4", "neon"],
-        ("aarch64", "sve2-sha3") => smallvec!["sve2-sha3", "neon"],
-        ("aarch64", "sve2-bitperm") => smallvec!["sve2-bitperm", "neon"],
-        (_, s) => smallvec![s],
+        ("x86", "sse4.2") => {
+            LLVMFeature::with_dependency("sse4.2", TargetFeatureFoldStrength::EnableOnly("crc32"))
+        }
+        ("x86", "pclmulqdq") => LLVMFeature::new("pclmul"),
+        ("x86", "rdrand") => LLVMFeature::new("rdrnd"),
+        ("x86", "bmi1") => LLVMFeature::new("bmi"),
+        ("x86", "cmpxchg16b") => LLVMFeature::new("cx16"),
+        ("aarch64", "rcpc2") => LLVMFeature::new("rcpc-immo"),
+        ("aarch64", "dpb") => LLVMFeature::new("ccpp"),
+        ("aarch64", "dpb2") => LLVMFeature::new("ccdp"),
+        ("aarch64", "frintts") => LLVMFeature::new("fptoint"),
+        ("aarch64", "fcma") => LLVMFeature::new("complxnum"),
+        ("aarch64", "pmuv3") => LLVMFeature::new("perfmon"),
+        ("aarch64", "paca") => LLVMFeature::new("pauth"),
+        ("aarch64", "pacg") => LLVMFeature::new("pauth"),
+        // Rust ties fp and neon together.
+        ("aarch64", "neon") => {
+            LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8"))
+        }
+        // In LLVM neon implicitly enables fp, but we manually enable
+        // neon when a feature only implicitly enables fp
+        ("aarch64", "f32mm") => {
+            LLVMFeature::with_dependency("f32mm", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "f64mm") => {
+            LLVMFeature::with_dependency("f64mm", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "fhm") => {
+            LLVMFeature::with_dependency("fp16fml", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "fp16") => {
+            LLVMFeature::with_dependency("fullfp16", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "jsconv") => {
+            LLVMFeature::with_dependency("jsconv", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "sve") => {
+            LLVMFeature::with_dependency("sve", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "sve2") => {
+            LLVMFeature::with_dependency("sve2", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "sve2-aes") => {
+            LLVMFeature::with_dependency("sve2-aes", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "sve2-sm4") => {
+            LLVMFeature::with_dependency("sve2-sm4", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "sve2-sha3") => {
+            LLVMFeature::with_dependency("sve2-sha3", TargetFeatureFoldStrength::EnableOnly("neon"))
+        }
+        ("aarch64", "sve2-bitperm") => LLVMFeature::with_dependency(
+            "sve2-bitperm",
+            TargetFeatureFoldStrength::EnableOnly("neon"),
+        ),
+        (_, s) => LLVMFeature::new(s),
     }
 }
 
@@ -274,18 +356,17 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
     let mut rustc_target_features = supported_target_features(sess)
         .iter()
         .map(|(feature, _gate)| {
-            let desc = if let Some(llvm_feature) = to_llvm_features(sess, *feature).first() {
-                // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
+            // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
+            let llvm_feature = to_llvm_features(sess, *feature).llvm_feature_name;
+            let desc =
                 match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {
                     Some(index) => {
                         known_llvm_target_features.insert(llvm_feature);
                         llvm_target_features[index].1
                     }
                     None => "",
-                }
-            } else {
-                ""
-            };
+                };
+
             (*feature, desc)
         })
         .collect::<Vec<_>>();
@@ -469,10 +550,19 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
             // passing requests down to LLVM. This means that all in-language
             // features also work on the command line instead of having two
             // different names when the LLVM name and the Rust name differ.
+            let llvm_feature = to_llvm_features(sess, feature);
+
             Some(
-                to_llvm_features(sess, feature)
-                    .into_iter()
-                    .map(move |f| format!("{}{}", enable_disable, f)),
+                std::iter::once(format!("{}{}", enable_disable, llvm_feature.llvm_feature_name))
+                    .chain(llvm_feature.dependency.into_iter().filter_map(move |feat| {
+                        match (enable_disable, feat) {
+                            ('-' | '+', TargetFeatureFoldStrength::Both(f))
+                            | ('+', TargetFeatureFoldStrength::EnableOnly(f)) => {
+                                Some(format!("{}{}", enable_disable, f))
+                            }
+                            _ => None,
+                        }
+                    })),
             )
         })
         .flatten();
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 1e57f4248d2..cd56f85cccd 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -144,7 +144,7 @@ pub fn get_linker<'a>(
             cmd,
             sess,
             target_cpu,
-            hinted_static: false,
+            hinted_static: None,
             is_ld: cc == Cc::No,
             is_gnu: flavor.is_gnu(),
         }) as Box<dyn Linker>,
@@ -214,7 +214,7 @@ pub struct GccLinker<'a> {
     cmd: Command,
     sess: &'a Session,
     target_cpu: &'a str,
-    hinted_static: bool, // Keeps track of the current hinting mode.
+    hinted_static: Option<bool>, // Keeps track of the current hinting mode.
     // Link as ld
     is_ld: bool,
     is_gnu: bool,
@@ -275,9 +275,9 @@ impl<'a> GccLinker<'a> {
         if !self.takes_hints() {
             return;
         }
-        if !self.hinted_static {
+        if self.hinted_static != Some(true) {
             self.linker_arg("-Bstatic");
-            self.hinted_static = true;
+            self.hinted_static = Some(true);
         }
     }
 
@@ -285,9 +285,9 @@ impl<'a> GccLinker<'a> {
         if !self.takes_hints() {
             return;
         }
-        if self.hinted_static {
+        if self.hinted_static != Some(false) {
             self.linker_arg("-Bdynamic");
-            self.hinted_static = false;
+            self.hinted_static = Some(false);
         }
     }
 
@@ -1484,25 +1484,25 @@ impl<'a> L4Bender<'a> {
 pub struct AixLinker<'a> {
     cmd: Command,
     sess: &'a Session,
-    hinted_static: bool,
+    hinted_static: Option<bool>,
 }
 
 impl<'a> AixLinker<'a> {
     pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
-        AixLinker { cmd: cmd, sess: sess, hinted_static: false }
+        AixLinker { cmd: cmd, sess: sess, hinted_static: None }
     }
 
     fn hint_static(&mut self) {
-        if !self.hinted_static {
+        if self.hinted_static != Some(true) {
             self.cmd.arg("-bstatic");
-            self.hinted_static = true;
+            self.hinted_static = Some(true);
         }
     }
 
     fn hint_dynamic(&mut self) {
-        if self.hinted_static {
+        if self.hinted_static != Some(false) {
             self.cmd.arg("-bdynamic");
-            self.hinted_static = false;
+            self.hinted_static = Some(false);
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 569599faa36..835074806e9 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -84,7 +84,7 @@ impl DefLocation {
 
 struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
     fx: &'mir FunctionCx<'a, 'tcx, Bx>,
-    dominators: Dominators<mir::BasicBlock>,
+    dominators: &'mir Dominators<mir::BasicBlock>,
     locals: IndexVec<mir::Local, LocalKind>,
 }
 
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index 4e80a285186..11ad5b49df2 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -58,11 +58,12 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
             // Types with identity (print the module path).
             ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
             | ty::FnDef(def_id, substs)
-            | ty::Alias(_, ty::AliasTy { def_id, substs, .. })
+            | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. })
             | ty::Closure(def_id, substs)
             | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
             ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
 
+            ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
             ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
             ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"),
         }
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index 594ed1ad2e7..a5db14d9102 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
@@ -26,7 +26,7 @@ rustc_index::newtype_index! {
     struct PreorderIndex {}
 }
 
-pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
+pub fn dominators<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
     // compute the post order index (rank) for each node
     let mut post_order_rank = IndexVec::from_elem_n(0, graph.num_nodes());
 
@@ -244,7 +244,10 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
 
     let start_node = graph.start_node();
     immediate_dominators[start_node] = None;
-    Dominators { start_node, post_order_rank, immediate_dominators }
+
+    let time = compute_access_time(start_node, &immediate_dominators);
+
+    Dominators { start_node, post_order_rank, immediate_dominators, time }
 }
 
 /// Evaluate the link-eval virtual forest, providing the currently minimum semi
@@ -316,6 +319,7 @@ pub struct Dominators<N: Idx> {
     // possible to get its full list of dominators by looking up the dominator
     // of each dominator. (See the `impl Iterator for Iter` definition).
     immediate_dominators: IndexVec<N, Option<N>>,
+    time: IndexVec<N, Time>,
 }
 
 impl<Node: Idx> Dominators<Node> {
@@ -333,12 +337,7 @@ impl<Node: Idx> Dominators<Node> {
     /// See the `impl Iterator for Iter` definition to understand how this works.
     pub fn dominators(&self, node: Node) -> Iter<'_, Node> {
         assert!(self.is_reachable(node), "node {node:?} is not reachable");
-        Iter { dominators: self, node: Some(node) }
-    }
-
-    pub fn dominates(&self, dom: Node, node: Node) -> bool {
-        // FIXME -- could be optimized by using post-order-rank
-        self.dominators(node).any(|n| n == dom)
+        Iter { dom_tree: self, node: Some(node) }
     }
 
     /// Provide deterministic ordering of nodes such that, if any two nodes have a dominator
@@ -348,10 +347,22 @@ impl<Node: Idx> Dominators<Node> {
     pub fn rank_partial_cmp(&self, lhs: Node, rhs: Node) -> Option<Ordering> {
         self.post_order_rank[rhs].partial_cmp(&self.post_order_rank[lhs])
     }
+
+    /// Returns true if `a` dominates `b`.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `b` is unreachable.
+    pub fn dominates(&self, a: Node, b: Node) -> bool {
+        let a = self.time[a];
+        let b = self.time[b];
+        assert!(b.start != 0, "node {b:?} is not reachable");
+        a.start <= b.start && b.finish <= a.finish
+    }
 }
 
 pub struct Iter<'dom, Node: Idx> {
-    dominators: &'dom Dominators<Node>,
+    dom_tree: &'dom Dominators<Node>,
     node: Option<Node>,
 }
 
@@ -360,10 +371,74 @@ impl<'dom, Node: Idx> Iterator for Iter<'dom, Node> {
 
     fn next(&mut self) -> Option<Self::Item> {
         if let Some(node) = self.node {
-            self.node = self.dominators.immediate_dominator(node);
+            self.node = self.dom_tree.immediate_dominator(node);
             Some(node)
         } else {
             None
         }
     }
 }
+
+/// Describes the number of vertices discovered at the time when processing of a particular vertex
+/// started and when it finished. Both values are zero for unreachable vertices.
+#[derive(Copy, Clone, Default, Debug)]
+struct Time {
+    start: u32,
+    finish: u32,
+}
+
+fn compute_access_time<N: Idx>(
+    start_node: N,
+    immediate_dominators: &IndexSlice<N, Option<N>>,
+) -> IndexVec<N, Time> {
+    // Transpose the dominator tree edges, so that child nodes of vertex v are stored in
+    // node[edges[v].start..edges[v].end].
+    let mut edges: IndexVec<N, std::ops::Range<u32>> =
+        IndexVec::from_elem(0..0, immediate_dominators);
+    for &idom in immediate_dominators.iter() {
+        if let Some(idom) = idom {
+            edges[idom].end += 1;
+        }
+    }
+    let mut m = 0;
+    for e in edges.iter_mut() {
+        m += e.end;
+        e.start = m;
+        e.end = m;
+    }
+    let mut node = IndexVec::from_elem_n(Idx::new(0), m.try_into().unwrap());
+    for (i, &idom) in immediate_dominators.iter_enumerated() {
+        if let Some(idom) = idom {
+            edges[idom].start -= 1;
+            node[edges[idom].start] = i;
+        }
+    }
+
+    // Perform a depth-first search of the dominator tree. Record the number of vertices discovered
+    // when vertex v is discovered first as time[v].start, and when its processing is finished as
+    // time[v].finish.
+    let mut time: IndexVec<N, Time> = IndexVec::from_elem(Time::default(), immediate_dominators);
+    let mut stack = Vec::new();
+
+    let mut discovered = 1;
+    stack.push(start_node);
+    time[start_node].start = discovered;
+
+    while let Some(&i) = stack.last() {
+        let e = &mut edges[i];
+        if e.start == e.end {
+            // Finish processing vertex i.
+            time[i].finish = discovered;
+            stack.pop();
+        } else {
+            let j = node[e.start];
+            e.start += 1;
+            // Start processing vertex j.
+            discovered += 1;
+            time[j].start = discovered;
+            stack.push(j);
+        }
+    }
+
+    time
+}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 5a80024f19b..074fbb1322c 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -478,6 +478,7 @@ pub enum StashKey {
     MaybeFruTypo,
     CallAssocMethod,
     TraitMissingMethod,
+    OpaqueHiddenTypeMismatch,
 }
 
 fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index 1cf93c86f4f..d6d1498d708 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -1,6 +1,5 @@
 use crate::errors::AutoDerefReachedRecursionLimit;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
-use crate::traits::NormalizeExt;
 use crate::traits::{self, TraitEngine, TraitEngineExt};
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::ty::TypeVisitableExt;
@@ -9,6 +8,7 @@ use rustc_session::Limit;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::Span;
+use rustc_trait_selection::traits::StructurallyNormalizeExt;
 
 #[derive(Copy, Clone, Debug)]
 pub enum AutoderefKind {
@@ -66,14 +66,27 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
         }
 
         // Otherwise, deref if type is derefable:
-        let (kind, new_ty) =
-            if let Some(mt) = self.state.cur_ty.builtin_deref(self.include_raw_pointers) {
-                (AutoderefKind::Builtin, mt.ty)
-            } else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) {
-                (AutoderefKind::Overloaded, ty)
+        let (kind, new_ty) = if let Some(ty::TypeAndMut { ty, .. }) =
+            self.state.cur_ty.builtin_deref(self.include_raw_pointers)
+        {
+            debug_assert_eq!(ty, self.infcx.resolve_vars_if_possible(ty));
+            // NOTE: we may still need to normalize the built-in deref in case
+            // we have some type like `&<Ty as Trait>::Assoc`, since users of
+            // autoderef expect this type to have been structurally normalized.
+            if self.infcx.tcx.trait_solver_next()
+                && let ty::Alias(ty::Projection, _) = ty.kind()
+            {
+                let (normalized_ty, obligations) = self.structurally_normalize(ty)?;
+                self.state.obligations.extend(obligations);
+                (AutoderefKind::Builtin, normalized_ty)
             } else {
-                return None;
-            };
+                (AutoderefKind::Builtin, ty)
+            }
+        } else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) {
+            (AutoderefKind::Overloaded, ty)
+        } else {
+            return None;
+        };
 
         if new_ty.references_error() {
             return None;
@@ -119,14 +132,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
 
     fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
         debug!("overloaded_deref_ty({:?})", ty);
-
         let tcx = self.infcx.tcx;
 
         // <ty as Deref>
         let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]);
-
         let cause = traits::ObligationCause::misc(self.span, self.body_id);
-
         let obligation = traits::Obligation::new(
             tcx,
             cause.clone(),
@@ -138,26 +148,48 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
             return None;
         }
 
-        let normalized_ty = self
+        let (normalized_ty, obligations) =
+            self.structurally_normalize(tcx.mk_projection(tcx.lang_items().deref_target()?, [ty]))?;
+        debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
+        self.state.obligations.extend(obligations);
+
+        Some(self.infcx.resolve_vars_if_possible(normalized_ty))
+    }
+
+    #[instrument(level = "debug", skip(self), ret)]
+    pub fn structurally_normalize(
+        &self,
+        ty: Ty<'tcx>,
+    ) -> Option<(Ty<'tcx>, Vec<traits::PredicateObligation<'tcx>>)> {
+        let tcx = self.infcx.tcx;
+        let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(tcx);
+
+        let cause = traits::ObligationCause::misc(self.span, self.body_id);
+        let normalized_ty = match self
             .infcx
             .at(&cause, self.param_env)
-            .normalize(tcx.mk_projection(tcx.lang_items().deref_target()?, trait_ref.substs));
-        let mut fulfillcx = <dyn TraitEngine<'tcx>>::new_in_snapshot(tcx);
-        let normalized_ty =
-            normalized_ty.into_value_registering_obligations(self.infcx, &mut *fulfillcx);
-        let errors = fulfillcx.select_where_possible(&self.infcx);
+            .structurally_normalize(ty, &mut *fulfill_cx)
+        {
+            Ok(normalized_ty) => normalized_ty,
+            Err(errors) => {
+                // This shouldn't happen, except for evaluate/fulfill mismatches,
+                // but that's not a reason for an ICE (`predicate_may_hold` is conservative
+                // by design).
+                debug!(?errors, "encountered errors while fulfilling");
+                return None;
+            }
+        };
+
+        let errors = fulfill_cx.select_where_possible(&self.infcx);
         if !errors.is_empty() {
             // This shouldn't happen, except for evaluate/fulfill mismatches,
             // but that's not a reason for an ICE (`predicate_may_hold` is conservative
             // by design).
-            debug!("overloaded_deref_ty: encountered errors {:?} while fulfilling", errors);
+            debug!(?errors, "encountered errors while fulfilling");
             return None;
         }
-        let obligations = fulfillcx.pending_obligations();
-        debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
-        self.state.obligations.extend(obligations);
 
-        Some(self.infcx.resolve_vars_if_possible(normalized_ty))
+        Some((normalized_ty, fulfill_cx.pending_obligations()))
     }
 
     /// Returns the final type we ended up with, which may be an inference
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index a33990813b8..e5b5dae551e 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -427,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
             //   supertrait).
             if let ty::Alias(ty::Projection, projection) = ty.kind() {
                 projection.substs == trait_identity_substs
+                    // FIXME(return_type_notation): This check should be more robust
+                    && !tcx.is_impl_trait_in_trait(projection.def_id)
                     && tcx.associated_item(projection.def_id).container_id(tcx)
                         == def_id.to_def_id()
             } else {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index ca430a5e863..97c6cb491d1 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -584,7 +584,8 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
                 debug!(?concrete_type, "found constraint");
                 if let Some(prev) = &mut self.found {
                     if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
-                        let guar = prev.report_mismatch(&concrete_type, self.tcx);
+                        let guar =
+                            prev.report_mismatch(&concrete_type, self.def_id, self.tcx).emit();
                         prev.ty = self.tcx.ty_error(guar);
                     }
                 } else {
@@ -678,10 +679,10 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
     // Only check against typeck if we didn't already error
     if !hidden.ty.references_error() {
         for concrete_type in locator.typeck_types {
-            if tcx.erase_regions(concrete_type.ty) != tcx.erase_regions(hidden.ty)
+            if concrete_type.ty != tcx.erase_regions(hidden.ty)
                 && !(concrete_type, hidden).references_error()
             {
-                hidden.report_mismatch(&concrete_type, tcx);
+                hidden.report_mismatch(&concrete_type, def_id, tcx).emit();
             }
         }
     }
@@ -722,7 +723,7 @@ fn find_opaque_ty_constraints_for_rpit(
                 if concrete_type.ty != self.found.ty
                     && !(concrete_type, self.found).references_error()
                 {
-                    self.found.report_mismatch(&concrete_type, self.tcx);
+                    self.found.report_mismatch(&concrete_type, self.def_id, self.tcx).emit();
                 }
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index bf8259ff70f..bfabd44bb57 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -32,6 +32,7 @@ pub(super) fn check_fn<'a, 'tcx>(
     fn_def_id: LocalDefId,
     body: &'tcx hir::Body<'tcx>,
     can_be_generator: Option<hir::Movability>,
+    params_can_be_unsized: bool,
 ) -> Option<GeneratorTypes<'tcx>> {
     let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id);
 
@@ -94,7 +95,7 @@ pub(super) fn check_fn<'a, 'tcx>(
         // The check for a non-trivial pattern is a hack to avoid duplicate warnings
         // for simple cases like `fn foo(x: Trait)`,
         // where we would error once on the parameter as a whole, and once on the binding `x`.
-        if param.pat.simple_ident().is_none() && !tcx.features().unsized_fn_params {
+        if param.pat.simple_ident().is_none() && !params_can_be_unsized {
             fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
         }
 
@@ -103,24 +104,8 @@ pub(super) fn check_fn<'a, 'tcx>(
 
     fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
 
-    if let ty::Dynamic(_, _, ty::Dyn) = declared_ret_ty.kind() {
-        // FIXME: We need to verify that the return type is `Sized` after the return expression has
-        // been evaluated so that we have types available for all the nodes being returned, but that
-        // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
-        // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
-        // while keeping the current ordering we will ignore the tail expression's type because we
-        // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
-        // because we will trigger "unreachable expression" lints unconditionally.
-        // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
-        // case that a newcomer might make, returning a bare trait, and in that case we populate
-        // the tail expression's type so that the suggestion will be correct, but ignore all other
-        // possible cases.
-        fcx.check_expr(&body.value);
-        fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
-    } else {
-        fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
-        fcx.check_return_expr(&body.value, false);
-    }
+    fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
+    fcx.check_return_expr(&body.value, false);
 
     // We insert the deferred_generator_interiors entry after visiting the body.
     // This ensures that all nested generators appear before the entry of this generator.
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 7046269c2de..9659a0ec13d 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -89,6 +89,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             expr_def_id,
             body,
             closure.movability,
+            // Closure "rust-call" ABI doesn't support unsized params
+            false,
         );
 
         let parent_substs = InternalSubsts::identity_for_item(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 039316c74dd..9721e3b427d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -35,7 +35,9 @@ use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 use rustc_target::abi::FieldIdx;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
-use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt};
+use rustc_trait_selection::traits::{
+    self, NormalizeExt, ObligationCauseCode, ObligationCtxt, StructurallyNormalizeExt,
+};
 
 use std::collections::hash_map::Entry;
 use std::slice;
@@ -1460,10 +1462,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Resolves `typ` by a single level if `typ` is a type variable.
+    ///
+    /// When the new solver is enabled, this will also attempt to normalize
+    /// the type if it's a projection (note that it will not deeply normalize
+    /// projections within the type, just the outermost layer of the type).
+    ///
     /// If no resolution is possible, then an error is reported.
     /// Numeric inference variables may be left unresolved.
     pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let ty = self.resolve_vars_with_obligations(ty);
+        let mut ty = self.resolve_vars_with_obligations(ty);
+
+        if self.tcx.trait_solver_next()
+            && let ty::Alias(ty::Projection, _) = ty.kind()
+        {
+            match self
+                .at(&self.misc(sp), self.param_env)
+                .structurally_normalize(ty, &mut **self.fulfillment_cx.borrow_mut())
+            {
+                Ok(normalized_ty) => {
+                    ty = normalized_ty;
+                },
+                Err(errors) => {
+                    let guar = self.err_ctxt().report_fulfillment_errors(&errors);
+                    return self.tcx.ty_error(guar);
+                }
+            }
+        }
+
         if !ty.is_ty_var() {
             ty
         } else {
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 64426c4cbbb..b97b55d8f7e 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -212,7 +212,7 @@ fn typeck_with_fallback<'tcx>(
         let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
         let fn_sig = fcx.normalize(body.value.span, fn_sig);
 
-        check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
+        check_fn(&mut fcx, fn_sig, decl, def_id, body, None, tcx.features().unsized_fn_params);
     } else {
         let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
             Some(fcx.next_ty_var(TypeVariableOrigin {
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 59bf45f0ed2..98529b66602 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -471,7 +471,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
             self_ty, method_self_ty, self.span, pick
         );
         let cause = self.cause(
-            self.span,
+            self.self_expr.span,
             ObligationCauseCode::UnifyReceiver(Box::new(UnifyReceiverContext {
                 assoc_item: pick.item,
                 param_env: self.param_env,
@@ -482,13 +482,22 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
             Ok(InferOk { obligations, value: () }) => {
                 self.register_predicates(obligations);
             }
-            Err(_) => {
-                span_bug!(
-                    self.span,
-                    "{} was a subtype of {} but now is not?",
-                    self_ty,
-                    method_self_ty
-                );
+            Err(terr) => {
+                // FIXME(arbitrary_self_types): We probably should limit the
+                // situations where this can occur by adding additional restrictions
+                // to the feature, like the self type can't reference method substs.
+                if self.tcx.features().arbitrary_self_types {
+                    self.err_ctxt()
+                        .report_mismatched_types(&cause, method_self_ty, self_ty, terr)
+                        .emit();
+                } else {
+                    span_bug!(
+                        self.span,
+                        "{} was a subtype of {} but now is not?",
+                        self_ty,
+                        method_self_ty
+                    );
+                }
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index a4c6dd4332a..0f21fc1e662 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -5,11 +5,10 @@
 use crate::FnCtxt;
 use hir::def_id::LocalDefId;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::ErrorGuaranteed;
+use rustc_errors::{ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
-use rustc_infer::infer::InferCtxt;
 use rustc_middle::hir::place::Place as HirPlace;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
@@ -83,10 +82,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         wbcx.typeck_results.treat_byte_string_as_slice =
             mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice);
 
-        if let Some(e) = self.tainted_by_errors() {
-            wbcx.typeck_results.tainted_by_errors = Some(e);
-        }
-
         debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results);
 
         self.tcx.arena.alloc(wbcx.typeck_results)
@@ -119,12 +114,21 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     ) -> WritebackCx<'cx, 'tcx> {
         let owner = body.id().hir_id.owner;
 
-        WritebackCx {
+        let mut wbcx = WritebackCx {
             fcx,
             typeck_results: ty::TypeckResults::new(owner),
             body,
             rustc_dump_user_substs,
+        };
+
+        // HACK: We specifically don't want the (opaque) error from tainting our
+        // inference context. That'll prevent us from doing opaque type inference
+        // later on in borrowck, which affects diagnostic spans pretty negatively.
+        if let Some(e) = fcx.tainted_by_errors() {
+            wbcx.typeck_results.tainted_by_errors = Some(e);
         }
+
+        wbcx
     }
 
     fn tcx(&self) -> TyCtxt<'tcx> {
@@ -579,13 +583,26 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 continue;
             }
 
-            let hidden_type = hidden_type.remap_generic_params_to_declaration_params(
-                opaque_type_key,
-                self.fcx.infcx.tcx,
-                true,
-            );
-
-            self.typeck_results.concrete_opaque_types.insert(opaque_type_key.def_id, hidden_type);
+            let hidden_type =
+                self.tcx().erase_regions(hidden_type.remap_generic_params_to_declaration_params(
+                    opaque_type_key,
+                    self.tcx(),
+                    true,
+                ));
+
+            if let Some(last_opaque_ty) = self
+                .typeck_results
+                .concrete_opaque_types
+                .insert(opaque_type_key.def_id, hidden_type)
+                && last_opaque_ty.ty != hidden_type.ty
+            {
+                hidden_type
+                    .report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx())
+                    .stash(
+                        self.tcx().def_span(opaque_type_key.def_id),
+                        StashKey::OpaqueHiddenTypeMismatch,
+                    );
+            }
         }
     }
 
@@ -737,8 +754,7 @@ impl Locatable for hir::HirId {
 /// The Resolver. This is the type folding engine that detects
 /// unresolved types and so forth.
 struct Resolver<'cx, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    infcx: &'cx InferCtxt<'tcx>,
+    fcx: &'cx FnCtxt<'cx, 'tcx>,
     span: &'cx dyn Locatable,
     body: &'tcx hir::Body<'tcx>,
 
@@ -752,18 +768,18 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
         span: &'cx dyn Locatable,
         body: &'tcx hir::Body<'tcx>,
     ) -> Resolver<'cx, 'tcx> {
-        Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: None }
+        Resolver { fcx, span, body, replaced_with_error: None }
     }
 
     fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
-        match self.tcx.sess.has_errors() {
+        match self.fcx.tcx.sess.has_errors() {
             Some(e) => e,
             None => self
-                .infcx
+                .fcx
                 .err_ctxt()
                 .emit_inference_failure_err(
-                    self.tcx.hir().body_owner_def_id(self.body.id()),
-                    self.span.to_span(self.tcx),
+                    self.fcx.tcx.hir().body_owner_def_id(self.body.id()),
+                    self.span.to_span(self.fcx.tcx),
                     p.into(),
                     E0282,
                     false,
@@ -795,40 +811,46 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEarlyRegions<'tcx> {
 
 impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
     fn interner(&self) -> TyCtxt<'tcx> {
-        self.tcx
+        self.fcx.tcx
     }
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        match self.infcx.fully_resolve(t) {
+        match self.fcx.fully_resolve(t) {
+            Ok(t) if self.fcx.tcx.trait_solver_next() => {
+                // We must normalize erasing regions here, since later lints
+                // expect that types that show up in the typeck are fully
+                // normalized.
+                self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t).unwrap_or(t)
+            }
             Ok(t) => {
                 // Do not anonymize late-bound regions
                 // (e.g. keep `for<'a>` named `for<'a>`).
                 // This allows NLL to generate error messages that
                 // refer to the higher-ranked lifetime names written by the user.
-                EraseEarlyRegions { tcx: self.tcx }.fold_ty(t)
+                EraseEarlyRegions { tcx: self.fcx.tcx }.fold_ty(t)
             }
             Err(_) => {
                 debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
                 let e = self.report_error(t);
                 self.replaced_with_error = Some(e);
-                self.interner().ty_error(e)
+                self.fcx.tcx.ty_error(e)
             }
         }
     }
 
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         debug_assert!(!r.is_late_bound(), "Should not be resolving bound region.");
-        self.tcx.lifetimes.re_erased
+        self.fcx.tcx.lifetimes.re_erased
     }
 
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
-        match self.infcx.fully_resolve(ct) {
-            Ok(ct) => self.tcx.erase_regions(ct),
+        match self.fcx.fully_resolve(ct) {
+            Ok(ct) => self.fcx.tcx.erase_regions(ct),
             Err(_) => {
                 debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
                 let e = self.report_error(ct);
                 self.replaced_with_error = Some(e);
-                self.interner().const_error(ct.ty(), e)
+                self.fcx.tcx.const_error(ct.ty(), e)
             }
         }
     }
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index a5639404faf..e1658d3ff82 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -521,18 +521,18 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass
 
 lint_opaque_hidden_inferred_bound_sugg = add this bound
 
-lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value does nothing
+lint_dropping_references = calls to `std::mem::drop` with a reference instead of an owned value does nothing
     .label = argument has type `{$arg_ty}`
     .note = use `let _ = ...` to ignore the expression or result
 
-lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy` does nothing
+lint_dropping_copy_types = calls to `std::mem::drop` with a value that implements `Copy` does nothing
     .label = argument has type `{$arg_ty}`
     .note = use `let _ = ...` to ignore the expression or result
 
-lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value does nothing
+lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing
     .label = argument has type `{$arg_ty}`
     .note = use `let _ = ...` to ignore the expression or result
 
-lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy` does nothing
+lint_forgetting_copy_types = calls to `std::mem::forget` with a value that implements `Copy` does nothing
     .label = argument has type `{$arg_ty}`
     .note = use `let _ = ...` to ignore the expression or result
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs
index 259abc2af11..ed2b384805e 100644
--- a/compiler/rustc_lint/src/drop_forget_useless.rs
+++ b/compiler/rustc_lint/src/drop_forget_useless.rs
@@ -7,7 +7,7 @@ use crate::{
 };
 
 declare_lint! {
-    /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference
+    /// The `dropping_references` lint checks for calls to `std::mem::drop` with a reference
     /// instead of an owned value.
     ///
     /// ### Example
@@ -29,13 +29,13 @@ declare_lint! {
     /// reference itself, which is a no-op. It will not call the `drop` method (from
     /// the `Drop` trait implementation) on the underlying referenced value, which
     /// is likely what was intended.
-    pub DROP_REF,
+    pub DROPPING_REFERENCES,
     Warn,
     "calls to `std::mem::drop` with a reference instead of an owned value"
 }
 
 declare_lint! {
-    /// The `forget_ref` lint checks for calls to `std::mem::forget` with a reference
+    /// The `forgetting_references` lint checks for calls to `std::mem::forget` with a reference
     /// instead of an owned value.
     ///
     /// ### Example
@@ -52,13 +52,13 @@ declare_lint! {
     /// Calling `forget` on a reference will only forget the
     /// reference itself, which is a no-op. It will not forget the underlying
     /// referenced value, which is likely what was intended.
-    pub FORGET_REF,
+    pub FORGETTING_REFERENCES,
     Warn,
     "calls to `std::mem::forget` with a reference instead of an owned value"
 }
 
 declare_lint! {
-    /// The `drop_copy` lint checks for calls to `std::mem::drop` with a value
+    /// The `dropping_copy_types` lint checks for calls to `std::mem::drop` with a value
     /// that derives the Copy trait.
     ///
     /// ### Example
@@ -76,13 +76,13 @@ declare_lint! {
     /// Calling `std::mem::drop` [does nothing for types that
     /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
     /// value will be copied and moved into the function on invocation.
-    pub DROP_COPY,
+    pub DROPPING_COPY_TYPES,
     Warn,
     "calls to `std::mem::drop` with a value that implements Copy"
 }
 
 declare_lint! {
-    /// The `forget_copy` lint checks for calls to `std::mem::forget` with a value
+    /// The `forgetting_copy_types` lint checks for calls to `std::mem::forget` with a value
     /// that derives the Copy trait.
     ///
     /// ### Example
@@ -104,12 +104,12 @@ declare_lint! {
     /// An alternative, but also valid, explanation is that Copy types do not
     /// implement the Drop trait, which means they have no destructors. Without a
     /// destructor, there is nothing for `std::mem::forget` to ignore.
-    pub FORGET_COPY,
+    pub FORGETTING_COPY_TYPES,
     Warn,
     "calls to `std::mem::forget` with a value that implements Copy"
 }
 
-declare_lint_pass!(DropForgetUseless => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]);
+declare_lint_pass!(DropForgetUseless => [DROPPING_REFERENCES, FORGETTING_REFERENCES, DROPPING_COPY_TYPES, FORGETTING_COPY_TYPES]);
 
 impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
@@ -123,16 +123,16 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
             let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
             match fn_name {
                 sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
-                    cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, label: arg.span });
+                    cx.emit_spanned_lint(DROPPING_REFERENCES, expr.span, DropRefDiag { arg_ty, label: arg.span });
                 },
                 sym::mem_forget if arg_ty.is_ref() => {
-                    cx.emit_spanned_lint(FORGET_REF, expr.span, ForgetRefDiag { arg_ty, label: arg.span });
+                    cx.emit_spanned_lint(FORGETTING_REFERENCES, expr.span, ForgetRefDiag { arg_ty, label: arg.span });
                 },
                 sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
-                    cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, label: arg.span });
+                    cx.emit_spanned_lint(DROPPING_COPY_TYPES, expr.span, DropCopyDiag { arg_ty, label: arg.span });
                 }
                 sym::mem_forget if is_copy => {
-                    cx.emit_spanned_lint(FORGET_COPY, expr.span, ForgetCopyDiag { arg_ty, label: arg.span });
+                    cx.emit_spanned_lint(FORGETTING_COPY_TYPES, expr.span, ForgetCopyDiag { arg_ty, label: arg.span });
                 }
                 _ => return,
             };
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 8e48806b504..de1c2be2875 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -662,9 +662,9 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
     pub end_span: Span,
 }
 
-// drop_ref.rs
+// drop_forget_useless.rs
 #[derive(LintDiagnostic)]
-#[diag(lint_drop_ref)]
+#[diag(lint_dropping_references)]
 #[note]
 pub struct DropRefDiag<'a> {
     pub arg_ty: Ty<'a>,
@@ -673,7 +673,7 @@ pub struct DropRefDiag<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(lint_drop_copy)]
+#[diag(lint_dropping_copy_types)]
 #[note]
 pub struct DropCopyDiag<'a> {
     pub arg_ty: Ty<'a>,
@@ -682,7 +682,7 @@ pub struct DropCopyDiag<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(lint_forget_ref)]
+#[diag(lint_forgetting_references)]
 #[note]
 pub struct ForgetRefDiag<'a> {
     pub arg_ty: Ty<'a>,
@@ -691,7 +691,7 @@ pub struct ForgetRefDiag<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(lint_forget_copy)]
+#[diag(lint_forgetting_copy_types)]
 #[note]
 pub struct ForgetCopyDiag<'a> {
     pub arg_ty: Ty<'a>,
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 98ea9dc7501..209bf395624 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -148,11 +148,15 @@ impl CStore {
         assert_eq!(self.metas.len(), self.stable_crate_ids.len());
         let num = CrateNum::new(self.stable_crate_ids.len());
         if let Some(&existing) = self.stable_crate_ids.get(&root.stable_crate_id()) {
-            let crate_name0 = root.name();
-            if let Some(crate_name1) = self.metas[existing].as_ref().map(|data| data.name()) {
+            // Check for (potential) conflicts with the local crate
+            if existing == LOCAL_CRATE {
+                Err(CrateError::SymbolConflictsCurrent(root.name()))
+            } else if let Some(crate_name1) = self.metas[existing].as_ref().map(|data| data.name())
+            {
+                let crate_name0 = root.name();
                 Err(CrateError::StableCrateIdCollision(crate_name0, crate_name1))
             } else {
-                Err(CrateError::SymbolConflictsCurrent(crate_name0))
+                Err(CrateError::NotFound(root.name()))
             }
         } else {
             self.metas.push(None);
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 6ec691f73b7..1aab4adf0b3 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -961,6 +961,7 @@ pub(crate) enum CrateError {
     DlSym(String),
     LocatorCombined(Box<CombinedLocatorError>),
     NonDylibPlugin(Symbol),
+    NotFound(Symbol),
 }
 
 enum MetadataError<'a> {
@@ -1131,6 +1132,18 @@ impl CrateError {
             CrateError::NonDylibPlugin(crate_name) => {
                 sess.emit_err(errors::NoDylibPlugin { span, crate_name });
             }
+            CrateError::NotFound(crate_name) => {
+                sess.emit_err(errors::CannotFindCrate {
+                    span,
+                    crate_name,
+                    add_info: String::new(),
+                    missing_core,
+                    current_crate: sess.opts.crate_name.clone().unwrap_or("<unknown>".to_string()),
+                    is_nightly_build: sess.is_nightly_build(),
+                    profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime),
+                    locator_triple: sess.opts.target_triple.clone(),
+                });
+            }
         }
     }
 }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 364269095e0..7425963d30f 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -323,7 +323,7 @@ provide! { tcx, def_id, other, cdata,
 
     extra_filename => { cdata.root.extra_filename.clone() }
 
-    traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
+    traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
     trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }
     implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
     crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 40723f41959..f067bca4b0b 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1938,7 +1938,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
     fn encode_traits(&mut self) -> LazyArray<DefIndex> {
         empty_proc_macro!(self);
-        self.lazy_array(self.tcx.traits_in_crate(LOCAL_CRATE).iter().map(|def_id| def_id.index))
+        self.lazy_array(self.tcx.traits(LOCAL_CRATE).iter().map(|def_id| def_id.index))
     }
 
     /// Encodes an index, mapping each trait to its (local) implementations.
@@ -2329,7 +2329,7 @@ pub fn provide(providers: &mut Providers) {
                 .get(&def_id)
                 .expect("no traits in scope for a doc link")
         },
-        traits_in_crate: |tcx, LocalCrate| {
+        traits: |tcx, LocalCrate| {
             let mut traits = Vec::new();
             for id in tcx.hir().items() {
                 if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 1319ddbb877..9d70dbfa072 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -27,6 +27,7 @@ struct Cache {
     switch_sources: OnceCell<SwitchSources>,
     is_cyclic: OnceCell<bool>,
     postorder: OnceCell<Vec<BasicBlock>>,
+    dominators: OnceCell<Dominators<BasicBlock>>,
 }
 
 impl<'tcx> BasicBlocks<'tcx> {
@@ -41,8 +42,8 @@ impl<'tcx> BasicBlocks<'tcx> {
         *self.cache.is_cyclic.get_or_init(|| graph::is_cyclic(self))
     }
 
-    pub fn dominators(&self) -> Dominators<BasicBlock> {
-        dominators(&self)
+    pub fn dominators(&self) -> &Dominators<BasicBlock> {
+        self.cache.dominators.get_or_init(|| dominators(self))
     }
 
     /// Returns predecessors for each basic block.
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 33b7fe0c2dc..21faf1958e9 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -749,6 +749,29 @@ pub enum TerminatorKind<'tcx> {
     },
 }
 
+impl TerminatorKind<'_> {
+    /// Returns a simple string representation of a `TerminatorKind` variant, independent of any
+    /// values it might hold (e.g. `TerminatorKind::Call` always returns `"Call"`).
+    pub const fn name(&self) -> &'static str {
+        match self {
+            TerminatorKind::Goto { .. } => "Goto",
+            TerminatorKind::SwitchInt { .. } => "SwitchInt",
+            TerminatorKind::Resume => "Resume",
+            TerminatorKind::Terminate => "Terminate",
+            TerminatorKind::Return => "Return",
+            TerminatorKind::Unreachable => "Unreachable",
+            TerminatorKind::Drop { .. } => "Drop",
+            TerminatorKind::Call { .. } => "Call",
+            TerminatorKind::Assert { .. } => "Assert",
+            TerminatorKind::Yield { .. } => "Yield",
+            TerminatorKind::GeneratorDrop => "GeneratorDrop",
+            TerminatorKind::FalseEdge { .. } => "FalseEdge",
+            TerminatorKind::FalseUnwind { .. } => "FalseUnwind",
+            TerminatorKind::InlineAsm { .. } => "InlineAsm",
+        }
+    }
+}
+
 /// Action to be taken when a stack unwind happens.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
 #[derive(TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index f5b42c80487..1528be42f6a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -38,7 +38,10 @@ use crate::traits::query::{
     OutlivesBound,
 };
 use crate::traits::specialization_graph;
-use crate::traits::{self, ImplSource};
+use crate::traits::{
+    CanonicalChalkEnvironmentAndGoal, CodegenObligationError, EvaluationResult, ImplSource,
+    ObjectSafetyViolation, ObligationCause, OverflowError, WellFormedLoc,
+};
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::layout::ValidityRequirement;
 use crate::ty::subst::{GenericArg, SubstsRef};
@@ -1273,7 +1276,7 @@ rustc_queries! {
 
     query codegen_select_candidate(
         key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
-    ) -> Result<&'tcx ImplSource<'tcx, ()>, traits::CodegenObligationError> {
+    ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
         cache_on_disk_if { true }
         desc { |tcx| "computing candidate for `{}`", key.1 }
     }
@@ -1294,7 +1297,7 @@ rustc_queries! {
         desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
         cache_on_disk_if { true }
     }
-    query object_safety_violations(trait_id: DefId) -> &'tcx [traits::ObjectSafetyViolation] {
+    query object_safety_violations(trait_id: DefId) -> &'tcx [ObjectSafetyViolation] {
         desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
     }
     query check_is_object_safe(trait_id: DefId) -> bool {
@@ -1838,8 +1841,7 @@ rustc_queries! {
     }
 
     /// A list of all traits in a crate, used by rustdoc and error reporting.
-    /// NOTE: Not named just `traits` due to a naming conflict.
-    query traits_in_crate(_: CrateNum) -> &'tcx [DefId] {
+    query traits(_: CrateNum) -> &'tcx [DefId] {
         desc { "fetching all traits in a crate" }
         separate_provide_extern
     }
@@ -1953,12 +1955,12 @@ rustc_queries! {
     /// `infcx.predicate_must_hold()` instead.
     query evaluate_obligation(
         goal: CanonicalPredicateGoal<'tcx>
-    ) -> Result<traits::EvaluationResult, traits::OverflowError> {
+    ) -> Result<EvaluationResult, OverflowError> {
         desc { "evaluating trait selection obligation `{}`", goal.value.value }
     }
 
     query evaluate_goal(
-        goal: traits::CanonicalChalkEnvironmentAndGoal<'tcx>
+        goal: CanonicalChalkEnvironmentAndGoal<'tcx>
     ) -> Result<
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
         NoSolution
@@ -2128,8 +2130,8 @@ rustc_queries! {
     /// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
     /// because the `ty::Ty`-based wfcheck is always run.
     query diagnostic_hir_wf_check(
-        key: (ty::Predicate<'tcx>, traits::WellFormedLoc)
-    ) -> &'tcx Option<traits::ObligationCause<'tcx>> {
+        key: (ty::Predicate<'tcx>, WellFormedLoc)
+    ) -> &'tcx Option<ObligationCause<'tcx>> {
         arena_cache
         eval_always
         no_hash
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 2f0b07d4c71..5b0b40cbfd9 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -701,9 +701,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
     }
 
     pub fn borrow_nested_obligations(&self) -> &[N] {
-        match &self {
-            ImplSource::UserDefined(i) => &i.nested[..],
-            ImplSource::Param(n, _) => &n,
+        match self {
+            ImplSource::UserDefined(i) => &i.nested,
+            ImplSource::Param(n, _) => n,
             ImplSource::Builtin(i) => &i.nested,
             ImplSource::AutoImpl(d) => &d.nested,
             ImplSource::Closure(c) => &c.nested,
@@ -717,6 +717,23 @@ impl<'tcx, N> ImplSource<'tcx, N> {
         }
     }
 
+    pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
+        match self {
+            ImplSource::UserDefined(i) => &mut i.nested,
+            ImplSource::Param(n, _) => n,
+            ImplSource::Builtin(i) => &mut i.nested,
+            ImplSource::AutoImpl(d) => &mut d.nested,
+            ImplSource::Closure(c) => &mut c.nested,
+            ImplSource::Generator(c) => &mut c.nested,
+            ImplSource::Future(c) => &mut c.nested,
+            ImplSource::Object(d) => &mut d.nested,
+            ImplSource::FnPointer(d) => &mut d.nested,
+            ImplSource::TraitAlias(d) => &mut d.nested,
+            ImplSource::TraitUpcasting(d) => &mut d.nested,
+            ImplSource::ConstDestruct(i) => &mut i.nested,
+        }
+    }
+
     pub fn map<M, F>(self, f: F) -> ImplSource<'tcx, M>
     where
         F: FnMut(N) -> M,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index bbea3e1412b..5393dba8c2e 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1199,7 +1199,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
         iter::once(LOCAL_CRATE)
             .chain(self.crates(()).iter().copied())
-            .flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
+            .flat_map(move |cnum| self.traits(cnum).iter().copied())
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index ecb191676c2..c9cd644fab0 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -37,7 +37,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
-use rustc_errors::ErrorGuaranteed;
+use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
@@ -1439,14 +1439,26 @@ pub struct OpaqueHiddenType<'tcx> {
 }
 
 impl<'tcx> OpaqueHiddenType<'tcx> {
-    pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) -> ErrorGuaranteed {
+    pub fn report_mismatch(
+        &self,
+        other: &Self,
+        opaque_def_id: LocalDefId,
+        tcx: TyCtxt<'tcx>,
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
+        if let Some(diag) = tcx
+            .sess
+            .diagnostic()
+            .steal_diagnostic(tcx.def_span(opaque_def_id), StashKey::OpaqueHiddenTypeMismatch)
+        {
+            diag.cancel();
+        }
         // Found different concrete types for the opaque type.
         let sub_diag = if self.span == other.span {
             TypeMismatchReason::ConflictType { span: self.span }
         } else {
             TypeMismatchReason::PreviousUse { span: self.span }
         };
-        tcx.sess.emit_err(OpaqueHiddenTypeMismatch {
+        tcx.sess.create_err(OpaqueHiddenTypeMismatch {
             self_ty: self.ty,
             other_ty: other.ty,
             other_span: other.span,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 4491d78648f..a064174e261 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1164,6 +1164,22 @@ pub trait PrettyPrinter<'tcx>:
         traits.entry(trait_ref).or_default().extend(proj_ty);
     }
 
+    fn pretty_print_inherent_projection(
+        self,
+        alias_ty: &ty::AliasTy<'tcx>,
+    ) -> Result<Self::Path, Self::Error> {
+        let def_key = self.tcx().def_key(alias_ty.def_id);
+        self.path_generic_args(
+            |cx| {
+                cx.path_append(
+                    |cx| cx.path_qualified(alias_ty.self_ty(), None),
+                    &def_key.disambiguated_data,
+                )
+            },
+            &alias_ty.substs[1..],
+        )
+    }
+
     fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> {
         None
     }
@@ -2821,7 +2837,11 @@ define_print_and_forward_display! {
     }
 
     ty::AliasTy<'tcx> {
-        p!(print_def_path(self.def_id, self.substs));
+        if let DefKind::Impl { of_trait: false } = cx.tcx().def_kind(cx.tcx().parent(self.def_id)) {
+            p!(pretty_print_inherent_projection(self))
+        } else {
+            p!(print_def_path(self.def_id, self.substs));
+        }
     }
 
     ty::ClosureKind {
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 5a0571f4bb7..e04dbbff9a7 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -151,10 +151,14 @@ pub struct TypeckResults<'tcx> {
     /// this field will be set to `Some(ErrorGuaranteed)`.
     pub tainted_by_errors: Option<ErrorGuaranteed>,
 
-    /// All the opaque types that have hidden types set
-    /// by this function. We also store the
-    /// type here, so that mir-borrowck can use it as a hint for figuring out hidden types,
-    /// even if they are only set in dead code (which doesn't show up in MIR).
+    /// All the opaque types that have hidden types set by this function.
+    /// We also store the type here, so that the compiler can use it as a hint
+    /// for figuring out hidden types, even if they are only set in dead code
+    /// (which doesn't show up in MIR).
+    ///
+    /// These types are mapped back to the opaque's identity substitutions
+    /// (with erased regions), which is why we don't associated substs with any
+    /// of these usages.
     pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
 
     /// Tracks the minimum captures required for a closure;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index c385b00692f..bcab4c0d24b 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -15,6 +15,7 @@ use rustc_middle::mir::Place;
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::cast::{mir_cast_kind, CastTy};
+use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{self, Ty, UpvarSubsts};
 use rustc_span::Span;
 
@@ -225,49 +226,63 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     );
                     let (op,ty) = (Operand::Move(discr), discr_ty);
 
-                    if let Abi::Scalar(scalar) = layout.unwrap().abi{
-                        if let Primitive::Int(_, signed) = scalar.primitive() {
-                            let range = scalar.valid_range(&this.tcx);
-                            // FIXME: Handle wraparound cases too.
-                            if range.end >= range.start {
-                                let mut assumer = |range: u128, bin_op: BinOp| {
-                                    // We will be overwriting this val if our scalar is signed value
-                                    // because sign extension on unsigned types might cause unintended things
-                                    let mut range_val =
-                                        ConstantKind::from_bits(this.tcx, range, ty::ParamEnv::empty().and(discr_ty));
-                                    let bool_ty = this.tcx.types.bool;
-                                    if signed {
-                                        let scalar_size_extend = scalar.size(&this.tcx).sign_extend(range);
-                                        let discr_layout = this.tcx.layout_of(this.param_env.and(discr_ty));
-                                        let truncated_val = discr_layout.unwrap().size.truncate(scalar_size_extend);
-                                        range_val = ConstantKind::from_bits(
-                                            this.tcx,
-                                            truncated_val,
-                                            ty::ParamEnv::empty().and(discr_ty),
-                                        );
-                                    }
-                                    let lit_op = this.literal_operand(expr.span, range_val);
-                                    let is_bin_op = this.temp(bool_ty, expr_span);
-                                    this.cfg.push_assign(
-                                        block,
-                                        source_info,
-                                        is_bin_op,
-                                        Rvalue::BinaryOp(bin_op, Box::new(((lit_op), (Operand::Copy(discr))))),
-                                    );
-                                    this.cfg.push(
-                                        block,
-                                        Statement {
-                                            source_info,
-                                            kind: StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(
-                                                Operand::Copy(is_bin_op),
-                                            ))),
-                                        },
-                                    )
-                                };
-                                assumer(range.end, BinOp::Ge);
-                                assumer(range.start, BinOp::Le);
-                            }
-                        }
+                    if let Abi::Scalar(scalar) = layout.unwrap().abi
+                        && !scalar.is_always_valid(&this.tcx)
+                        && let Primitive::Int(int_width, _signed) = scalar.primitive()
+                    {
+                        let unsigned_ty = int_width.to_ty(this.tcx, false);
+                        let unsigned_place = this.temp(unsigned_ty, expr_span);
+                        this.cfg.push_assign(
+                            block,
+                            source_info,
+                            unsigned_place,
+                            Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr), unsigned_ty));
+
+                        let bool_ty = this.tcx.types.bool;
+                        let range = scalar.valid_range(&this.tcx);
+                        let merge_op =
+                            if range.start <= range.end {
+                                BinOp::BitAnd
+                            } else {
+                                BinOp::BitOr
+                            };
+
+                        let mut comparer = |range: u128, bin_op: BinOp| -> Place<'tcx> {
+                            let range_val =
+                                ConstantKind::from_bits(this.tcx, range, ty::ParamEnv::empty().and(unsigned_ty));
+                            let lit_op = this.literal_operand(expr.span, range_val);
+                            let is_bin_op = this.temp(bool_ty, expr_span);
+                            this.cfg.push_assign(
+                                block,
+                                source_info,
+                                is_bin_op,
+                                Rvalue::BinaryOp(bin_op, Box::new((Operand::Copy(unsigned_place), lit_op))),
+                            );
+                            is_bin_op
+                        };
+                        let assert_place = if range.start == 0 {
+                            comparer(range.end, BinOp::Le)
+                        } else {
+                            let start_place = comparer(range.start, BinOp::Ge);
+                            let end_place = comparer(range.end, BinOp::Le);
+                            let merge_place = this.temp(bool_ty, expr_span);
+                            this.cfg.push_assign(
+                                block,
+                                source_info,
+                                merge_place,
+                                Rvalue::BinaryOp(merge_op, Box::new((Operand::Move(start_place), Operand::Move(end_place)))),
+                            );
+                            merge_place
+                        };
+                        this.cfg.push(
+                            block,
+                            Statement {
+                                source_info,
+                                kind: StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(
+                                    Operand::Move(assert_place),
+                                ))),
+                            },
+                        );
                     }
 
                     (op,ty)
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 56c87c402fe..b01b6fbf222 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -644,24 +644,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
         };
 
-        if let Some(destination) = destination {
-            if let Some(value) = value {
+        match (destination, value) {
+            (Some(destination), Some(value)) => {
                 debug!("stmt_expr Break val block_context.push(SubExpr)");
                 self.block_context.push(BlockFrame::SubExpr);
                 unpack!(block = self.expr_into_dest(destination, block, value));
                 self.block_context.pop();
-            } else {
+            }
+            (Some(destination), None) => {
                 self.cfg.push_assign_unit(block, source_info, destination, self.tcx)
             }
-        } else {
-            assert!(value.is_none(), "`return` and `break` should have a destination");
-            if self.tcx.sess.instrument_coverage() {
+            (None, Some(_)) => {
+                panic!("`return`, `become` and `break` with value and must have a destination")
+            }
+            (None, None) if self.tcx.sess.instrument_coverage() => {
                 // Unlike `break` and `return`, which push an `Assign` statement to MIR, from which
                 // a Coverage code region can be generated, `continue` needs no `Assign`; but
                 // without one, the `InstrumentCoverage` MIR pass cannot generate a code region for
                 // `continue`. Coverage will be missing unless we add a dummy `Assign` to MIR.
                 self.add_dummy_assignment(span, block, source_info);
             }
+            (None, None) => {}
         }
 
         let region_scope = self.scopes.breakable_scopes[break_index].region_scope;
@@ -671,12 +674,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         } else {
             self.scopes.breakable_scopes[break_index].continue_drops.as_mut().unwrap()
         };
-        let mut drop_idx = ROOT_NODE;
-        for scope in &self.scopes.scopes[scope_index + 1..] {
-            for drop in &scope.drops {
-                drop_idx = drops.add_drop(*drop, drop_idx);
-            }
-        }
+
+        let drop_idx = self.scopes.scopes[scope_index + 1..]
+            .iter()
+            .flat_map(|scope| &scope.drops)
+            .fold(ROOT_NODE, |drop_idx, &drop| drops.add_drop(drop, drop_idx));
+
         drops.add_entry(block, drop_idx);
 
         // `build_drop_trees` doesn't have access to our source_info, so we
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index f46eb5a0ce1..c8648224ac1 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -130,6 +130,7 @@ impl<'tcx> Cx<'tcx> {
                 ExprKind::Pointer { cast: PointerCast::Unsize, source: self.thir.exprs.push(expr) }
             }
             Adjust::Pointer(cast) => ExprKind::Pointer { cast, source: self.thir.exprs.push(expr) },
+            Adjust::NeverToAny if adjustment.target.is_never() => return expr,
             Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) },
             Adjust::Deref(None) => {
                 adjust_span(&mut expr);
diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs
index e554c470646..35e4c24dc46 100644
--- a/compiler/rustc_mir_transform/src/coverage/debug.rs
+++ b/compiler/rustc_mir_transform/src/coverage/debug.rs
@@ -118,7 +118,7 @@ use rustc_middle::mir::spanview::{self, SpanViewable};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::mir::coverage::*;
-use rustc_middle::mir::{self, BasicBlock, TerminatorKind};
+use rustc_middle::mir::{self, BasicBlock};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 
@@ -796,7 +796,7 @@ fn bcb_to_string_sections<'tcx>(
     }
     let non_term_blocks = bcb_data.basic_blocks[0..len - 1]
         .iter()
-        .map(|&bb| format!("{:?}: {}", bb, term_type(&mir_body[bb].terminator().kind)))
+        .map(|&bb| format!("{:?}: {}", bb, mir_body[bb].terminator().kind.name()))
         .collect::<Vec<_>>();
     if non_term_blocks.len() > 0 {
         sections.push(non_term_blocks.join("\n"));
@@ -804,28 +804,7 @@ fn bcb_to_string_sections<'tcx>(
     sections.push(format!(
         "{:?}: {}",
         bcb_data.basic_blocks.last().unwrap(),
-        term_type(&bcb_data.terminator(mir_body).kind)
+        bcb_data.terminator(mir_body).kind.name(),
     ));
     sections
 }
-
-/// Returns a simple string representation of a `TerminatorKind` variant, independent of any
-/// values it might hold.
-pub(super) fn term_type(kind: &TerminatorKind<'_>) -> &'static str {
-    match kind {
-        TerminatorKind::Goto { .. } => "Goto",
-        TerminatorKind::SwitchInt { .. } => "SwitchInt",
-        TerminatorKind::Resume => "Resume",
-        TerminatorKind::Terminate => "Terminate",
-        TerminatorKind::Return => "Return",
-        TerminatorKind::Unreachable => "Unreachable",
-        TerminatorKind::Drop { .. } => "Drop",
-        TerminatorKind::Call { .. } => "Call",
-        TerminatorKind::Assert { .. } => "Assert",
-        TerminatorKind::Yield { .. } => "Yield",
-        TerminatorKind::GeneratorDrop => "GeneratorDrop",
-        TerminatorKind::FalseEdge { .. } => "FalseEdge",
-        TerminatorKind::FalseUnwind { .. } => "FalseUnwind",
-        TerminatorKind::InlineAsm { .. } => "InlineAsm",
-    }
-}
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 986d2fd190d..ea1223fbca6 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -9,6 +9,7 @@ use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::{self, BasicBlock, BasicBlockData, Terminator, TerminatorKind};
 
+use std::cmp::Ordering;
 use std::ops::{Index, IndexMut};
 
 const ID_SEPARATOR: &str = ",";
@@ -212,8 +213,12 @@ impl CoverageGraph {
     }
 
     #[inline(always)]
-    pub fn dominators(&self) -> &Dominators<BasicCoverageBlock> {
-        self.dominators.as_ref().unwrap()
+    pub fn rank_partial_cmp(
+        &self,
+        a: BasicCoverageBlock,
+        b: BasicCoverageBlock,
+    ) -> Option<Ordering> {
+        self.dominators.as_ref().unwrap().rank_partial_cmp(a, b)
     }
 }
 
@@ -650,26 +655,6 @@ pub(super) fn find_loop_backedges(
     let mut backedges = IndexVec::from_elem_n(Vec::<BasicCoverageBlock>::new(), num_bcbs);
 
     // Identify loops by their backedges.
-    //
-    // The computational complexity is bounded by: n(s) x d where `n` is the number of
-    // `BasicCoverageBlock` nodes (the simplified/reduced representation of the CFG derived from the
-    // MIR); `s` is the average number of successors per node (which is most likely less than 2, and
-    // independent of the size of the function, so it can be treated as a constant);
-    // and `d` is the average number of dominators per node.
-    //
-    // The average number of dominators depends on the size and complexity of the function, and
-    // nodes near the start of the function's control flow graph typically have less dominators
-    // than nodes near the end of the CFG. Without doing a detailed mathematical analysis, I
-    // think the resulting complexity has the characteristics of O(n log n).
-    //
-    // The overall complexity appears to be comparable to many other MIR transform algorithms, and I
-    // don't expect that this function is creating a performance hot spot, but if this becomes an
-    // issue, there may be ways to optimize the `dominates` algorithm (as indicated by an
-    // existing `FIXME` comment in that code), or possibly ways to optimize it's usage here, perhaps
-    // by keeping track of results for visited `BasicCoverageBlock`s if they can be used to short
-    // circuit downstream `dominates` checks.
-    //
-    // For now, that kind of optimization seems unnecessarily complicated.
     for (bcb, _) in basic_coverage_blocks.iter_enumerated() {
         for &successor in &basic_coverage_blocks.successors[bcb] {
             if basic_coverage_blocks.dominates(successor, bcb) {
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 287ae217087..d27200419e2 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,4 +1,3 @@
-use super::debug::term_type;
 use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB};
 
 use itertools::Itertools;
@@ -40,7 +39,7 @@ impl CoverageStatement {
                     "{}: @{}.{}: {:?}",
                     source_range_no_file(tcx, span),
                     bb.index(),
-                    term_type(&term.kind),
+                    term.kind.name(),
                     term.kind
                 )
             }
@@ -345,7 +344,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
                         // before the dominated equal spans). When later comparing two spans in
                         // order, the first will either dominate the second, or they will have no
                         // dominator relationship.
-                        self.basic_coverage_blocks.dominators().rank_partial_cmp(a.bcb, b.bcb)
+                        self.basic_coverage_blocks.rank_partial_cmp(a.bcb, b.bcb)
                     }
                 } else {
                     // Sort hi() in reverse order so shorter spans are attempted after longer spans.
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 83a335197b3..90b58933df7 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -25,7 +25,6 @@
 //! to: `rustc_span::create_default_session_globals_then(|| { test_here(); })`.
 
 use super::counters;
-use super::debug;
 use super::graph;
 use super::spans;
 
@@ -188,12 +187,12 @@ fn debug_basic_blocks(mir_body: &Body<'_>) -> String {
                     | TerminatorKind::Goto { target }
                     | TerminatorKind::InlineAsm { destination: Some(target), .. }
                     | TerminatorKind::Yield { resume: target, .. } => {
-                        format!("{}{:?}:{} -> {:?}", sp, bb, debug::term_type(kind), target)
+                        format!("{}{:?}:{} -> {:?}", sp, bb, kind.name(), target)
                     }
                     TerminatorKind::SwitchInt { targets, .. } => {
-                        format!("{}{:?}:{} -> {:?}", sp, bb, debug::term_type(kind), targets)
+                        format!("{}{:?}:{} -> {:?}", sp, bb, kind.name(), targets)
                     }
-                    _ => format!("{}{:?}:{}", sp, bb, debug::term_type(kind)),
+                    _ => format!("{}{:?}:{}", sp, bb, kind.name()),
                 }
             })
             .collect::<Vec<_>>()
@@ -215,7 +214,7 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) {
                         "    {:?} [label=\"{:?}: {}\"];\n{}",
                         bb,
                         bb,
-                        debug::term_type(&data.terminator().kind),
+                        data.terminator().kind.name(),
                         mir_body
                             .basic_blocks
                             .successors(bb)
@@ -244,7 +243,7 @@ fn print_coverage_graphviz(
                         "    {:?} [label=\"{:?}: {}\"];\n{}",
                         bcb,
                         bcb,
-                        debug::term_type(&bcb_data.terminator(mir_body).kind),
+                        bcb_data.terminator(mir_body).kind.name(),
                         basic_coverage_blocks
                             .successors(bcb)
                             .map(|successor| { format!("    {:?} -> {:?};", bcb, successor) })
diff --git a/compiler/rustc_mir_transform/src/ctfe_limit.rs b/compiler/rustc_mir_transform/src/ctfe_limit.rs
index 1b3ac78fbc6..bf5722b3d00 100644
--- a/compiler/rustc_mir_transform/src/ctfe_limit.rs
+++ b/compiler/rustc_mir_transform/src/ctfe_limit.rs
@@ -47,7 +47,7 @@ fn has_back_edge(
         return false;
     }
     // Check if any of the dominators of the node are also the node's successor.
-    doms.dominators(node).any(|dom| node_data.terminator().successors().any(|succ| succ == dom))
+    node_data.terminator().successors().any(|succ| doms.dominates(succ, node))
 }
 
 fn insert_counter(basic_block_data: &mut BasicBlockData<'_>) {
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index 2b404efccc7..e8e4246b797 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -31,11 +31,11 @@ pub struct SsaLocals {
 /// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to
 /// actually compute dominators, we can just compare block indices because bb0 is always the first
 /// block, and in any body all other blocks are always dominated by bb0.
-struct SmallDominators {
-    inner: Option<Dominators<BasicBlock>>,
+struct SmallDominators<'a> {
+    inner: Option<&'a Dominators<BasicBlock>>,
 }
 
-impl SmallDominators {
+impl SmallDominators<'_> {
     fn dominates(&self, first: Location, second: Location) -> bool {
         if first.block == second.block {
             first.statement_index <= second.statement_index
@@ -198,14 +198,14 @@ enum LocationExtended {
     Arg,
 }
 
-struct SsaVisitor {
-    dominators: SmallDominators,
+struct SsaVisitor<'a> {
+    dominators: SmallDominators<'a>,
     assignments: IndexVec<Local, Set1<LocationExtended>>,
     assignment_order: Vec<Local>,
     direct_uses: IndexVec<Local, u32>,
 }
 
-impl<'tcx> Visitor<'tcx> for SsaVisitor {
+impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
     fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) {
         match ctxt {
             PlaceContext::MutatingUse(MutatingUseContext::Projection)
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 08b73ebb694..b3d0e4ba258 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -873,6 +873,11 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                     let msg = "macro-expanded `extern crate` items cannot \
                                        shadow names passed with `--extern`";
                     self.r.tcx.sess.span_err(item.span, msg);
+                    // `return` is intended to discard this binding because it's an
+                    // unregistered ambiguity error which would result in a panic
+                    // caused by inconsistency `path_res`
+                    // more details: https://github.com/rust-lang/rust/pull/111761
+                    return;
                 }
             }
             let entry = self.r.extern_prelude.entry(ident.normalize_to_macros_2_0()).or_insert(
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index a1077615d95..e0611907613 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -17,7 +17,7 @@ use rustc_ast::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_errors::{Applicability, DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg};
 use rustc_hir::def::Namespace::{self, *};
-use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
+use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
 use rustc_middle::middle::resolve_bound_vars::Set1;
@@ -4287,12 +4287,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         }
     }
 
-    fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> bool {
+    fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option<Res> {
         // FIXME: This caching may be incorrect in case of multiple `macro_rules`
         // items with the same name in the same module.
         // Also hygiene is not considered.
         let mut doc_link_resolutions = std::mem::take(&mut self.r.doc_link_resolutions);
-        let res = doc_link_resolutions
+        let res = *doc_link_resolutions
             .entry(self.parent_scope.module.nearest_parent_mod().expect_local())
             .or_default()
             .entry((Symbol::intern(path_str), ns))
@@ -4307,8 +4307,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     return None;
                 }
                 res
-            })
-            .is_some();
+            });
         self.r.doc_link_resolutions = doc_link_resolutions;
         res
     }
@@ -4343,8 +4342,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             let mut any_resolved = false;
             let mut need_assoc = false;
             for ns in [TypeNS, ValueNS, MacroNS] {
-                if self.resolve_and_cache_rustdoc_path(&path_str, ns) {
-                    any_resolved = true;
+                if let Some(res) = self.resolve_and_cache_rustdoc_path(&path_str, ns) {
+                    // Rustdoc ignores tool attribute resolutions and attempts
+                    // to resolve their prefixes for diagnostics.
+                    any_resolved = !matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Tool));
                 } else if ns != MacroNS {
                     need_assoc = true;
                 }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 3cdc3f0ecf8..1e31a0ff278 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -106,7 +106,7 @@ impl Determinacy {
 /// A specific scope in which a name can be looked up.
 /// This enum is currently used only for early resolution (imports and macros),
 /// but not for late resolution yet.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 enum Scope<'a> {
     DeriveHelpers(LocalExpnId),
     DeriveHelpersCompat,
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index a3f262905c7..254ede4e6a0 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -220,7 +220,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
         match *ty.kind() {
             // Print all nominal types as paths (unlike `pretty_print_type`).
             ty::FnDef(def_id, substs)
-            | ty::Alias(_, ty::AliasTy { def_id, substs, .. })
+            | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. })
             | ty::Closure(def_id, substs)
             | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
 
@@ -241,6 +241,8 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
                 Ok(self)
             }
 
+            ty::Alias(ty::Inherent, _) => panic!("unexpected inherent projection"),
+
             _ => self.pretty_print_type(ty),
         }
     }
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 51d508a580b..da8a16dee8a 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -272,12 +272,11 @@ fn encode_region<'tcx>(
             s.push('E');
             compress(dict, DictKey::Region(region), &mut s);
         }
-        RegionKind::ReErased => {
+        RegionKind::ReEarlyBound(..) | RegionKind::ReErased => {
             s.push_str("u6region");
             compress(dict, DictKey::Region(region), &mut s);
         }
-        RegionKind::ReEarlyBound(..)
-        | RegionKind::ReFree(..)
+        RegionKind::ReFree(..)
         | RegionKind::ReStatic
         | RegionKind::ReError(_)
         | RegionKind::ReVar(..)
@@ -704,14 +703,15 @@ fn transform_predicates<'tcx>(
 ) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
     let predicates: Vec<ty::PolyExistentialPredicate<'tcx>> = predicates
         .iter()
-        .map(|predicate| match predicate.skip_binder() {
+        .filter_map(|predicate| match predicate.skip_binder() {
             ty::ExistentialPredicate::Trait(trait_ref) => {
                 let trait_ref = ty::TraitRef::identity(tcx, trait_ref.def_id);
-                ty::Binder::dummy(ty::ExistentialPredicate::Trait(
+                Some(ty::Binder::dummy(ty::ExistentialPredicate::Trait(
                     ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
-                ))
+                )))
             }
-            _ => predicate,
+            ty::ExistentialPredicate::Projection(..) => None,
+            ty::ExistentialPredicate::AutoTrait(..) => Some(predicate),
         })
         .collect();
     tcx.mk_poly_existential_predicates(&predicates)
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 2235524129e..4cccc639892 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -433,7 +433,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
             // Mangle all nominal types as paths.
             ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
             | ty::FnDef(def_id, substs)
-            | ty::Alias(_, ty::AliasTy { def_id, substs, .. })
+            | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. })
             | ty::Closure(def_id, substs)
             | ty::Generator(def_id, substs, _) => {
                 self = self.print_def_path(def_id, substs)?;
@@ -482,6 +482,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
                 self = r.print(self)?;
             }
 
+            ty::Alias(ty::Inherent, _) => bug!("symbol_names: unexpected inherent projection"),
             ty::GeneratorWitness(_) => bug!("symbol_names: unexpected `GeneratorWitness`"),
             ty::GeneratorWitnessMIR(..) => bug!("symbol_names: unexpected `GeneratorWitnessMIR`"),
         }
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index dcfa33ae842..644bfd33970 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -177,14 +177,18 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             return Err(NoSolution);
         }
 
-        if goal.predicate.self_ty().has_non_region_infer() {
+        // The regions of a type don't affect the size of the type
+        let tcx = ecx.tcx();
+        // We should erase regions from both the param-env and type, since both
+        // may have infer regions. Specifically, after canonicalizing and instantiating,
+        // early bound regions turn into region vars in both the new and old solver.
+        let key = tcx.erase_regions(goal.param_env.and(goal.predicate.self_ty()));
+        // But if there are inference variables, we have to wait until it's resolved.
+        if key.has_non_region_infer() {
             return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
         }
 
-        let tcx = ecx.tcx();
-        let self_ty = tcx.erase_regions(goal.predicate.self_ty());
-
-        if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
+        if let Ok(layout) = tcx.layout_of(key)
             && layout.layout.is_pointer_like(&tcx.data_layout)
         {
             // FIXME: We could make this faster by making a no-constraints response
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 f5f2fe54217..dc43a3d154a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -885,7 +885,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             return;
                         }
 
-                        if self.suggest_impl_trait(&mut err, span, &obligation, trait_predicate) {
+                        if self.suggest_impl_trait(&mut err, &obligation, trait_predicate) {
                             err.emit();
                             return;
                         }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index 88525e1b720..10bd027b684 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -306,6 +306,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     }
                 }
             }
+
+            // `&[{integral}]` - `FromIterator` needs that.
+            if let ty::Ref(_, ref_ty, rustc_ast::Mutability::Not) = self_ty.kind()
+                && let ty::Slice(sty) = ref_ty.kind()
+                && sty.is_integral()
+            {
+                flags.push((sym::_Self, Some("&[{integral}]".to_owned())));
+            }
         });
 
         if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {
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 ea17f23434b..83511e898f7 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -30,9 +30,9 @@ use rustc_middle::hir::map;
 use rustc_middle::ty::error::TypeError::{self, Sorts};
 use rustc_middle::ty::{
     self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind,
-    GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts,
-    IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder,
-    TypeSuperFoldable, TypeVisitableExt, TypeckResults,
+    GeneratorDiagnosticData, GeneratorInteriorTypeCause, InferTy, InternalSubsts, IsSuggestable,
+    ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeVisitableExt, TypeckResults,
 };
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -261,7 +261,6 @@ pub trait TypeErrCtxtExt<'tcx> {
     fn suggest_impl_trait(
         &self,
         err: &mut Diagnostic,
-        span: Span,
         obligation: &PredicateObligation<'tcx>,
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool;
@@ -1792,215 +1791,66 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     fn suggest_impl_trait(
         &self,
         err: &mut Diagnostic,
-        span: Span,
         obligation: &PredicateObligation<'tcx>,
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
-        match obligation.cause.code().peel_derives() {
-            // Only suggest `impl Trait` if the return type is unsized because it is `dyn Trait`.
-            ObligationCauseCode::SizedReturnType => {}
-            _ => return false,
-        }
-
-        let hir = self.tcx.hir();
-        let fn_hir_id = hir.local_def_id_to_hir_id(obligation.cause.body_id);
-        let node = hir.find_by_def_id(obligation.cause.body_id);
-        let Some(hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Fn(sig, _, body_id),
-            ..
-        })) = node
-        else {
+        let ObligationCauseCode::SizedReturnType = obligation.cause.code() else {
             return false;
         };
-        let body = hir.body(*body_id);
-        let trait_pred = self.resolve_vars_if_possible(trait_pred);
-        let ty = trait_pred.skip_binder().self_ty();
-        let is_object_safe = match ty.kind() {
-            ty::Dynamic(predicates, _, ty::Dyn) => {
-                // If the `dyn Trait` is not object safe, do not suggest `Box<dyn Trait>`.
-                predicates
-                    .principal_def_id()
-                    .map_or(true, |def_id| self.tcx.check_is_object_safe(def_id))
-            }
-            // We only want to suggest `impl Trait` to `dyn Trait`s.
-            // For example, `fn foo() -> str` needs to be filtered out.
-            _ => return false,
-        };
-
-        let hir::FnRetTy::Return(ret_ty) = sig.decl.output else {
+        let ty::Dynamic(_, _, ty::Dyn) = trait_pred.self_ty().skip_binder().kind() else {
             return false;
         };
 
-        // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for
-        // cases like `fn foo() -> (dyn Trait, i32) {}`.
-        // Recursively look for `TraitObject` types and if there's only one, use that span to
-        // suggest `impl Trait`.
-
-        // Visit to make sure there's a single `return` type to suggest `impl Trait`,
-        // otherwise suggest using `Box<dyn Trait>` or an enum.
-        let mut visitor = ReturnsVisitor::default();
-        visitor.visit_body(&body);
-
-        let typeck_results = self.typeck_results.as_ref().unwrap();
-        let Some(liberated_sig) = typeck_results.liberated_fn_sigs().get(fn_hir_id).copied() else { return false; };
-
-        let ret_types = visitor
-            .returns
-            .iter()
-            .filter_map(|expr| Some((expr.span, typeck_results.node_type_opt(expr.hir_id)?)))
-            .map(|(expr_span, ty)| (expr_span, self.resolve_vars_if_possible(ty)));
-        let (last_ty, all_returns_have_same_type, only_never_return) = ret_types.clone().fold(
-            (None, true, true),
-            |(last_ty, mut same, only_never_return): (std::option::Option<Ty<'_>>, bool, bool),
-             (_, ty)| {
-                let ty = self.resolve_vars_if_possible(ty);
-                same &=
-                    !matches!(ty.kind(), ty::Error(_))
-                        && last_ty.map_or(true, |last_ty| {
-                            // FIXME: ideally we would use `can_coerce` here instead, but `typeck` comes
-                            // *after* in the dependency graph.
-                            match (ty.kind(), last_ty.kind()) {
-                                (Infer(InferTy::IntVar(_)), Infer(InferTy::IntVar(_)))
-                                | (Infer(InferTy::FloatVar(_)), Infer(InferTy::FloatVar(_)))
-                                | (Infer(InferTy::FreshIntTy(_)), Infer(InferTy::FreshIntTy(_)))
-                                | (
-                                    Infer(InferTy::FreshFloatTy(_)),
-                                    Infer(InferTy::FreshFloatTy(_)),
-                                ) => true,
-                                _ => ty == last_ty,
-                            }
-                        });
-                (Some(ty), same, only_never_return && matches!(ty.kind(), ty::Never))
-            },
-        );
-        let mut spans_and_needs_box = vec![];
-
-        match liberated_sig.output().kind() {
-            ty::Dynamic(predicates, _, ty::Dyn) => {
-                let cause = ObligationCause::misc(ret_ty.span, obligation.cause.body_id);
-                let param_env = ty::ParamEnv::empty();
-
-                if !only_never_return {
-                    for (expr_span, return_ty) in ret_types {
-                        let self_ty_satisfies_dyn_predicates = |self_ty| {
-                            predicates.iter().all(|predicate| {
-                                let pred = predicate.with_self_ty(self.tcx, self_ty);
-                                let obl = Obligation::new(self.tcx, cause.clone(), param_env, pred);
-                                self.predicate_may_hold(&obl)
-                            })
-                        };
-
-                        if let ty::Adt(def, substs) = return_ty.kind()
-                            && def.is_box()
-                            && self_ty_satisfies_dyn_predicates(substs.type_at(0))
-                        {
-                            spans_and_needs_box.push((expr_span, false));
-                        } else if self_ty_satisfies_dyn_predicates(return_ty) {
-                            spans_and_needs_box.push((expr_span, true));
-                        } else {
-                            return false;
-                        }
-                    }
-                }
-            }
-            _ => return false,
-        };
-
-        let sm = self.tcx.sess.source_map();
-        if !ret_ty.span.overlaps(span) {
-            return false;
-        }
-        let snippet = if let hir::TyKind::TraitObject(..) = ret_ty.kind {
-            if let Ok(snippet) = sm.span_to_snippet(ret_ty.span) {
-                snippet
-            } else {
-                return false;
-            }
-        } else {
-            // Substitute the type, so we can print a fixup given `type Alias = dyn Trait`
-            let name = liberated_sig.output().to_string();
-            let name =
-                name.strip_prefix('(').and_then(|name| name.strip_suffix(')')).unwrap_or(&name);
-            if !name.starts_with("dyn ") {
-                return false;
-            }
-            name.to_owned()
-        };
-
         err.code(error_code!(E0746));
         err.set_primary_message("return type cannot have an unboxed trait object");
         err.children.clear();
-        let impl_trait_msg = "for information on `impl Trait`, see \
-            <https://doc.rust-lang.org/book/ch10-02-traits.html\
-            #returning-types-that-implement-traits>";
-        let trait_obj_msg = "for information on trait objects, see \
-            <https://doc.rust-lang.org/book/ch17-02-trait-objects.html\
-            #using-trait-objects-that-allow-for-values-of-different-types>";
-
-        let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn");
-        let trait_obj = if has_dyn { &snippet[4..] } else { &snippet };
-        if only_never_return {
-            // No return paths, probably using `panic!()` or similar.
-            // Suggest `-> impl Trait`, and if `Trait` is object safe, `-> Box<dyn Trait>`.
-            suggest_trait_object_return_type_alternatives(
-                err,
-                ret_ty.span,
-                trait_obj,
-                is_object_safe,
-            );
-        } else if let (Some(last_ty), true) = (last_ty, all_returns_have_same_type) {
-            // Suggest `-> impl Trait`.
+
+        let span = obligation.cause.span;
+        if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span)
+            && snip.starts_with("dyn ")
+        {
             err.span_suggestion(
-                ret_ty.span,
-                format!(
-                    "use `impl {1}` as the return type, as all return paths are of type `{}`, \
-                     which implements `{1}`",
-                    last_ty, trait_obj,
-                ),
-                format!("impl {}", trait_obj),
-                Applicability::MachineApplicable,
+                span.with_hi(span.lo() + BytePos(4)),
+                "return an `impl Trait` instead of a `dyn Trait`, \
+                if all returned values are the same type",
+                "impl ",
+                Applicability::MaybeIncorrect,
             );
-            err.note(impl_trait_msg);
-        } else {
-            if is_object_safe {
-                // Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`.
-                err.multipart_suggestion(
-                    "return a boxed trait object instead",
-                    vec![
-                        (ret_ty.span.shrink_to_lo(), "Box<".to_string()),
-                        (span.shrink_to_hi(), ">".to_string()),
-                    ],
-                    Applicability::MaybeIncorrect,
-                );
-                for (span, needs_box) in spans_and_needs_box {
-                    if needs_box {
-                        err.multipart_suggestion(
-                            "... and box this value",
-                            vec![
-                                (span.shrink_to_lo(), "Box::new(".to_string()),
-                                (span.shrink_to_hi(), ")".to_string()),
-                            ],
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                }
+        }
+
+        let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(obligation.cause.body_id));
+
+        let mut visitor = ReturnsVisitor::default();
+        visitor.visit_body(&body);
+
+        let mut sugg =
+            vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())];
+        sugg.extend(visitor.returns.into_iter().flat_map(|expr| {
+            let span = expr.span.find_ancestor_in_same_ctxt(obligation.cause.span).unwrap_or(expr.span);
+            if !span.can_be_used_for_suggestions() {
+                vec![]
+            } else if let hir::ExprKind::Call(path, ..) = expr.kind
+                && let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, method)) = path.kind
+                && method.ident.name == sym::new
+                && let hir::TyKind::Path(hir::QPath::Resolved(.., box_path)) = ty.kind
+                && box_path.res.opt_def_id().is_some_and(|def_id| Some(def_id) == self.tcx.lang_items().owned_box())
+            {
+                // Don't box `Box::new`
+                vec![]
             } else {
-                // This is currently not possible to trigger because E0038 takes precedence, but
-                // leave it in for completeness in case anything changes in an earlier stage.
-                err.note(format!(
-                    "if trait `{}` were object-safe, you could return a trait object",
-                    trait_obj,
-                ));
+                vec![
+                    (span.shrink_to_lo(), "Box::new(".to_string()),
+                    (span.shrink_to_hi(), ")".to_string()),
+                ]
             }
-            err.note(trait_obj_msg);
-            err.note(format!(
-                "if all the returned values were of the same type you could use `impl {}` as the \
-                 return type",
-                trait_obj,
-            ));
-            err.note(impl_trait_msg);
-            err.note("you can create a new `enum` with a variant for each returned type");
-        }
+        }));
+
+        err.multipart_suggestion(
+            "box the return type, and wrap all of the returned values in `Box::new`",
+            sugg,
+            Applicability::MaybeIncorrect,
+        );
+
         true
     }
 
@@ -4139,37 +3989,6 @@ impl NextTypeParamName for &[hir::GenericParam<'_>] {
     }
 }
 
-fn suggest_trait_object_return_type_alternatives(
-    err: &mut Diagnostic,
-    ret_ty: Span,
-    trait_obj: &str,
-    is_object_safe: bool,
-) {
-    err.span_suggestion(
-        ret_ty,
-        format!(
-            "use `impl {}` as the return type if all return paths have the same type but you \
-                want to expose only the trait in the signature",
-            trait_obj,
-        ),
-        format!("impl {}", trait_obj),
-        Applicability::MaybeIncorrect,
-    );
-    if is_object_safe {
-        err.multipart_suggestion(
-            format!(
-                "use a boxed trait object if all return paths implement trait `{}`",
-                trait_obj,
-            ),
-            vec![
-                (ret_ty.shrink_to_lo(), "Box<".to_string()),
-                (ret_ty.shrink_to_hi(), ">".to_string()),
-            ],
-            Applicability::MaybeIncorrect,
-        );
-    }
-}
-
 /// Collect the spans that we see the generic param `param_did`
 struct ReplaceImplTraitVisitor<'a> {
     ty_spans: &'a mut Vec<Span>,
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 28dad8592a8..f265230ff77 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -17,6 +17,7 @@ pub mod query;
 mod select;
 mod specialize;
 mod structural_match;
+mod structural_normalize;
 mod util;
 mod vtable;
 pub mod wf;
@@ -62,6 +63,7 @@ pub use self::specialize::{
 pub use self::structural_match::{
     search_for_adt_const_param_violation, search_for_structural_match_violation,
 };
+pub use self::structural_normalize::StructurallyNormalizeExt;
 pub use self::util::elaborate;
 pub use self::util::{expand_trait_aliases, TraitAliasExpander};
 pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices};
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 aa230936903..8bc82b9f549 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -967,16 +967,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) {
         // The regions of a type don't affect the size of the type
         let tcx = self.tcx();
-        let self_ty =
-            tcx.erase_regions(tcx.erase_late_bound_regions(obligation.predicate.self_ty()));
-
+        let self_ty = tcx.erase_late_bound_regions(obligation.predicate.self_ty());
+        // We should erase regions from both the param-env and type, since both
+        // may have infer regions. Specifically, after canonicalizing and instantiating,
+        // early bound regions turn into region vars in both the new and old solver.
+        let key = tcx.erase_regions(obligation.param_env.and(self_ty));
         // But if there are inference variables, we have to wait until it's resolved.
-        if self_ty.has_non_region_infer() {
+        if key.has_non_region_infer() {
             candidates.ambiguous = true;
             return;
         }
 
-        if let Ok(layout) = tcx.layout_of(obligation.param_env.and(self_ty))
+        if let Ok(layout) = tcx.layout_of(key)
             && layout.layout.is_pointer_like(&tcx.data_layout)
         {
             candidates.vec.push(BuiltinCandidate { has_nested: false });
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index de023501f9e..0d9f55d4c2e 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -132,6 +132,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
         };
 
+        // The obligations returned by confirmation are recursively evaluated
+        // so we need to make sure they have the correct depth.
+        for subobligation in impl_src.borrow_nested_obligations_mut() {
+            subobligation.set_depth_from_parent(obligation.recursion_depth);
+        }
+
         if !obligation.predicate.is_const_if_const() {
             // normalize nested predicates according to parent predicate's constness.
             impl_src = impl_src.map(|mut o| {
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
new file mode 100644
index 00000000000..af8dd0da579
--- /dev/null
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -0,0 +1,55 @@
+use rustc_infer::infer::at::At;
+use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_infer::traits::{FulfillmentError, TraitEngine};
+use rustc_middle::ty::{self, Ty};
+
+use crate::traits::{query::evaluate_obligation::InferCtxtExt, NormalizeExt, Obligation};
+
+pub trait StructurallyNormalizeExt<'tcx> {
+    fn structurally_normalize(
+        &self,
+        ty: Ty<'tcx>,
+        fulfill_cx: &mut dyn TraitEngine<'tcx>,
+    ) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>>;
+}
+
+impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
+    fn structurally_normalize(
+        &self,
+        mut ty: Ty<'tcx>,
+        fulfill_cx: &mut dyn TraitEngine<'tcx>,
+    ) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
+        assert!(!ty.is_ty_var(), "should have resolved vars before calling");
+
+        if self.infcx.tcx.trait_solver_next() {
+            while let ty::Alias(ty::Projection, projection_ty) = *ty.kind() {
+                let new_infer_ty = self.infcx.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::NormalizeProjectionType,
+                    span: self.cause.span,
+                });
+                let obligation = Obligation::new(
+                    self.infcx.tcx,
+                    self.cause.clone(),
+                    self.param_env,
+                    ty::Binder::dummy(ty::ProjectionPredicate {
+                        projection_ty,
+                        term: new_infer_ty.into(),
+                    }),
+                );
+                if self.infcx.predicate_may_hold(&obligation) {
+                    fulfill_cx.register_predicate_obligation(self.infcx, obligation);
+                    let errors = fulfill_cx.select_where_possible(self.infcx);
+                    if !errors.is_empty() {
+                        return Err(errors);
+                    }
+                    ty = self.infcx.resolve_vars_if_possible(new_infer_ty);
+                } else {
+                    break;
+                }
+            }
+            Ok(ty)
+        } else {
+            Ok(self.normalize(ty).into_value_registering_obligations(self.infcx, fulfill_cx))
+        }
+    }
+}
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 442d041a8a7..15c19104616 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -238,6 +238,7 @@ fn adjust_for_rust_scalar<'tcx>(
     layout: TyAndLayout<'tcx>,
     offset: Size,
     is_return: bool,
+    drop_target_pointee: Option<Ty<'tcx>>,
 ) {
     // Booleans are always a noundef i1 that needs to be zero-extended.
     if scalar.is_bool() {
@@ -251,14 +252,24 @@ fn adjust_for_rust_scalar<'tcx>(
     }
 
     // Only pointer types handled below.
-    let Scalar::Initialized { value: Pointer(_), valid_range} = scalar else { return };
+    let Scalar::Initialized { value: Pointer(_), valid_range } = scalar else { return };
 
-    if !valid_range.contains(0) {
+    // Set `nonnull` if the validity range excludes zero, or for the argument to `drop_in_place`,
+    // which must be nonnull per its documented safety requirements.
+    if !valid_range.contains(0) || drop_target_pointee.is_some() {
         attrs.set(ArgAttribute::NonNull);
     }
 
     if let Some(pointee) = layout.pointee_info_at(&cx, offset) {
-        if let Some(kind) = pointee.safe {
+        let kind = if let Some(kind) = pointee.safe {
+            Some(kind)
+        } else if let Some(pointee) = drop_target_pointee {
+            // The argument to `drop_in_place` is semantically equivalent to a mutable reference.
+            Some(PointerKind::MutableRef { unpin: pointee.is_unpin(cx.tcx, cx.param_env()) })
+        } else {
+            None
+        };
+        if let Some(kind) = kind {
             attrs.pointee_align = Some(pointee.align);
 
             // `Box` are not necessarily dereferenceable for the entire duration of the function as
@@ -362,10 +373,18 @@ fn fn_abi_new_uncached<'tcx>(
     use SpecAbi::*;
     let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall);
 
+    let is_drop_in_place =
+        fn_def_id.is_some() && fn_def_id == cx.tcx.lang_items().drop_in_place_fn();
+
     let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
         let span = tracing::debug_span!("arg_of");
         let _entered = span.enter();
         let is_return = arg_idx.is_none();
+        let is_drop_target = is_drop_in_place && arg_idx == Some(0);
+        let drop_target_pointee = is_drop_target.then(|| match ty.kind() {
+            ty::RawPtr(ty::TypeAndMut { ty, .. }) => *ty,
+            _ => bug!("argument to drop_in_place is not a raw ptr: {:?}", ty),
+        });
 
         let layout = cx.layout_of(ty)?;
         let layout = if force_thin_self_ptr && arg_idx == Some(0) {
@@ -379,7 +398,15 @@ fn fn_abi_new_uncached<'tcx>(
 
         let mut arg = ArgAbi::new(cx, layout, |layout, scalar, offset| {
             let mut attrs = ArgAttributes::new();
-            adjust_for_rust_scalar(*cx, &mut attrs, scalar, *layout, offset, is_return);
+            adjust_for_rust_scalar(
+                *cx,
+                &mut attrs,
+                scalar,
+                *layout,
+                offset,
+                is_return,
+                drop_target_pointee,
+            );
             attrs
         });
 
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 7347980abbc..bfdb7a92bef 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -502,6 +502,7 @@ impl<T> Arc<T> {
     /// assert_eq!(*five, 5)
     /// ```
     #[cfg(not(no_global_oom_handling))]
+    #[inline]
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use]
     pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
@@ -535,6 +536,7 @@ impl<T> Arc<T> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
+    #[inline]
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use]
     pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
@@ -844,6 +846,7 @@ impl<T> Arc<[T]> {
     /// assert_eq!(*values, [1, 2, 3])
     /// ```
     #[cfg(not(no_global_oom_handling))]
+    #[inline]
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use]
     pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
@@ -871,6 +874,7 @@ impl<T> Arc<[T]> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
+    #[inline]
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use]
     pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
@@ -1300,10 +1304,10 @@ impl<T: ?Sized> Arc<T> {
         mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
     ) -> *mut ArcInner<T> {
         let layout = arcinner_layout_for_value_layout(value_layout);
-        unsafe {
-            Arc::try_allocate_for_layout(value_layout, allocate, mem_to_arcinner)
-                .unwrap_or_else(|_| handle_alloc_error(layout))
-        }
+
+        let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout));
+
+        unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) }
     }
 
     /// Allocates an `ArcInner<T>` with sufficient space for
@@ -1321,7 +1325,16 @@ impl<T: ?Sized> Arc<T> {
 
         let ptr = allocate(layout)?;
 
-        // Initialize the ArcInner
+        let inner = unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) };
+
+        Ok(inner)
+    }
+
+    unsafe fn initialize_arcinner(
+        ptr: NonNull<[u8]>,
+        layout: Layout,
+        mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
+    ) -> *mut ArcInner<T> {
         let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr());
         debug_assert_eq!(unsafe { Layout::for_value(&*inner) }, layout);
 
@@ -1330,7 +1343,7 @@ impl<T: ?Sized> Arc<T> {
             ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
         }
 
-        Ok(inner)
+        inner
     }
 
     /// Allocates an `ArcInner<T>` with sufficient space for an unsized inner value.
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs
index 2f1ee8b0353..5ecd0479971 100644
--- a/library/alloc/src/vec/in_place_collect.rs
+++ b/library/alloc/src/vec/in_place_collect.rs
@@ -178,7 +178,8 @@ where
             )
         };
 
-        let len = SpecInPlaceCollect::collect_in_place(&mut iterator, dst_buf, dst_end);
+        // SAFETY: `dst_buf` and `dst_end` are the start and end of the buffer.
+        let len = unsafe { SpecInPlaceCollect::collect_in_place(&mut iterator, dst_buf, dst_end) };
 
         let src = unsafe { iterator.as_inner().as_into_iter() };
         // check if SourceIter contract was upheld
@@ -239,7 +240,7 @@ trait SpecInPlaceCollect<T, I>: Iterator<Item = T> {
     /// `Iterator::__iterator_get_unchecked` calls with a `TrustedRandomAccessNoCoerce` bound
     /// on `I` which means the caller of this method must take the safety conditions
     /// of that trait into consideration.
-    fn collect_in_place(&mut self, dst: *mut T, end: *const T) -> usize;
+    unsafe fn collect_in_place(&mut self, dst: *mut T, end: *const T) -> usize;
 }
 
 impl<T, I> SpecInPlaceCollect<T, I> for I
@@ -247,7 +248,7 @@ where
     I: Iterator<Item = T>,
 {
     #[inline]
-    default fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize {
+    default unsafe fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize {
         // use try-fold since
         // - it vectorizes better for some iterator adapters
         // - unlike most internal iteration methods, it only takes a &mut self
@@ -265,7 +266,7 @@ where
     I: Iterator<Item = T> + TrustedRandomAccessNoCoerce,
 {
     #[inline]
-    fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize {
+    unsafe fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize {
         let len = self.size();
         let mut drop_guard = InPlaceDrop { inner: dst_buf, dst: dst_buf };
         for i in 0..len {
diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs
index 89d5fac30d3..3bbf5d8770b 100644
--- a/library/core/src/fmt/float.rs
+++ b/library/core/src/fmt/float.rs
@@ -45,7 +45,8 @@ where
         &mut buf,
         &mut parts,
     );
-    fmt.pad_formatted_parts(&formatted)
+    // SAFETY: `to_exact_fixed_str` and `format_exact` produce only ASCII characters.
+    unsafe { fmt.pad_formatted_parts(&formatted) }
 }
 
 // Don't inline this so callers that call both this and the above won't wind
@@ -71,7 +72,8 @@ where
         &mut buf,
         &mut parts,
     );
-    fmt.pad_formatted_parts(&formatted)
+    // SAFETY: `to_shortest_str` and `format_shortest` produce only ASCII characters.
+    unsafe { fmt.pad_formatted_parts(&formatted) }
 }
 
 fn float_to_decimal_display<T>(fmt: &mut Formatter<'_>, num: &T) -> Result
@@ -116,7 +118,8 @@ where
         &mut buf,
         &mut parts,
     );
-    fmt.pad_formatted_parts(&formatted)
+    // SAFETY: `to_exact_exp_str` and `format_exact` produce only ASCII characters.
+    unsafe { fmt.pad_formatted_parts(&formatted) }
 }
 
 // Don't inline this so callers that call both this and the above won't wind
@@ -143,7 +146,8 @@ where
         &mut buf,
         &mut parts,
     );
-    fmt.pad_formatted_parts(&formatted)
+    // SAFETY: `to_shortest_exp_str` and `format_shortest` produce only ASCII characters.
+    unsafe { fmt.pad_formatted_parts(&formatted) }
 }
 
 // Common code of floating point LowerExp and UpperExp.
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index bac2f31878b..1786b309c5b 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -1415,7 +1415,11 @@ impl<'a> Formatter<'a> {
     /// Takes the formatted parts and applies the padding.
     /// Assumes that the caller already has rendered the parts with required precision,
     /// so that `self.precision` can be ignored.
-    fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
+    ///
+    /// # Safety
+    ///
+    /// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8.
+    unsafe fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
         if let Some(mut width) = self.width {
             // for the sign-aware zero padding, we render the sign first and
             // behave as if we had no sign from the beginning.
@@ -1438,10 +1442,14 @@ impl<'a> Formatter<'a> {
             let len = formatted.len();
             let ret = if width <= len {
                 // no padding
-                self.write_formatted_parts(&formatted)
+                // SAFETY: Per the precondition.
+                unsafe { self.write_formatted_parts(&formatted) }
             } else {
                 let post_padding = self.padding(width - len, Alignment::Right)?;
-                self.write_formatted_parts(&formatted)?;
+                // SAFETY: Per the precondition.
+                unsafe {
+                    self.write_formatted_parts(&formatted)?;
+                }
                 post_padding.write(self)
             };
             self.fill = old_fill;
@@ -1449,20 +1457,20 @@ impl<'a> Formatter<'a> {
             ret
         } else {
             // this is the common case and we take a shortcut
-            self.write_formatted_parts(formatted)
+            // SAFETY: Per the precondition.
+            unsafe { self.write_formatted_parts(formatted) }
         }
     }
 
-    fn write_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
-        fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result {
+    /// # Safety
+    ///
+    /// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8.
+    unsafe fn write_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
+        unsafe fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result {
             // SAFETY: This is used for `numfmt::Part::Num` and `numfmt::Part::Copy`.
             // It's safe to use for `numfmt::Part::Num` since every char `c` is between
-            // `b'0'` and `b'9'`, which means `s` is valid UTF-8.
-            // It's also probably safe in practice to use for `numfmt::Part::Copy(buf)`
-            // since `buf` should be plain ASCII, but it's possible for someone to pass
-            // in a bad value for `buf` into `numfmt::to_shortest_str` since it is a
-            // public function.
-            // FIXME: Determine whether this could result in UB.
+            // `b'0'` and `b'9'`, which means `s` is valid UTF-8. It's safe to use for
+            // `numfmt::Part::Copy` due to this function's precondition.
             buf.write_str(unsafe { str::from_utf8_unchecked(s) })
         }
 
@@ -1489,11 +1497,15 @@ impl<'a> Formatter<'a> {
                         *c = b'0' + (v % 10) as u8;
                         v /= 10;
                     }
-                    write_bytes(self.buf, &s[..len])?;
+                    // SAFETY: Per the precondition.
+                    unsafe {
+                        write_bytes(self.buf, &s[..len])?;
+                    }
                 }
-                numfmt::Part::Copy(buf) => {
+                // SAFETY: Per the precondition.
+                numfmt::Part::Copy(buf) => unsafe {
                     write_bytes(self.buf, buf)?;
-                }
+                },
             }
         }
         Ok(())
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index d8365ae9bf9..4f42f73ebba 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -52,8 +52,12 @@ impl_int! { i8 i16 i32 i64 i128 isize }
 impl_uint! { u8 u16 u32 u64 u128 usize }
 
 /// A type that represents a specific radix
+///
+/// # Safety
+///
+/// `digit` must return an ASCII character.
 #[doc(hidden)]
-trait GenericRadix: Sized {
+unsafe trait GenericRadix: Sized {
     /// The number of digits.
     const BASE: u8;
 
@@ -129,7 +133,7 @@ struct UpperHex;
 
 macro_rules! radix {
     ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
-        impl GenericRadix for $T {
+        unsafe impl GenericRadix for $T {
             const BASE: u8 = $base;
             const PREFIX: &'static str = $prefix;
             fn digit(x: u8) -> u8 {
@@ -407,7 +411,7 @@ macro_rules! impl_Exp {
             let parts = &[
                 numfmt::Part::Copy(buf_slice),
                 numfmt::Part::Zero(added_precision),
-                numfmt::Part::Copy(exp_slice)
+                numfmt::Part::Copy(exp_slice),
             ];
             let sign = if !is_nonnegative {
                 "-"
@@ -416,8 +420,9 @@ macro_rules! impl_Exp {
             } else {
                 ""
             };
-            let formatted = numfmt::Formatted{sign, parts};
-            f.pad_formatted_parts(&formatted)
+            let formatted = numfmt::Formatted { sign, parts };
+            // SAFETY: `buf_slice` and `exp_slice` contain only ASCII characters.
+            unsafe { f.pad_formatted_parts(&formatted) }
         }
 
         $(
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index 76b3a32880d..0675e56358f 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -95,6 +95,16 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented(
     on(
+        _Self = "&[{A}]",
+        message = "a slice of type `{Self}` cannot be built since we need to store the elements somewhere",
+        label = "try explicitly collecting into a `Vec<{A}>`",
+    ),
+    on(
+        all(A = "{integer}", any(_Self = "&[{integral}]",)),
+        message = "a slice of type `{Self}` cannot be built since we need to store the elements somewhere",
+        label = "try explicitly collecting into a `Vec<{A}>`",
+    ),
+    on(
         _Self = "[{A}]",
         message = "a slice of type `{Self}` cannot be built since `{Self}` has no definite size",
         label = "try explicitly collecting into a `Vec<{A}>`",
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 289305253ec..afbfd6d362d 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -968,7 +968,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
 /// Integers and other types implementing [`Copy`] are unaffected by `drop`.
 ///
 /// ```
-/// # #![cfg_attr(not(bootstrap), allow(drop_copy))]
+/// # #![cfg_attr(not(bootstrap), allow(dropping_copy_types))]
 /// #[derive(Copy, Clone)]
 /// struct Foo(u8);
 ///
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index ecbf4e66fa4..ff9fa48f311 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -441,10 +441,18 @@ mod mut_ptr;
 ///
 /// * `to_drop` must be [valid] for both reads and writes.
 ///
-/// * `to_drop` must be properly aligned.
+/// * `to_drop` must be properly aligned, even if `T` has size 0.
 ///
-/// * The value `to_drop` points to must be valid for dropping, which may mean it must uphold
-///   additional invariants - this is type-dependent.
+/// * `to_drop` must be nonnull, even if `T` has size 0.
+///
+/// * The value `to_drop` points to must be valid for dropping, which may mean
+///   it must uphold additional invariants. These invariants depend on the type
+///   of the value being dropped. For instance, when dropping a Box, the box's
+///   pointer to the heap must be valid.
+///
+/// * While `drop_in_place` is executing, the only way to access parts of
+///   `to_drop` is through the `&mut self` references supplied to the
+///   `Drop::drop` methods that `drop_in_place` invokes.
 ///
 /// Additionally, if `T` is not [`Copy`], using the pointed-to value after
 /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
@@ -452,8 +460,6 @@ mod mut_ptr;
 /// again. [`write()`] can be used to overwrite data without causing it to be
 /// dropped.
 ///
-/// Note that even if `T` has size `0`, the pointer must be non-null and properly aligned.
-///
 /// [valid]: self#safety
 ///
 /// # Examples
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 43203c5824d..febdeb51463 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -733,8 +733,9 @@ impl<'a> Components<'a> {
         }
     }
 
-    // parse a given byte sequence into the corresponding path component
-    fn parse_single_component<'b>(&self, comp: &'b [u8]) -> Option<Component<'b>> {
+    // parse a given byte sequence following the OsStr encoding into the
+    // corresponding path component
+    unsafe fn parse_single_component<'b>(&self, comp: &'b [u8]) -> Option<Component<'b>> {
         match comp {
             b"." if self.prefix_verbatim() => Some(Component::CurDir),
             b"." => None, // . components are normalized away, except at
@@ -754,7 +755,8 @@ impl<'a> Components<'a> {
             None => (0, self.path),
             Some(i) => (1, &self.path[..i]),
         };
-        (comp.len() + extra, self.parse_single_component(comp))
+        // SAFETY: `comp` is a valid substring, since it is split on a separator.
+        (comp.len() + extra, unsafe { self.parse_single_component(comp) })
     }
 
     // parse a component from the right, saying how many bytes to consume to
@@ -766,7 +768,8 @@ impl<'a> Components<'a> {
             None => (0, &self.path[start..]),
             Some(i) => (1, &self.path[start + i + 1..]),
         };
-        (comp.len() + extra, self.parse_single_component(comp))
+        // SAFETY: `comp` is a valid substring, since it is split on a separator.
+        (comp.len() + extra, unsafe { self.parse_single_component(comp) })
     }
 
     // trim away repeated separators (i.e., empty components) on the left
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 710c8b52194..e192cda9a9a 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -350,7 +350,7 @@ impl SplitDebuginfo {
 }
 
 /// LTO mode used for compiling rustc itself.
-#[derive(Default, Clone, PartialEq)]
+#[derive(Default, Clone, PartialEq, Debug)]
 pub enum RustcLto {
     Off,
     #[default]
@@ -508,29 +508,42 @@ struct TomlConfig {
     profile: Option<String>,
 }
 
+/// Describes how to handle conflicts in merging two [`TomlConfig`]
+#[derive(Copy, Clone, Debug)]
+enum ReplaceOpt {
+    /// Silently ignore a duplicated value
+    IgnoreDuplicate,
+    /// Override the current value, even if it's `Some`
+    Override,
+    /// Exit with an error on duplicate values
+    ErrorOnDuplicate,
+}
+
 trait Merge {
-    fn merge(&mut self, other: Self);
+    fn merge(&mut self, other: Self, replace: ReplaceOpt);
 }
 
 impl Merge for TomlConfig {
     fn merge(
         &mut self,
-        TomlConfig { build, install, llvm, rust, dist, target, profile: _, changelog_seen: _ }: Self,
+        TomlConfig { build, install, llvm, rust, dist, target, profile: _, changelog_seen }: Self,
+        replace: ReplaceOpt,
     ) {
-        fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>) {
+        fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
             if let Some(new) = y {
                 if let Some(original) = x {
-                    original.merge(new);
+                    original.merge(new, replace);
                 } else {
                     *x = Some(new);
                 }
             }
         }
-        do_merge(&mut self.build, build);
-        do_merge(&mut self.install, install);
-        do_merge(&mut self.llvm, llvm);
-        do_merge(&mut self.rust, rust);
-        do_merge(&mut self.dist, dist);
+        self.changelog_seen.merge(changelog_seen, replace);
+        do_merge(&mut self.build, build, replace);
+        do_merge(&mut self.install, install, replace);
+        do_merge(&mut self.llvm, llvm, replace);
+        do_merge(&mut self.rust, rust, replace);
+        do_merge(&mut self.dist, dist, replace);
         assert!(target.is_none(), "merging target-specific config is not currently supported");
     }
 }
@@ -547,10 +560,33 @@ macro_rules! define_config {
         }
 
         impl Merge for $name {
-            fn merge(&mut self, other: Self) {
+            fn merge(&mut self, other: Self, replace: ReplaceOpt) {
                 $(
-                    if !self.$field.is_some() {
-                        self.$field = other.$field;
+                    match replace {
+                        ReplaceOpt::IgnoreDuplicate => {
+                            if self.$field.is_none() {
+                                self.$field = other.$field;
+                            }
+                        },
+                        ReplaceOpt::Override => {
+                            if other.$field.is_some() {
+                                self.$field = other.$field;
+                            }
+                        }
+                        ReplaceOpt::ErrorOnDuplicate => {
+                            if other.$field.is_some() {
+                                if self.$field.is_some() {
+                                    if cfg!(test) {
+                                        panic!("overriding existing option")
+                                    } else {
+                                        eprintln!("overriding existing option: `{}`", stringify!($field));
+                                        crate::detail_exit(2);
+                                    }
+                                } else {
+                                    self.$field = other.$field;
+                                }
+                            }
+                        }
                     }
                 )*
             }
@@ -623,6 +659,37 @@ macro_rules! define_config {
     }
 }
 
+impl<T> Merge for Option<T> {
+    fn merge(&mut self, other: Self, replace: ReplaceOpt) {
+        match replace {
+            ReplaceOpt::IgnoreDuplicate => {
+                if self.is_none() {
+                    *self = other;
+                }
+            }
+            ReplaceOpt::Override => {
+                if other.is_some() {
+                    *self = other;
+                }
+            }
+            ReplaceOpt::ErrorOnDuplicate => {
+                if other.is_some() {
+                    if self.is_some() {
+                        if cfg!(test) {
+                            panic!("overriding existing option")
+                        } else {
+                            eprintln!("overriding existing option");
+                            crate::detail_exit(2);
+                        }
+                    } else {
+                        *self = other;
+                    }
+                }
+            }
+        }
+    }
+}
+
 define_config! {
     /// TOML representation of various global build decisions.
     #[derive(Default)]
@@ -864,28 +931,27 @@ impl Config {
 
     pub fn parse(args: &[String]) -> Config {
         #[cfg(test)]
-        let get_toml = |_: &_| TomlConfig::default();
+        fn get_toml(_: &Path) -> TomlConfig {
+            TomlConfig::default()
+        }
+
         #[cfg(not(test))]
-        let get_toml = |file: &Path| {
+        fn get_toml(file: &Path) -> TomlConfig {
             let contents =
                 t!(fs::read_to_string(file), format!("config file {} not found", file.display()));
             // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of
             // TomlConfig and sub types to be monomorphized 5x by toml.
-            match toml::from_str(&contents)
+            toml::from_str(&contents)
                 .and_then(|table: toml::Value| TomlConfig::deserialize(table))
-            {
-                Ok(table) => table,
-                Err(err) => {
-                    eprintln!("failed to parse TOML configuration '{}': {}", file.display(), err);
+                .unwrap_or_else(|err| {
+                    eprintln!("failed to parse TOML configuration '{}': {err}", file.display());
                     crate::detail_exit(2);
-                }
-            }
-        };
-
+                })
+        }
         Self::parse_inner(args, get_toml)
     }
 
-    fn parse_inner<'a>(args: &[String], get_toml: impl 'a + Fn(&Path) -> TomlConfig) -> Config {
+    fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
         let mut flags = Flags::parse(&args);
         let mut config = Config::default_opts();
 
@@ -998,8 +1064,40 @@ impl Config {
             include_path.push("defaults");
             include_path.push(format!("config.{}.toml", include));
             let included_toml = get_toml(&include_path);
-            toml.merge(included_toml);
+            toml.merge(included_toml, ReplaceOpt::IgnoreDuplicate);
+        }
+
+        let mut override_toml = TomlConfig::default();
+        for option in flags.set.iter() {
+            fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
+                toml::from_str(&option)
+                    .and_then(|table: toml::Value| TomlConfig::deserialize(table))
+            }
+
+            let mut err = match get_table(option) {
+                Ok(v) => {
+                    override_toml.merge(v, ReplaceOpt::ErrorOnDuplicate);
+                    continue;
+                }
+                Err(e) => e,
+            };
+            // We want to be able to set string values without quotes,
+            // like in `configure.py`. Try adding quotes around the right hand side
+            if let Some((key, value)) = option.split_once("=") {
+                if !value.contains('"') {
+                    match get_table(&format!(r#"{key}="{value}""#)) {
+                        Ok(v) => {
+                            override_toml.merge(v, ReplaceOpt::ErrorOnDuplicate);
+                            continue;
+                        }
+                        Err(e) => err = e,
+                    }
+                }
+            }
+            eprintln!("failed to parse override `{option}`: `{err}");
+            crate::detail_exit(2)
         }
+        toml.merge(override_toml, ReplaceOpt::Override);
 
         config.changelog_seen = toml.changelog_seen;
 
diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs
index d913ca295e2..4de84b543ed 100644
--- a/src/bootstrap/config/tests.rs
+++ b/src/bootstrap/config/tests.rs
@@ -1,13 +1,11 @@
-use super::{Config, Flags, TomlConfig};
+use super::{Config, Flags};
 use clap::CommandFactory;
 use std::{env, path::Path};
 
-fn toml(config: &str) -> impl '_ + Fn(&Path) -> TomlConfig {
-    |&_| toml::from_str(config).unwrap()
-}
-
 fn parse(config: &str) -> Config {
-    Config::parse_inner(&["check".to_owned(), "--config=/does/not/exist".to_owned()], toml(config))
+    Config::parse_inner(&["check".to_owned(), "--config=/does/not/exist".to_owned()], |&_| {
+        toml::from_str(config).unwrap()
+    })
 }
 
 #[test]
@@ -94,3 +92,70 @@ fn detect_src_and_out() {
 fn clap_verify() {
     Flags::command().debug_assert();
 }
+
+#[test]
+fn override_toml() {
+    let config = Config::parse_inner(
+        &[
+            "check".to_owned(),
+            "--config=/does/not/exist".to_owned(),
+            "--set=changelog-seen=1".to_owned(),
+            "--set=rust.lto=fat".to_owned(),
+            "--set=rust.deny-warnings=false".to_owned(),
+            "--set=build.gdb=\"bar\"".to_owned(),
+            "--set=build.tools=[\"cargo\"]".to_owned(),
+            "--set=llvm.build-config={\"foo\" = \"bar\"}".to_owned(),
+        ],
+        |&_| {
+            toml::from_str(
+                r#"
+changelog-seen = 0
+[rust]
+lto = "off"
+deny-warnings = true
+
+[build]
+gdb = "foo"
+tools = []
+
+[llvm]
+download-ci-llvm = false
+build-config = {}
+                "#,
+            )
+            .unwrap()
+        },
+    );
+    assert_eq!(config.changelog_seen, Some(1), "setting top-level value");
+    assert_eq!(
+        config.rust_lto,
+        crate::config::RustcLto::Fat,
+        "setting string value without quotes"
+    );
+    assert_eq!(config.gdb, Some("bar".into()), "setting string value with quotes");
+    assert_eq!(config.deny_warnings, false, "setting boolean value");
+    assert_eq!(
+        config.tools,
+        Some(["cargo".to_string()].into_iter().collect()),
+        "setting list value"
+    );
+    assert_eq!(
+        config.llvm_build_config,
+        [("foo".to_string(), "bar".to_string())].into_iter().collect(),
+        "setting dictionary value"
+    );
+}
+
+#[test]
+#[should_panic]
+fn override_toml_duplicate() {
+    Config::parse_inner(
+        &[
+            "check".to_owned(),
+            "--config=/does/not/exist".to_owned(),
+            "--set=changelog-seen=1".to_owned(),
+            "--set=changelog-seen=2".to_owned(),
+        ],
+        |&_| toml::from_str("changelog-seen = 0").unwrap(),
+    );
+}
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index d8b298b59a3..80e71577798 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -158,6 +158,9 @@ pub struct Flags {
     #[arg(global(true))]
     /// paths for the subcommand
     pub paths: Vec<PathBuf>,
+    /// override options in config.toml
+    #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "section.option=value")]
+    pub set: Vec<String>,
     /// arguments passed to subcommands
     #[arg(global(true), last(true), value_name = "ARGS")]
     pub free_args: Vec<String>,
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 67cb8837391..040a12f5d10 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -185,6 +185,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
         ("arm-unknown-linux-gnueabi", false),
         ("arm-unknown-linux-gnueabihf", false),
         ("armv7-unknown-linux-gnueabihf", false),
+        ("loongarch64-unknown-linux-gnu", false),
         ("mips-unknown-linux-gnu", false),
         ("mips64-unknown-linux-gnuabi64", false),
         ("mips64el-unknown-linux-gnuabi64", false),
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index 5898a21d613..e799d7c9688 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -257,6 +257,22 @@ For targets: `i586-unknown-linux-gnu`
 (\*) Compressed debug is enabled by default for gas (assembly) on Linux/x86 targets,
      but that makes our `compiler_builtins` incompatible with binutils < 2.32.
 
+### `loongarch64-linux-gnu.defconfig`
+
+For targets: `loongarch64-unknown-linux-gnu`
+
+- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET}
+- Path and misc options > Use a mirror = ENABLE
+- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc
+- Target options > Target Architecture = loongarch
+- Target options > Bitness = 64-bit
+- Operating System > Target OS = linux
+- Operating System > Linux kernel version = 5.19.16
+- Binary utilities > Version of binutils = 2.40
+- C-library > glibc version = 2.36
+- C compiler > gcc version = 12.2.0
+- C compiler > C++ = ENABLE -- to cross compile LLVM
+
 ### `mips-linux-gnu.defconfig`
 
 For targets: `mips-unknown-linux-gnu`
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
new file mode 100644
index 00000000000..78689c429c2
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
@@ -0,0 +1,30 @@
+FROM ubuntu:22.04
+
+COPY scripts/cross-apt-packages.sh /scripts/
+RUN sh /scripts/cross-apt-packages.sh
+
+# The latest released version does not support LoongArch.
+COPY scripts/crosstool-ng-git.sh /scripts/
+RUN sh /scripts/crosstool-ng-git.sh
+
+COPY scripts/rustbuild-setup.sh /scripts/
+RUN sh /scripts/rustbuild-setup.sh
+WORKDIR /tmp
+
+COPY scripts/crosstool-ng-build.sh /scripts/
+COPY host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig /tmp/crosstool.defconfig
+RUN /scripts/crosstool-ng-build.sh
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV PATH=$PATH:/x-tools/loongarch64-unknown-linux-gnu/bin
+
+ENV CC_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-gcc \
+    AR_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-ar \
+    CXX_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-g++
+
+ENV HOSTS=loongarch64-unknown-linux-gnu
+
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig
new file mode 100644
index 00000000000..576f3631cd5
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig
@@ -0,0 +1,14 @@
+CT_CONFIG_VERSION="4"
+CT_EXPERIMENTAL=y
+CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
+CT_ARCH_LOONGARCH=y
+# CT_DEMULTILIB is not set
+CT_ARCH_USE_MMU=y
+CT_ARCH_ARCH="loongarch64"
+CT_KERNEL_LINUX=y
+CT_LINUX_V_5_19=y
+CT_GLIBC_V_2_36=y
+CT_CC_GCC_ENABLE_DEFAULT_PIE=y
+CT_CC_LANG_CXX=y
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index 6b4966ddeb4..806935b827f 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.16.3
\ No newline at end of file
+0.16.4
\ No newline at end of file
diff --git a/src/ci/docker/scripts/cross-apt-packages.sh b/src/ci/docker/scripts/cross-apt-packages.sh
index 2f8bf119424..398362ca52f 100644
--- a/src/ci/docker/scripts/cross-apt-packages.sh
+++ b/src/ci/docker/scripts/cross-apt-packages.sh
@@ -22,6 +22,7 @@ apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install
   patch \
   pkg-config \
   python3 \
+  rsync \
   sudo \
   texinfo \
   unzip \
diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh
new file mode 100644
index 00000000000..449cc476f9a
--- /dev/null
+++ b/src/ci/docker/scripts/crosstool-ng-git.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+URL=https://github.com/crosstool-ng/crosstool-ng
+REV=943364711a650d9b9e84c1b42c91cc0265b6ab5c
+
+mkdir crosstool-ng
+cd crosstool-ng
+git init
+git fetch --depth=1 ${URL} ${REV}
+git reset --hard FETCH_HEAD
+./bootstrap
+./configure --prefix=/usr/local
+make -j$(nproc)
+make install
+cd ..
+rm -rf crosstool-ng
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index f81e740936b..fd619467fc1 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -359,6 +359,9 @@ jobs:
           - name: dist-i686-linux
             <<: *job-linux-8c
 
+          - name: dist-loongarch64-linux
+            <<: *job-linux-8c
+
           - name: dist-mips-linux
             <<: *job-linux-8c
 
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject d9eb4c3f75435b008881062ffa77bf0d1527b37
+Subproject f2aed2fe8e9f55508c86ba3aa4b6789b18a08a2
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject b5f7500fc40775096c2bbd204eae096612cf904
+Subproject b5f018fb5930cb733b0a8aaf2eed975d4771e74
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 28dc0f3576b55f5e57c5d6e65cd68ba3161e9fd
+Subproject 553d99b02a53b4133a40d5bd2e19958c67487c0
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 28dbeaf5c44bc7f5111ad412e99f2d7c5cec6c9
+Subproject f1e637883fafeb83bdd5906ee7f467e4d35b733
diff --git a/src/doc/rustc/src/exploit-mitigations.md b/src/doc/rustc/src/exploit-mitigations.md
index 98b49e07171..a82a53248d4 100644
--- a/src/doc/rustc/src/exploit-mitigations.md
+++ b/src/doc/rustc/src/exploit-mitigations.md
@@ -115,9 +115,9 @@ equivalent.
   <tr>
    <td>Stack smashing protection
    </td>
-   <td>No
+   <td>Yes
    </td>
-   <td>
+   <td>Nightly
    </td>
   </tr>
   <tr>
@@ -432,18 +432,16 @@ saved return instruction pointer, and checking if this value has changed
 when returning from a function. This is also known as “Stack Protector” or
 “Stack Smashing Protector (SSP)”.
 
-The Rust compiler does not support stack smashing protection. However, more
-comprehensive alternatives to stack smashing protection exist, such as
-shadow and safe stack (see backward-edge control flow protection).
+The Rust compiler supports stack smashing protection on nightly builds[42].
 
 ![Screenshot of IDA Pro listing cross references to __stack_chk_fail in hello-rust.](images/image3.png "Cross references to __stack_chk_fail in hello-rust.")
 Fig. 14. IDA Pro listing cross references to `__stack_chk_fail` in
 hello-rust.
 
 To check if stack smashing protection is enabled for a given binary, search
-for cross references to `__stack_chk_fail`. The only cross references to
-`__stack_chk_fail` in hello-rust are from the statically-linked libbacktrace
-library (see Fig. 14).
+for cross references to `__stack_chk_fail`. The presence of these
+cross-references in Rust-compiled code (e.g., `hello_rust::main`) indicates
+that the stack smashing protection is enabled (see Fig. 14).
 
 
 ### Forward-edge control flow protection
@@ -697,3 +695,6 @@ defaults (unrelated to `READ_IMPLIES_EXEC`).
 
 41. “ControlFlowIntegrity.” The Rust Unstable Book.
     [https://doc.rust-lang.org/unstable-book/compiler-flags/sanitizer.html#controlflowintegrity](../unstable-book/compiler-flags/sanitizer.html#controlflowintegrity).
+
+42. bbjornse. “add codegen option for using LLVM stack smash protection #84197.”
+    GitHub. <https://github.com/rust-lang/rust/pull/84197>
diff --git a/src/doc/rustc/src/images/image3.png b/src/doc/rustc/src/images/image3.png
index a49e14b5ed2..ef02c605ead 100644
--- a/src/doc/rustc/src/images/image3.png
+++ b/src/doc/rustc/src/images/image3.png
Binary files differdiff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index d22e1cf7f68..3b2463aa5b2 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -88,6 +88,7 @@ target | notes
 `arm-unknown-linux-gnueabi` | ARMv6 Linux (kernel 3.2, glibc 2.17)
 `arm-unknown-linux-gnueabihf` | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
 `armv7-unknown-linux-gnueabihf` | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
+[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)
 `mips-unknown-linux-gnu` | MIPS Linux (kernel 4.4, glibc 2.23)
 `mips64-unknown-linux-gnuabi64` | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23)
 `mips64el-unknown-linux-gnuabi64` | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23)
@@ -266,7 +267,6 @@ target | std | host | notes
 `i686-uwp-windows-gnu` | ? |  |
 `i686-uwp-windows-msvc` | ? |  |
 `i686-wrs-vxworks` | ? |  |
-[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | ? |  | LoongArch64 Linux (LP64D ABI)
 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? |  | Motorola 680x0 Linux
 `mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
 [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? |  | MIPS64 for OpenWrt Linux MUSL
diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md
index 16ccaf46b2f..999e71f8028 100644
--- a/src/doc/rustc/src/platform-support/loongarch-linux.md
+++ b/src/doc/rustc/src/platform-support/loongarch-linux.md
@@ -1,6 +1,6 @@
 # loongarch\*-unknown-linux-\*
 
-**Tier: 3**
+**Tier: 2**
 
 [LoongArch] is a new RISC ISA developed by Loongson Technology Corporation Limited.
 
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 4eddd5cedf1..9f65f1eeeb7 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -19,6 +19,7 @@ complete -c x.py -n "__fish_use_subcommand" -l rust-profile-generate -d 'generat
 complete -c x.py -n "__fish_use_subcommand" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_use_subcommand" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_use_subcommand" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_use_subcommand" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_use_subcommand" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_use_subcommand" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -62,6 +63,7 @@ complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from build" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from build" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_seen_subcommand_from build" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -91,6 +93,7 @@ complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from check" -l all-targets -d 'Check all targets'
 complete -c x.py -n "__fish_seen_subcommand_from check" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from check" -s i -l incremental -d 'use incremental compilation'
@@ -125,6 +128,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-generat
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l fix
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -s i -l incremental -d 'use incremental compilation'
@@ -155,6 +159,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-generate -
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fix" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from fix" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -184,6 +189,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-generate -
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l check -d 'check formatting instead of applying'
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -s i -l incremental -d 'use incremental compilation'
@@ -214,6 +220,7 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-generate -
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l open -d 'open the docs in a browser'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l json -d 'render the documentation in JSON format in addition to the usual HTML format'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
@@ -251,6 +258,7 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from test" -l no-fail-fast -d 'run all tests regardless of failure'
 complete -c x.py -n "__fish_seen_subcommand_from test" -l no-doc -d 'do not run doc tests'
 complete -c x.py -n "__fish_seen_subcommand_from test" -l doc -d 'only run doc tests'
@@ -288,6 +296,7 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from bench" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from bench" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -317,6 +326,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l all
 complete -c x.py -n "__fish_seen_subcommand_from clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from clean" -s i -l incremental -d 'use incremental compilation'
@@ -347,6 +357,7 @@ complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from dist" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from dist" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -376,6 +387,7 @@ complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-genera
 complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from install" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from install" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_seen_subcommand_from install" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -406,6 +418,7 @@ complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-generate -
 complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from run" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from run" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_seen_subcommand_from run" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -435,6 +448,7 @@ complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from setup" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from setup" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -464,6 +478,7 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-genera
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l set -d 'override options in config.toml' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l run -d 'run suggested tests'
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -s i -l incremental -d 'use incremental compilation'
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 59fabf53f98..569c186555c 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -43,6 +43,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -93,6 +94,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -129,6 +131,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('--all-targets', 'all-targets', [CompletionResultType]::ParameterName, 'Check all targets')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -170,6 +173,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('--fix', 'fix', [CompletionResultType]::ParameterName, 'fix')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -207,6 +211,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -243,6 +248,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'check formatting instead of applying')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -280,6 +286,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('--open', 'open', [CompletionResultType]::ParameterName, 'open the docs in a browser')
             [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'render the documentation in JSON format in addition to the usual HTML format')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -324,6 +331,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('--no-fail-fast', 'no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
             [CompletionResult]::new('--no-doc', 'no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
             [CompletionResult]::new('--doc', 'doc', [CompletionResultType]::ParameterName, 'only run doc tests')
@@ -368,6 +376,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -404,6 +413,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'all')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -441,6 +451,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -477,6 +488,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -514,6 +526,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -550,6 +563,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -586,6 +600,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
             [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
             [CompletionResult]::new('--run', 'run', [CompletionResultType]::ParameterName, 'run suggested tests')
             [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index 931cc4353b2..322afdb2883 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -61,7 +61,7 @@ _x.py() {
 
     case "${cmd}" in
         x.py)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -155,6 +155,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -163,7 +167,7 @@ _x.py() {
             return 0
             ;;
         x.py__bench)
-            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -261,6 +265,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -269,7 +277,7 @@ _x.py() {
             return 0
             ;;
         x.py__build)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -363,6 +371,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -371,7 +383,7 @@ _x.py() {
             return 0
             ;;
         x.py__check)
-            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -465,6 +477,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -473,7 +489,7 @@ _x.py() {
             return 0
             ;;
         x.py__clean)
-            opts="-v -i -j -h --all --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -567,6 +583,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -575,7 +595,7 @@ _x.py() {
             return 0
             ;;
         x.py__clippy)
-            opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -685,6 +705,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -693,7 +717,7 @@ _x.py() {
             return 0
             ;;
         x.py__dist)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -787,6 +811,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -795,7 +823,7 @@ _x.py() {
             return 0
             ;;
         x.py__doc)
-            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -889,6 +917,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -897,7 +929,7 @@ _x.py() {
             return 0
             ;;
         x.py__fix)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -991,6 +1023,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -999,7 +1035,7 @@ _x.py() {
             return 0
             ;;
         x.py__fmt)
-            opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1093,6 +1129,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1101,7 +1141,7 @@ _x.py() {
             return 0
             ;;
         x.py__install)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1195,6 +1235,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1203,7 +1247,7 @@ _x.py() {
             return 0
             ;;
         x.py__run)
-            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1301,6 +1345,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1309,7 +1357,7 @@ _x.py() {
             return 0
             ;;
         x.py__setup)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1403,6 +1451,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1411,7 +1463,7 @@ _x.py() {
             return 0
             ;;
         x.py__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1505,6 +1557,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1513,7 +1569,7 @@ _x.py() {
             return 0
             ;;
         x.py__test)
-            opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1631,6 +1687,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css
index 99cf8e443f0..c1324c0760e 100644
--- a/src/librustdoc/html/static/css/settings.css
+++ b/src/librustdoc/html/static/css/settings.css
@@ -1,6 +1,5 @@
 .setting-line {
 	margin: 1.2em 0.6em;
-	position: relative;
 }
 
 .setting-radio input, .setting-check input {
@@ -15,11 +14,6 @@
 .setting-radio input {
 	border-radius: 50%;
 }
-.setting-check input:checked {
-	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">\
-		<path d="M7,25L17,32L33,12" fill="none" stroke="black" stroke-width="5"/>\
-		<path d="M7,23L17,30L33,10" fill="none" stroke="white" stroke-width="5"/></svg>');
-}
 
 .setting-radio span, .setting-check span {
 	padding-bottom: 1px;
@@ -52,6 +46,9 @@
 .setting-check input:checked {
 	background-color: var(--settings-input-color);
 	border-width: 1px;
+	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">\
+		<path d="M7,25L17,32L33,12" fill="none" stroke="black" stroke-width="5"/>\
+		<path d="M7,23L17,30L33,10" fill="none" stroke="white" stroke-width="5"/></svg>');
 }
 .setting-radio input:focus, .setting-check input:focus {
 	box-shadow: 0 0 1px 1px var(--settings-input-color);
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 9381b3e0567..9e6894a77df 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -149,7 +149,7 @@ impl TryFrom<ResolveRes> for Res {
             Def(kind, id) => Ok(Res::Def(kind, id)),
             PrimTy(prim) => Ok(Res::Primitive(PrimitiveType::from_hir(prim))),
             // e.g. `#[derive]`
-            NonMacroAttr(..) | Err => Result::Err(()),
+            ToolMod | NonMacroAttr(..) | Err => Result::Err(()),
             other => bug!("unrecognized res {:?}", other),
         }
     }
diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml
index d63caa7ad70..d3548036d4c 100644
--- a/src/rustdoc-json-types/Cargo.toml
+++ b/src/rustdoc-json-types/Cargo.toml
@@ -12,3 +12,4 @@ rustc-hash = "1.1.0"
 
 [dev-dependencies]
 serde_json = "1.0"
+bincode = "1"
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 3556834071f..ba8eeaa6682 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
 use std::path::PathBuf;
 
 /// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 25;
+pub const FORMAT_VERSION: u32 = 26;
 
 /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
 /// about the language items in the local crate, as well as info about external items to allow
@@ -83,7 +83,6 @@ pub struct Item {
     /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
     pub attrs: Vec<String>,
     pub deprecation: Option<Deprecation>,
-    #[serde(flatten)]
     pub inner: ItemEnum,
 }
 
@@ -222,7 +221,7 @@ pub enum ItemKind {
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
-#[serde(tag = "kind", content = "inner", rename_all = "snake_case")]
+#[serde(rename_all = "snake_case")]
 pub enum ItemEnum {
     Module(Module),
     ExternCrate {
@@ -543,7 +542,6 @@ pub enum Term {
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 #[serde(rename_all = "snake_case")]
-#[serde(tag = "kind", content = "inner")]
 pub enum Type {
     /// Structs, enums, and unions
     ResolvedPath(Path),
diff --git a/src/rustdoc-json-types/tests.rs b/src/rustdoc-json-types/tests.rs
index 399ff54b294..1126d5f786f 100644
--- a/src/rustdoc-json-types/tests.rs
+++ b/src/rustdoc-json-types/tests.rs
@@ -8,11 +8,15 @@ fn test_struct_info_roundtrip() {
         impls: vec![],
     });
 
+    // JSON
     let struct_json = serde_json::to_string(&s).unwrap();
-
     let de_s = serde_json::from_str(&struct_json).unwrap();
-
     assert_eq!(s, de_s);
+
+    // Bincode
+    let encoded: Vec<u8> = bincode::serialize(&s).unwrap();
+    let decoded: ItemEnum = bincode::deserialize(&encoded).unwrap();
+    assert_eq!(s, decoded);
 }
 
 #[test]
@@ -24,9 +28,13 @@ fn test_union_info_roundtrip() {
         impls: vec![],
     });
 
+    // JSON
     let union_json = serde_json::to_string(&u).unwrap();
-
     let de_u = serde_json::from_str(&union_json).unwrap();
-
     assert_eq!(u, de_u);
+
+    // Bincode
+    let encoded: Vec<u8> = bincode::serialize(&u).unwrap();
+    let decoded: ItemEnum = bincode::deserialize(&encoded).unwrap();
+    assert_eq!(u, decoded);
 }
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 21dad9eb74a..8b28c68e04f 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -24,6 +24,7 @@ static HOSTS: &[&str] = &[
     "i686-pc-windows-gnu",
     "i686-pc-windows-msvc",
     "i686-unknown-linux-gnu",
+    "loongarch64-unknown-linux-gnu",
     "mips-unknown-linux-gnu",
     "mips64-unknown-linux-gnuabi64",
     "mips64el-unknown-linux-gnuabi64",
@@ -97,6 +98,7 @@ static TARGETS: &[&str] = &[
     "i686-unknown-linux-gnu",
     "i686-unknown-linux-musl",
     "i686-unknown-uefi",
+    "loongarch64-unknown-linux-gnu",
     "m68k-unknown-linux-gnu",
     "mips-unknown-linux-gnu",
     "mips-unknown-linux-musl",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 09276c703a473ab33daaeb94917232e80eefd62
+Subproject 64fb38c97ac4d3a327fc9032c862dd28c8833b1
diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
index b2f7d026cc8..9c60edb1794 100644
--- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
@@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
             let is_copy = is_copy(cx, arg_ty);
             let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
             let (lint, msg) = match fn_name {
-                // early return for uplifted lints: drop_ref, drop_copy, forget_ref, forget_copy
+                // early return for uplifted lints: dropping_references, dropping_copy_types, forgetting_references, forgetting_copy_types
                 sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return,
                 sym::mem_forget if arg_ty.is_ref() => return,
                 sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return,
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index a2c3465cde4..b0db56bb417 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -33,13 +33,13 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::zero_width_space", "clippy::invisible_characters"),
     ("clippy::clone_double_ref", "suspicious_double_ref_op"),
     ("clippy::drop_bounds", "drop_bounds"),
-    ("clippy::drop_copy", "drop_copy"),
-    ("clippy::drop_ref", "drop_ref"),
+    ("clippy::drop_copy", "dropping_copy_types"),
+    ("clippy::drop_ref", "dropping_references"),
     ("clippy::for_loop_over_option", "for_loops_over_fallibles"),
     ("clippy::for_loop_over_result", "for_loops_over_fallibles"),
     ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
-    ("clippy::forget_copy", "forget_copy"),
-    ("clippy::forget_ref", "forget_ref"),
+    ("clippy::forget_copy", "forgetting_copy_types"),
+    ("clippy::forget_ref", "forgetting_references"),
     ("clippy::into_iter_on_array", "array_into_iter"),
     ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
     ("clippy::invalid_ref", "invalid_value"),
diff --git a/src/tools/clippy/tests/ui/mem_forget.rs b/src/tools/clippy/tests/ui/mem_forget.rs
index 5137448a6d4..edb9d87d032 100644
--- a/src/tools/clippy/tests/ui/mem_forget.rs
+++ b/src/tools/clippy/tests/ui/mem_forget.rs
@@ -5,7 +5,7 @@ use std::mem as memstuff;
 use std::mem::forget as forgetSomething;
 
 #[warn(clippy::mem_forget)]
-#[allow(forget_copy)]
+#[allow(forgetting_copy_types)]
 fn main() {
     let five: i32 = 5;
     forgetSomething(five);
diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
index f28153e56b0..4ef6f0ca92f 100644
--- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
@@ -2,7 +2,7 @@
 #![allow(unused)]
 #![allow(deref_nullptr)]
 #![allow(clippy::unnecessary_operation)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 #![warn(clippy::multiple_unsafe_ops_per_block)]
 
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 7c2acf43fe8..dfe45dec8a7 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -30,11 +30,11 @@
 #![allow(clippy::invisible_characters)]
 #![allow(suspicious_double_ref_op)]
 #![allow(drop_bounds)]
-#![allow(drop_copy)]
-#![allow(drop_ref)]
+#![allow(dropping_copy_types)]
+#![allow(dropping_references)]
 #![allow(for_loops_over_fallibles)]
-#![allow(forget_copy)]
-#![allow(forget_ref)]
+#![allow(forgetting_copy_types)]
+#![allow(forgetting_references)]
 #![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
 #![allow(invalid_value)]
@@ -77,13 +77,13 @@
 #![warn(clippy::invisible_characters)]
 #![warn(suspicious_double_ref_op)]
 #![warn(drop_bounds)]
-#![warn(drop_copy)]
-#![warn(drop_ref)]
+#![warn(dropping_copy_types)]
+#![warn(dropping_references)]
 #![warn(for_loops_over_fallibles)]
 #![warn(for_loops_over_fallibles)]
 #![warn(for_loops_over_fallibles)]
-#![warn(forget_copy)]
-#![warn(forget_ref)]
+#![warn(forgetting_copy_types)]
+#![warn(forgetting_references)]
 #![warn(array_into_iter)]
 #![warn(invalid_atomic_ordering)]
 #![warn(invalid_value)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 8d334b0d050..ce8eca5a308 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -30,11 +30,11 @@
 #![allow(clippy::invisible_characters)]
 #![allow(suspicious_double_ref_op)]
 #![allow(drop_bounds)]
-#![allow(drop_copy)]
-#![allow(drop_ref)]
+#![allow(dropping_copy_types)]
+#![allow(dropping_references)]
 #![allow(for_loops_over_fallibles)]
-#![allow(forget_copy)]
-#![allow(forget_ref)]
+#![allow(forgetting_copy_types)]
+#![allow(forgetting_references)]
 #![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
 #![allow(invalid_value)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index fbf8d3d7e4e..3fca60aa2eb 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -186,17 +186,17 @@ error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
 LL | #![warn(clippy::drop_bounds)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
 
-error: lint `clippy::drop_copy` has been renamed to `drop_copy`
+error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
   --> $DIR/rename.rs:80:9
    |
 LL | #![warn(clippy::drop_copy)]
-   |         ^^^^^^^^^^^^^^^^^ help: use the new name: `drop_copy`
+   |         ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
 
-error: lint `clippy::drop_ref` has been renamed to `drop_ref`
+error: lint `clippy::drop_ref` has been renamed to `dropping_references`
   --> $DIR/rename.rs:81:9
    |
 LL | #![warn(clippy::drop_ref)]
-   |         ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref`
+   |         ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
 
 error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
   --> $DIR/rename.rs:82:9
@@ -216,17 +216,17 @@ error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_ov
 LL | #![warn(clippy::for_loops_over_fallibles)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
-error: lint `clippy::forget_copy` has been renamed to `forget_copy`
+error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
   --> $DIR/rename.rs:85:9
    |
 LL | #![warn(clippy::forget_copy)]
-   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_copy`
+   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
 
-error: lint `clippy::forget_ref` has been renamed to `forget_ref`
+error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
   --> $DIR/rename.rs:86:9
    |
 LL | #![warn(clippy::forget_ref)]
-   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_ref`
+   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
 
 error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
   --> $DIR/rename.rs:87:9
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 737423a2cd1..7bedb5d48f6 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -184,6 +184,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "ctrlc"
+version = "3.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639"
+dependencies = [
+ "nix",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
 name = "diff"
 version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -421,6 +431,7 @@ name = "miri"
 version = "0.1.0"
 dependencies = [
  "colored",
+ "ctrlc",
  "env_logger",
  "getrandom",
  "lazy_static",
@@ -438,6 +449,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "nix"
+version = "0.26.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+ "static_assertions",
+]
+
+[[package]]
 name = "object"
 version = "0.30.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -714,6 +737,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
 
 [[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
 name = "syn"
 version = "2.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index 5987b0df8d6..683f99ca4de 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -29,6 +29,7 @@ smallvec = "1.7"
 # for more information.
 rustc-workspace-hack = "1.0.0"
 measureme = "10.0.0"
+ctrlc = "3.2.5"
 
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
diff --git a/src/tools/miri/cargo-miri/src/arg.rs b/src/tools/miri/cargo-miri/src/arg.rs
index e8bac4625f7..d7216060358 100644
--- a/src/tools/miri/cargo-miri/src/arg.rs
+++ b/src/tools/miri/cargo-miri/src/arg.rs
@@ -40,7 +40,8 @@ impl<'s, I: Iterator<Item = Cow<'s, str>>> Iterator for ArgSplitFlagValue<'_, I>
         if arg == "--" {
             // Stop searching at `--`.
             self.args = None;
-            return None;
+            // But yield the `--` so that it does not get lost!
+            return Some(Err(Cow::Borrowed("--")));
         }
         // These branches cannot be merged if we want to avoid the allocation in the `Borrowed` branch.
         match &arg {
@@ -79,9 +80,8 @@ impl<'a, I: Iterator<Item = String> + 'a> ArgSplitFlagValue<'a, I> {
     ) -> impl Iterator<Item = Result<String, String>> + 'a {
         ArgSplitFlagValue::new(args.map(Cow::Owned), name).map(|x| {
             match x {
-                Ok(Cow::Owned(s)) => Ok(s),
-                Err(Cow::Owned(s)) => Err(s),
-                _ => panic!("iterator converted owned to borrowed"),
+                Ok(s) => Ok(s.into_owned()),
+                Err(s) => Err(s.into_owned()),
             }
         })
     }
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index 37f66d0033f..465e4a1b2d2 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -113,30 +113,17 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
     };
     let metadata = get_cargo_metadata();
     let mut cmd = cargo();
-    cmd.arg(cargo_cmd);
-
-    // Forward all arguments before `--` other than `--target-dir` and its value to Cargo.
-    // (We want to *change* the target-dir value, so we must not forward it.)
-    let mut target_dir = None;
-    for arg in ArgSplitFlagValue::from_string_iter(&mut args, "--target-dir") {
-        match arg {
-            Ok(value) => {
-                if target_dir.is_some() {
-                    show_error!("`--target-dir` is provided more than once");
-                }
-                target_dir = Some(value.into());
-            }
-            Err(arg) => {
-                cmd.arg(arg);
-            }
-        }
+    cmd.arg(&cargo_cmd);
+    // In nextest we have to also forward the main `verb`.
+    if cargo_cmd == "nextest" {
+        cmd.arg(
+            args.next()
+                .unwrap_or_else(|| show_error!("`cargo miri nextest` expects a verb (e.g. `run`)")),
+        );
     }
-    // Detect the target directory if it's not specified via `--target-dir`.
-    // (`cargo metadata` does not support `--target-dir`, that's why we have to handle this ourselves.)
-    let target_dir = target_dir.get_or_insert_with(|| metadata.target_directory.clone());
-    // Set `--target-dir` to `miri` inside the original target directory.
-    target_dir.push("miri");
-    cmd.arg("--target-dir").arg(target_dir);
+    // We set the following flags *before* forwarding more arguments.
+    // This is needed to fix <https://github.com/rust-lang/miri/issues/2829>: cargo will stop
+    // interpreting things as flags when it sees the first positional argument.
 
     // Make sure the build target is explicitly set.
     // This is needed to make the `target.runner` settings do something,
@@ -154,8 +141,23 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
     cmd.arg("--config")
         .arg(format!("target.'cfg(all())'.runner=[{cargo_miri_path_for_toml}, 'runner']"));
 
-    // Forward all further arguments after `--` to cargo.
-    cmd.arg("--").args(args);
+    // Set `--target-dir` to `miri` inside the original target directory.
+    let mut target_dir = match get_arg_flag_value("--target-dir") {
+        Some(dir) => PathBuf::from(dir),
+        None => metadata.target_directory.clone().into_std_path_buf(),
+    };
+    target_dir.push("miri");
+    cmd.arg("--target-dir").arg(target_dir);
+
+    // *After* we set all the flags that need setting, forward everything else. Make sure to skip
+    // `--target-dir` (which would otherwise be set twice).
+    for arg in
+        ArgSplitFlagValue::from_string_iter(&mut args, "--target-dir").filter_map(Result::err)
+    {
+        cmd.arg(arg);
+    }
+    // Forward all further arguments (not consumed by `ArgSplitFlagValue`) to cargo.
+    cmd.args(args);
 
     // Set `RUSTC_WRAPPER` to ourselves.  Cargo will prepend that binary to its usual invocation,
     // i.e., the first argument is `rustc` -- which is what we use in `main` to distinguish
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index b450f986149..0bff100dc14 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-69fef92ab2f287f072b66fb7b4f62c8bb4acba43
+8b4b20836b832e91aa605a2faf5e2a55190202c8
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index e9bbae4d504..d85cac7bcbb 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -3,6 +3,7 @@
 use std::cell::RefCell;
 use std::collections::hash_map::Entry;
 use std::num::TryFromIntError;
+use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
 use std::task::Poll;
 use std::time::{Duration, SystemTime};
 
@@ -1012,8 +1013,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     /// Run the core interpreter loop. Returns only when an interrupt occurs (an error or program
     /// termination).
     fn run_threads(&mut self) -> InterpResult<'tcx, !> {
+        static SIGNALED: AtomicBool = AtomicBool::new(false);
+        ctrlc::set_handler(move || {
+            // Indicate that we have ben signaled to stop. If we were already signaled, exit
+            // immediately. In our interpreter loop we try to consult this value often, but if for
+            // whatever reason we don't get to that check or the cleanup we do upon finding that
+            // this bool has become true takes a long time, the exit here will promptly exit the
+            // process on the second Ctrl-C.
+            if SIGNALED.swap(true, Relaxed) {
+                std::process::exit(1);
+            }
+        })
+        .unwrap();
         let this = self.eval_context_mut();
         loop {
+            if SIGNALED.load(Relaxed) {
+                this.machine.handle_abnormal_termination();
+                std::process::exit(1);
+            }
             match this.machine.threads.schedule(&this.machine.clock)? {
                 SchedulingAction::ExecuteStep => {
                     if !this.step()? {
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 32717a0d28b..29f518fe58b 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -713,6 +713,15 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
         let def_id = frame.instance.def_id();
         def_id.is_local() || self.local_crates.contains(&def_id.krate)
     }
+
+    /// Called when the interpreter is going to shut down abnormally, such as due to a Ctrl-C.
+    pub(crate) fn handle_abnormal_termination(&mut self) {
+        // All strings in the profile data are stored in a single string table which is not
+        // written to disk until the profiler is dropped. If the interpreter exits without dropping
+        // the profiler, it is not possible to interpret the profile data and all measureme tools
+        // will panic when given the file.
+        drop(self.profiler.take());
+    }
 }
 
 impl VisitTags for MiriMachine<'_, '_> {
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index 1e4ab2f0f62..323991249d3 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -102,7 +102,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let ptr_layout = this.layout_of(ptr_ty)?;
 
                 for (i, ptr) in ptrs.into_iter().enumerate() {
-                    let offset = ptr_layout.size * i.try_into().unwrap();
+                    let offset = ptr_layout.size.checked_mul(i.try_into().unwrap(), this).unwrap();
 
                     let op_place = buf_place.offset(offset, ptr_layout, this)?;
 
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 44bca3796f9..aa0794c00be 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -166,7 +166,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| {
                         // We add 1 to the number because that's what rustc also does everywhere it
                         // calls `CrateNum::new`...
-                        #[allow(clippy::integer_arithmetic)]
+                        #[allow(clippy::arithmetic_side_effects)]
                         (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1))
                     }),
                 ) {
@@ -707,7 +707,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     .position(|&c| c == val)
                 {
                     let idx = u64::try_from(idx).unwrap();
-                    #[allow(clippy::integer_arithmetic)] // idx < num, so this never wraps
+                    #[allow(clippy::arithmetic_side_effects)] // idx < num, so this never wraps
                     let new_ptr = ptr.offset(Size::from_bytes(num - idx - 1), this)?;
                     this.write_pointer(new_ptr, dest)?;
                 } else {
@@ -916,10 +916,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let a = this.read_scalar(a)?.to_u64()?;
                 let b = this.read_scalar(b)?.to_u64()?;
 
-                #[allow(clippy::integer_arithmetic)]
+                #[allow(clippy::arithmetic_side_effects)]
                 // adding two u64 and a u8 cannot wrap in a u128
                 let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b);
-                #[allow(clippy::integer_arithmetic)] // it's a u128, we can shift by 64
+                #[allow(clippy::arithmetic_side_effects)] // it's a u128, we can shift by 64
                 let (c_out, sum) = ((wide_sum >> 64).truncate::<u8>(), wide_sum.truncate::<u64>());
 
                 let c_out_field = this.place_field(dest, 0)?;
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index 114c66253f7..1995db715e8 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -563,7 +563,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let (op, op_len) = this.operand_to_simd(op)?;
                 let bitmask_len = op_len.max(8);
 
-                assert!(dest.layout.ty.is_integral());
+                // Returns either an unsigned integer or array of `u8`.
+                assert!(
+                    dest.layout.ty.is_integral()
+                        || matches!(dest.layout.ty.kind(), ty::Array(elemty, _) if elemty == &this.tcx.types.u8)
+                );
                 assert!(bitmask_len <= 64);
                 assert_eq!(bitmask_len, dest.layout.size.bits());
                 let op_len = u32::try_from(op_len).unwrap();
@@ -577,7 +581,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                             .unwrap();
                     }
                 }
-                this.write_int(res, dest)?;
+                // We have to force the place type to be an int so that we can write `res` into it.
+                let mut dest = this.force_allocation(dest)?;
+                dest.layout = this.machine.layouts.uint(dest.layout.size).unwrap();
+                this.write_int(res, &dest.into())?;
             }
 
             name => throw_unsup_format!("unimplemented intrinsic: `simd_{name}`"),
@@ -605,7 +612,7 @@ fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 {
     assert!(idx < vec_len);
     match endianness {
         Endian::Little => idx,
-        #[allow(clippy::integer_arithmetic)] // idx < vec_len
+        #[allow(clippy::arithmetic_side_effects)] // idx < vec_len
         Endian::Big => vec_len - 1 - idx, // reverse order of bits
     }
 }
diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs
index 918efda3777..a423a0786b7 100644
--- a/src/tools/miri/src/shims/mod.rs
+++ b/src/tools/miri/src/shims/mod.rs
@@ -1,4 +1,4 @@
-#![warn(clippy::integer_arithmetic)]
+#![warn(clippy::arithmetic_side_effects)]
 
 mod backtrace;
 #[cfg(target_os = "linux")]
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index 2f24c00ce14..756dec1beca 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -108,7 +108,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         Ok(0)
     }
 
-    #[allow(non_snake_case, clippy::integer_arithmetic)]
+    #[allow(non_snake_case, clippy::arithmetic_side_effects)]
     fn GetSystemTimeAsFileTime(
         &mut self,
         LPFILETIME_op: &OpTy<'tcx, Provenance>,
diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs
index 685feeaf892..62bd087e7e8 100644
--- a/src/tools/miri/src/shims/tls.rs
+++ b/src/tools/miri/src/shims/tls.rs
@@ -56,7 +56,7 @@ impl<'tcx> Default for TlsData<'tcx> {
 impl<'tcx> TlsData<'tcx> {
     /// Generate a new TLS key with the given destructor.
     /// `max_size` determines the integer size the key has to fit in.
-    #[allow(clippy::integer_arithmetic)]
+    #[allow(clippy::arithmetic_side_effects)]
     pub fn create_tls_key(
         &mut self,
         dtor: Option<ty::Instance<'tcx>>,
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index abec782b4f0..d1b09cd7b55 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -458,7 +458,7 @@ pub struct DirHandler {
 }
 
 impl DirHandler {
-    #[allow(clippy::integer_arithmetic)]
+    #[allow(clippy::arithmetic_side_effects)]
     fn insert_new(&mut self, read_dir: ReadDir) -> u64 {
         let id = self.next_id;
         self.next_id += 1;
diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs
index ffe3ca69c58..6889c430042 100644
--- a/src/tools/miri/src/shims/unix/linux/sync.rs
+++ b/src/tools/miri/src/shims/unix/linux/sync.rs
@@ -247,7 +247,7 @@ pub fn futex<'tcx>(
             // before doing the syscall.
             this.atomic_fence(AtomicFenceOrd::SeqCst)?;
             let mut n = 0;
-            #[allow(clippy::integer_arithmetic)]
+            #[allow(clippy::arithmetic_side_effects)]
             for _ in 0..val {
                 if let Some(thread) = this.futex_wake(addr_usize, bitset) {
                     this.unblock_thread(thread);
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index f72ba5cca7a..b8bb7f62452 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -219,7 +219,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     .copied()
                     .scan(Size::ZERO, |a, x| {
                         let res = Some(*a);
-                        *a += x;
+                        *a = a.checked_add(x, this).unwrap();
                         res
                     })
                     .collect();
diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs
index 8bffa9991c7..d9ae1b22409 100644
--- a/src/tools/miri/src/shims/windows/handle.rs
+++ b/src/tools/miri/src/shims/windows/handle.rs
@@ -62,7 +62,7 @@ impl Handle {
         let floor_log2 = variant_count.ilog2();
 
         // we need to add one for non powers of two to compensate for the difference
-        #[allow(clippy::integer_arithmetic)] // cannot overflow
+        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
         if variant_count.is_power_of_two() { floor_log2 } else { floor_log2 + 1 }
     }
 
@@ -87,7 +87,7 @@ impl Handle {
 
         // packs the data into the lower `data_size` bits
         // and packs the discriminant right above the data
-        #[allow(clippy::integer_arithmetic)] // cannot overflow
+        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
         return discriminant << data_size | data;
     }
 
@@ -106,11 +106,11 @@ impl Handle {
         let data_size = u32::BITS.checked_sub(disc_size).unwrap();
 
         // the lower `data_size` bits of this mask are 1
-        #[allow(clippy::integer_arithmetic)] // cannot overflow
+        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
         let data_mask = 2u32.pow(data_size) - 1;
 
         // the discriminant is stored right above the lower `data_size` bits
-        #[allow(clippy::integer_arithmetic)] // cannot overflow
+        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
         let discriminant = handle >> data_size;
 
         // the data is stored in the lower `data_size` bits
diff --git a/src/tools/miri/test-cargo-miri/run-test.py b/src/tools/miri/test-cargo-miri/run-test.py
index 46b3afa70e5..9df90c725e4 100755
--- a/src/tools/miri/test-cargo-miri/run-test.py
+++ b/src/tools/miri/test-cargo-miri/run-test.py
@@ -108,8 +108,9 @@ def test_cargo_miri_run():
         env={'MIRITESTVAR': "wrongval"}, # changing the env var causes a rebuild (re-runs build.rs),
                                          # so keep it set
     )
+    # This also covers passing arguments without `--`: Cargo will forward unused positional arguments to the program.
     test("`cargo miri run` (with arguments and target)",
-        cargo_miri("run") + ["--bin", "cargo-miri-test", "--", "hello world", '"hello world"', r'he\\llo\"world'],
+        cargo_miri("run") + ["--bin", "cargo-miri-test", "hello world", '"hello world"', r'he\\llo\"world'],
         "run.args.stdout.ref", "run.args.stderr.ref",
     )
     test("`cargo miri r` (subcrate, no isolation)",
diff --git a/src/tools/miri/tests/fail/never_say_never.rs b/src/tools/miri/tests/fail/never_say_never.rs
index f6d3dc790bf..fd082e367a8 100644
--- a/src/tools/miri/tests/fail/never_say_never.rs
+++ b/src/tools/miri/tests/fail/never_say_never.rs
@@ -6,10 +6,8 @@
 
 fn main() {
     let y = &5;
-    let x: ! = unsafe {
-        *(y as *const _ as *const !) //~ ERROR: entering unreachable code
-    };
-    f(x)
+    let x: ! = unsafe { *(y as *const _ as *const !) };
+    f(x) //~ ERROR: entering unreachable code
 }
 
 fn f(x: !) -> ! {
diff --git a/src/tools/miri/tests/fail/never_say_never.stderr b/src/tools/miri/tests/fail/never_say_never.stderr
index a2a63b8baf5..9d3a8df525a 100644
--- a/src/tools/miri/tests/fail/never_say_never.stderr
+++ b/src/tools/miri/tests/fail/never_say_never.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: entering unreachable code
   --> $DIR/never_say_never.rs:LL:CC
    |
-LL |         *(y as *const _ as *const !)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code
+LL |     f(x)
+   |     ^^^^ entering unreachable code
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
index bf4204c61fd..a5a1930ed65 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
@@ -1,4 +1,4 @@
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 fn main() {
     let target = &mut 42;
diff --git a/src/tools/miri/tests/fail/uninit_buffer.rs b/src/tools/miri/tests/fail/uninit_buffer.rs
index 8a330058375..d622b2fa7d8 100644
--- a/src/tools/miri/tests/fail/uninit_buffer.rs
+++ b/src/tools/miri/tests/fail/uninit_buffer.rs
@@ -1,6 +1,6 @@
 //@error-in-other-file: memory is uninitialized at [0x4..0x10]
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 use std::alloc::{alloc, dealloc, Layout};
 use std::slice::from_raw_parts;
diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
index 443f481c087..ca825901372 100644
--- a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
+++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
@@ -1,7 +1,7 @@
 //@error-in-other-file: memory is uninitialized at [0x4..0x8]
 //@normalize-stderr-test: "a[0-9]+" -> "ALLOC"
 #![feature(strict_provenance)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 // Test printing allocations that contain single-byte provenance.
 
diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/portable-simd.rs
index 173ac654b03..ee67a65a4f9 100644
--- a/src/tools/miri/tests/pass/portable-simd.rs
+++ b/src/tools/miri/tests/pass/portable-simd.rs
@@ -2,6 +2,10 @@
 #![feature(portable_simd, platform_intrinsics)]
 use std::simd::*;
 
+extern "platform-intrinsic" {
+    pub(crate) fn simd_bitmask<T, U>(x: T) -> U;
+}
+
 fn simd_ops_f32() {
     let a = f32x4::splat(10.0);
     let b = f32x4::from_array([1.0, 2.0, 3.0, -4.0]);
@@ -208,11 +212,40 @@ fn simd_mask() {
     assert_eq!(bitmask, 0b1010001101001001);
     assert_eq!(Mask::<i64, 16>::from_bitmask(bitmask), mask);
 
+    // Also directly call intrinsic, to test both kinds of return types.
+    unsafe {
+        let bitmask1: u16 = simd_bitmask(mask.to_int());
+        let bitmask2: [u8; 2] = simd_bitmask(mask.to_int());
+        if cfg!(target_endian = "little") {
+            assert_eq!(bitmask1, 0b1010001101001001);
+            assert_eq!(bitmask2, [0b01001001, 0b10100011]);
+        } else {
+            // All the bitstrings are reversed compared to above, but the array elements are in the
+            // same order.
+            assert_eq!(bitmask1, 0b1001001011000101);
+            assert_eq!(bitmask2, [0b10010010, 0b11000101]);
+        }
+    }
+
+    // Mask less than 8 bits long, which is a special case (padding with 0s).
     let values = [false, false, false, true];
     let mask = Mask::<i64, 4>::from_array(values);
     let bitmask = mask.to_bitmask();
     assert_eq!(bitmask, 0b1000);
     assert_eq!(Mask::<i64, 4>::from_bitmask(bitmask), mask);
+
+    // Also directly call intrinsic, to test both kinds of return types.
+    unsafe {
+        let bitmask1: u8 = simd_bitmask(mask.to_int());
+        let bitmask2: [u8; 1] = simd_bitmask(mask.to_int());
+        if cfg!(target_endian = "little") {
+            assert_eq!(bitmask1, 0b1000);
+            assert_eq!(bitmask2, [0b1000]);
+        } else {
+            assert_eq!(bitmask1, 0b0001);
+            assert_eq!(bitmask2, [0b0001]);
+        }
+    }
 }
 
 fn simd_cast() {
diff --git a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
index 9f743f0b566..6e13a9ea836 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
@@ -1,7 +1,7 @@
 //@compile-flags: -Zmiri-retag-fields
 // Checks that the test does not run forever (which relies on a fast path).
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 fn main() {
     let array = [(); usize::MAX];
diff --git a/tests/assembly/option-nonzero-eq.rs b/tests/assembly/option-nonzero-eq.rs
new file mode 100644
index 00000000000..f5d88de76dd
--- /dev/null
+++ b/tests/assembly/option-nonzero-eq.rs
@@ -0,0 +1,28 @@
+// revisions: WIN LIN
+// [WIN] only-windows
+// [LIN] only-linux
+// assembly-output: emit-asm
+// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
+// only-x86_64
+// ignore-sgx
+// ignore-debug
+
+use std::cmp::Ordering;
+
+// CHECK-lABEL: ordering_eq:
+#[no_mangle]
+pub fn ordering_eq(l: Option<Ordering>, r: Option<Ordering>) -> bool {
+    // Linux (System V): first two arguments are rdi then rsi
+    // Windows: first two arguments are rcx then rdx
+    // Both use rax for the return value.
+
+    // CHECK-NOT: mov
+    // CHECK-NOT: test
+    // CHECK-NOT: cmp
+
+    // LIN: cmp dil, sil
+    // WIN: cmp cl, dl
+    // CHECK-NEXT: sete al
+    // CHECK-NEXT: ret
+    l == r
+}
diff --git a/tests/codegen/drop-in-place-noalias.rs b/tests/codegen/drop-in-place-noalias.rs
new file mode 100644
index 00000000000..725e6fc048d
--- /dev/null
+++ b/tests/codegen/drop-in-place-noalias.rs
@@ -0,0 +1,38 @@
+// compile-flags: -O -C no-prepopulate-passes
+
+// Tests that the compiler can apply `noalias` and other &mut attributes to `drop_in_place`.
+// Note that non-Unpin types should not get `noalias`, matching &mut behavior.
+
+#![crate_type="lib"]
+
+use std::marker::PhantomPinned;
+
+// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructUnpin{{.*}}({{.*\*|ptr}} noalias noundef align 4 dereferenceable(12) %{{.+}})
+
+// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructNotUnpin{{.*}}({{.*\*|ptr}} noundef nonnull align 4 %{{.+}})
+
+pub struct StructUnpin {
+    a: i32,
+    b: i32,
+    c: i32,
+}
+
+impl Drop for StructUnpin {
+    fn drop(&mut self) {}
+}
+
+pub struct StructNotUnpin {
+    a: i32,
+    b: i32,
+    c: i32,
+    p: PhantomPinned,
+}
+
+impl Drop for StructNotUnpin {
+    fn drop(&mut self) {}
+}
+
+pub unsafe fn main(x: StructUnpin, y: StructNotUnpin) {
+    drop(x);
+    drop(y);
+}
diff --git a/tests/codegen/issues/issue-111603.rs b/tests/codegen/issues/issue-111603.rs
new file mode 100644
index 00000000000..90b3c314d2f
--- /dev/null
+++ b/tests/codegen/issues/issue-111603.rs
@@ -0,0 +1,28 @@
+// compile-flags: -O
+
+#![crate_type = "lib"]
+#![feature(get_mut_unchecked, new_uninit)]
+
+use std::sync::Arc;
+
+// CHECK-LABEL: @new_uninit
+#[no_mangle]
+pub fn new_uninit(x: u64) -> Arc<[u64; 1000]> {
+    // CHECK: call alloc::sync::arcinner_layout_for_value_layout
+    // CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout
+    let mut arc = Arc::new_uninit();
+    unsafe { Arc::get_mut_unchecked(&mut arc) }.write([x; 1000]);
+    unsafe { arc.assume_init() }
+}
+
+// CHECK-LABEL: @new_uninit_slice
+#[no_mangle]
+pub fn new_uninit_slice(x: u64) -> Arc<[u64]> {
+    // CHECK: call alloc::sync::arcinner_layout_for_value_layout
+    // CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout
+    let mut arc = Arc::new_uninit_slice(1000);
+    for elem in unsafe { Arc::get_mut_unchecked(&mut arc) } {
+        elem.write(x);
+    }
+    unsafe { arc.assume_init() }
+}
diff --git a/tests/codegen/noalias-box-off.rs b/tests/codegen/noalias-box-off.rs
index afd17c7c160..c82c53b2a48 100644
--- a/tests/codegen/noalias-box-off.rs
+++ b/tests/codegen/noalias-box-off.rs
@@ -4,5 +4,8 @@
 
 // CHECK-LABEL: @box_should_not_have_noalias_if_disabled(
 // CHECK-NOT: noalias
+// CHECK-SAME: %foo)
 #[no_mangle]
-pub fn box_should_not_have_noalias_if_disabled(_b: Box<u8>) {}
+pub fn box_should_not_have_noalias_if_disabled(foo: Box<u8>) {
+    drop(foo);
+}
diff --git a/tests/codegen/option-nonzero-eq.rs b/tests/codegen/option-nonzero-eq.rs
index 835decd3e5f..a394695f3bd 100644
--- a/tests/codegen/option-nonzero-eq.rs
+++ b/tests/codegen/option-nonzero-eq.rs
@@ -7,6 +7,9 @@ use core::cmp::Ordering;
 use core::num::{NonZeroU32, NonZeroI64};
 use core::ptr::NonNull;
 
+// See also tests/assembly/option-nonzero-eq.rs, for cases with `assume`s in the
+// LLVM and thus don't optimize down clearly here, but do in assembly.
+
 // CHECK-lABEL: @non_zero_eq
 #[no_mangle]
 pub fn non_zero_eq(l: Option<NonZeroU32>, r: Option<NonZeroU32>) -> bool {
@@ -33,12 +36,3 @@ pub fn non_null_eq(l: Option<NonNull<u8>>, r: Option<NonNull<u8>>) -> bool {
     // CHECK-NEXT: ret i1
     l == r
 }
-
-// CHECK-lABEL: @ordering_eq
-#[no_mangle]
-pub fn ordering_eq(l: Option<Ordering>, r: Option<Ordering>) -> bool {
-    // CHECK: start:
-    // CHECK-NEXT: icmp eq i8
-    // CHECK-NEXT: ret i1
-    l == r
-}
diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs
index 3aa16d9f645..ebb26cd35c0 100644
--- a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs
+++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs
@@ -536,15 +536,15 @@ pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { }
 // CHECK: ![[TYPE93]] = !{i64 0, !"_ZTSFvPFu3i32S_EE"}
 // CHECK: ![[TYPE94]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_E"}
 // CHECK: ![[TYPE95]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_S0_E"}
-// CHECK: ![[TYPE96]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEEE"}
-// CHECK: ![[TYPE97]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_E"}
-// CHECK: ![[TYPE98]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_S6_E"}
-// CHECK: ![[TYPE99]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEEE"}
-// CHECK: ![[TYPE100]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_E"}
-// CHECK: ![[TYPE101]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_S6_E"}
-// CHECK: ![[TYPE102]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEEE"}
-// CHECK: ![[TYPE103]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_E"}
-// CHECK: ![[TYPE104]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIu5tupleIu3i32EES1_u6regionEES6_S6_E"}
+// CHECK: ![[TYPE96]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEEE"}
+// CHECK: ![[TYPE97]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_E"}
+// CHECK: ![[TYPE98]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_S3_E"}
+// CHECK: ![[TYPE99]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEEE"}
+// CHECK: ![[TYPE100]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_E"}
+// CHECK: ![[TYPE101]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_S3_E"}
+// CHECK: ![[TYPE102]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEEE"}
+// CHECK: ![[TYPE103]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_E"}
+// CHECK: ![[TYPE104]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_S3_E"}
 // CHECK: ![[TYPE105]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEEE"}
 // CHECK: ![[TYPE106]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_E"}
 // CHECK: ![[TYPE107]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_S2_E"}
diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs
index 18914049a10..0f79adab7bd 100644
--- a/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs
+++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs
@@ -39,6 +39,20 @@ impl<T, U> Trait3<U> for T {
     }
 }
 
+pub trait Trait4<'a, T> {
+    type Output: 'a;
+    fn qux(&self, _: &T) -> Self::Output;
+}
+
+pub struct Type4;
+
+impl<'a, T, U> Trait4<'a, U> for T {
+    type Output = &'a i32;
+    fn qux(&self, _: &U) -> Self::Output {
+        &0
+    }
+}
+
 pub fn foo1(a: &dyn Trait1) {
     a.foo();
     // CHECK-LABEL: define{{.*}}4foo1{{.*}}!type !{{[0-9]+}}
@@ -84,6 +98,23 @@ pub fn bar3() {
     // CHECK:       call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
 }
 
+pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) {
+    let b = Type4;
+    a.qux(&b);
+    // CHECK-LABEL: define{{.*}}4foo4{{.*}}!type !{{[0-9]+}}
+    // CHECK:       call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
+}
+
+pub fn bar4<'a>() {
+    let a = Type4;
+    foo4(&a);
+    let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>;
+    b.qux(&a);
+    // CHECK-LABEL: define{{.*}}4bar4{{.*}}!type !{{[0-9]+}}
+    // CHECK:       call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
+}
+
 // CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"}
 // CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE2]]"}
 // CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE3]]"}
+// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE4]]"}
diff --git a/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs
index a46f0955696..004a67e7df2 100644
--- a/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs
+++ b/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs
@@ -63,6 +63,20 @@ impl<T, U> Trait3<U> for T {
     }
 }
 
+pub trait Trait4<'a, T> {
+    type Output: 'a;
+    fn qux(&self, _: &T) -> Self::Output;
+}
+
+pub struct Type4;
+
+impl<'a, T, U> Trait4<'a, U> for T {
+    type Output = &'a i32;
+    fn qux(&self, _: &U) -> Self::Output {
+        &0
+    }
+}
+
 pub fn foo1(a: &dyn Trait1) {
     a.foo();
     // CHECK-LABEL: define{{.*}}4foo1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
@@ -108,6 +122,23 @@ pub fn bar3() {
     // CHECK:       call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type3\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ]
 }
 
+pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) {
+    let b = Type4;
+    a.qux(&b);
+    // CHECK-LABEL: define{{.*}}4foo4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
+    // CHECK:       call align 4 {{ptr|i32\*}} %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type4\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ]
+}
+
+pub fn bar4<'a>() {
+    let a = Type4;
+    foo4(&a);
+    let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>;
+    b.qux(&a);
+    // CHECK-LABEL: define{{.*}}4bar4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
+    // CHECK:       call align 4 {{ptr|i32\*}} %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type4\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ]
+}
+
 // CHECK: !{{[0-9]+}} = !{i32 [[TYPE1]]}
 // CHECK: !{{[0-9]+}} = !{i32 [[TYPE2]]}
 // CHECK: !{{[0-9]+}} = !{i32 [[TYPE3]]}
+// CHECK: !{{[0-9]+}} = !{i32 [[TYPE4]]}
diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs
new file mode 100644
index 00000000000..51334c12158
--- /dev/null
+++ b/tests/codegen/tied-features-strength.rs
@@ -0,0 +1,29 @@
+// ignore-tidy-linelength
+// revisions: ENABLE_SVE DISABLE_SVE DISABLE_NEON ENABLE_NEON
+// compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
+// needs-llvm-components: aarch64
+
+// The "+v8a" feature is matched as optional as it isn't added when we
+// are targeting older LLVM versions. Once the min supported version
+// is LLVM-14 we can remove the optional regex matching for this feature.
+
+// [ENABLE_SVE] compile-flags: -C target-feature=+sve
+// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+sve,?)|(\+neon,?))*}}" }
+
+// [DISABLE_SVE] compile-flags: -C target-feature=-sve
+// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-sve,?)|(\+neon,?))*}}" }
+
+// [DISABLE_NEON] compile-flags: -C target-feature=-neon
+// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
+
+// [ENABLE_NEON] compile-flags: -C target-feature=+neon
+// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
+
+
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub fn test() {}
diff --git a/tests/mir-opt/building/enum_cast.bar.built.after.mir b/tests/mir-opt/building/enum_cast.bar.built.after.mir
index 0746e0b498e..9f14c028465 100644
--- a/tests/mir-opt/building/enum_cast.bar.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.bar.built.after.mir
@@ -5,17 +5,16 @@ fn bar(_1: Bar) -> usize {
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
     let _2: Bar;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
     let mut _3: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
-    let mut _4: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+    let mut _4: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
     let mut _5: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
 
     bb0: {
         StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
         _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
         _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _4 = Ge(const 1_isize, _3);      // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        assume(_4);                      // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _5 = Le(const 0_isize, _3);      // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        assume(_5);                      // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _4 = _3 as u8 (IntToInt);        // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _5 = Le(_4, const 1_u8);         // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        assume(move _5);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
         _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
         StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
diff --git a/tests/mir-opt/building/enum_cast.boo.built.after.mir b/tests/mir-opt/building/enum_cast.boo.built.after.mir
index 699c876b01a..715dedcf24d 100644
--- a/tests/mir-opt/building/enum_cast.boo.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.boo.built.after.mir
@@ -5,17 +5,16 @@ fn boo(_1: Boo) -> usize {
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
     let _2: Boo;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
     let mut _3: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
-    let mut _4: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+    let mut _4: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
     let mut _5: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
 
     bb0: {
         StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
         _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
         _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _4 = Ge(const 1_u8, _3);         // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        assume(_4);                      // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _5 = Le(const 0_u8, _3);         // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        assume(_5);                      // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _4 = _3 as u8 (IntToInt);        // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _5 = Le(_4, const 1_u8);         // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        assume(move _5);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
         _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
         StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
diff --git a/tests/mir-opt/building/enum_cast.droppy.built.after.mir b/tests/mir-opt/building/enum_cast.droppy.built.after.mir
index 1112177fbbf..6c177c61eca 100644
--- a/tests/mir-opt/building/enum_cast.droppy.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.droppy.built.after.mir
@@ -6,7 +6,7 @@ fn droppy() -> () {
     let _2: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
     let _4: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
     let mut _5: isize;                   // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
-    let mut _6: bool;                    // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27
+    let mut _6: u8;                      // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27
     let mut _7: bool;                    // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27
     let _8: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
     scope 1 {
@@ -31,10 +31,9 @@ fn droppy() -> () {
         StorageLive(_4);                 // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
         _4 = move _2;                    // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
         _5 = discriminant(_4);           // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
-        _6 = Ge(const 2_isize, _5);      // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
-        assume(_6);                      // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
-        _7 = Le(const 0_isize, _5);      // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
-        assume(_7);                      // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        _6 = _5 as u8 (IntToInt);        // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        _7 = Le(_6, const 2_u8);         // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        assume(move _7);                 // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
         _3 = move _5 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
         drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
     }
diff --git a/tests/mir-opt/building/enum_cast.far.built.after.mir b/tests/mir-opt/building/enum_cast.far.built.after.mir
new file mode 100644
index 00000000000..ab8129ca01c
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.far.built.after.mir
@@ -0,0 +1,22 @@
+// MIR for `far` after built
+
+fn far(_1: Far) -> isize {
+    debug far => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
+    let mut _0: isize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
+    let _2: Far;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _3: i16;                     // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _4: u16;                     // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+    let mut _5: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _4 = _3 as u16 (IntToInt);       // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _5 = Le(_4, const 1_u16);        // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        assume(move _5);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _0 = move _3 as isize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
+        return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+    }
+}
diff --git a/tests/mir-opt/building/enum_cast.offsetty.built.after.mir b/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
new file mode 100644
index 00000000000..7b2b583f20f
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
@@ -0,0 +1,26 @@
+// MIR for `offsetty` after built
+
+fn offsetty(_1: NotStartingAtZero) -> u32 {
+    debug x => _1;                       // in scope 0 at $DIR/enum_cast.rs:+0:13: +0:14
+    let mut _0: u32;                     // return place in scope 0 at $DIR/enum_cast.rs:+0:38: +0:41
+    let _2: NotStartingAtZero;           // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+    let mut _3: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+    let mut _4: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+    let mut _5: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+    let mut _6: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+    let mut _7: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _4 = _3 as u8 (IntToInt);        // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _5 = Ge(_4, const 4_u8);         // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _6 = Le(_4, const 8_u8);         // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _7 = BitAnd(move _5, move _6);   // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        assume(move _7);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _0 = move _3 as u32 (IntToInt);  // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:12: +1:13
+        return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+    }
+}
diff --git a/tests/mir-opt/building/enum_cast.rs b/tests/mir-opt/building/enum_cast.rs
index 98fd5acfb14..431b5c708b9 100644
--- a/tests/mir-opt/building/enum_cast.rs
+++ b/tests/mir-opt/building/enum_cast.rs
@@ -1,6 +1,7 @@
 // EMIT_MIR enum_cast.foo.built.after.mir
 // EMIT_MIR enum_cast.bar.built.after.mir
 // EMIT_MIR enum_cast.boo.built.after.mir
+// EMIT_MIR enum_cast.far.built.after.mir
 
 enum Foo {
     A
@@ -15,6 +16,11 @@ enum Boo {
     A, B
 }
 
+#[repr(i16)]
+enum Far {
+    A, B
+}
+
 fn foo(foo: Foo) -> usize {
     foo as usize
 }
@@ -27,6 +33,10 @@ fn boo(boo: Boo) -> usize {
     boo as usize
 }
 
+fn far(far: Far) -> isize {
+    far as isize
+}
+
 // EMIT_MIR enum_cast.droppy.built.after.mir
 enum Droppy {
     A, B, C
@@ -46,5 +56,37 @@ fn droppy() {
     let z = Droppy::B;
 }
 
+#[repr(i16)]
+enum SignedAroundZero {
+    A = -2,
+    B = 0,
+    C = 2,
+}
+
+#[repr(u16)]
+enum UnsignedAroundZero {
+    A = 65535,
+    B = 0,
+    C = 1,
+}
+
+// EMIT_MIR enum_cast.signy.built.after.mir
+fn signy(x: SignedAroundZero) -> i16 {
+    x as i16
+}
+
+// EMIT_MIR enum_cast.unsigny.built.after.mir
+fn unsigny(x: UnsignedAroundZero) -> u16 {
+    // FIXME: This doesn't get an around-the-end range today, sadly.
+    x as u16
+}
+
+enum NotStartingAtZero { A = 4, B = 6, C = 8 }
+
+// EMIT_MIR enum_cast.offsetty.built.after.mir
+fn offsetty(x: NotStartingAtZero) -> u32 {
+    x as u32
+}
+
 fn main() {
 }
diff --git a/tests/mir-opt/building/enum_cast.signy.built.after.mir b/tests/mir-opt/building/enum_cast.signy.built.after.mir
new file mode 100644
index 00000000000..ef4fea604ec
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.signy.built.after.mir
@@ -0,0 +1,26 @@
+// MIR for `signy` after built
+
+fn signy(_1: SignedAroundZero) -> i16 {
+    debug x => _1;                       // in scope 0 at $DIR/enum_cast.rs:+0:10: +0:11
+    let mut _0: i16;                     // return place in scope 0 at $DIR/enum_cast.rs:+0:34: +0:37
+    let _2: SignedAroundZero;            // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+    let mut _3: i16;                     // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+    let mut _4: u16;                     // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+    let mut _5: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+    let mut _6: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+    let mut _7: bool;                    // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:6
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _4 = _3 as u16 (IntToInt);       // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _5 = Ge(_4, const 65534_u16);    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _6 = Le(_4, const 2_u16);        // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _7 = BitOr(move _5, move _6);    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        assume(move _7);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        _0 = move _3 as i16 (IntToInt);  // scope 0 at $DIR/enum_cast.rs:+1:5: +1:13
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:12: +1:13
+        return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
+    }
+}
diff --git a/tests/mir-opt/building/enum_cast.unsigny.built.after.mir b/tests/mir-opt/building/enum_cast.unsigny.built.after.mir
new file mode 100644
index 00000000000..7ca147b1596
--- /dev/null
+++ b/tests/mir-opt/building/enum_cast.unsigny.built.after.mir
@@ -0,0 +1,17 @@
+// MIR for `unsigny` after built
+
+fn unsigny(_1: UnsignedAroundZero) -> u16 {
+    debug x => _1;                       // in scope 0 at $DIR/enum_cast.rs:+0:12: +0:13
+    let mut _0: u16;                     // return place in scope 0 at $DIR/enum_cast.rs:+0:38: +0:41
+    let _2: UnsignedAroundZero;          // in scope 0 at $DIR/enum_cast.rs:+2:5: +2:6
+    let mut _3: u16;                     // in scope 0 at $DIR/enum_cast.rs:+2:5: +2:6
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+2:5: +2:6
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+2:5: +2:6
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+2:5: +2:13
+        _0 = move _3 as u16 (IntToInt);  // scope 0 at $DIR/enum_cast.rs:+2:5: +2:13
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+2:12: +2:13
+        return;                          // scope 0 at $DIR/enum_cast.rs:+3:2: +3:2
+    }
+}
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff
index bc41b5d0813..5258d75bdf7 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff
@@ -3,24 +3,20 @@
   
   fn unreachable_box() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:38: +3:2
-      let _2: std::boxed::Box<Never>;      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:16
+      let _1: std::boxed::Box<Never>;      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:38: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
--         _2 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
-+         _2 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+-         _1 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
++         _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: Box<Never>, val: Value(Scalar(0x00000001)) }
-          StorageLive(_3);                 // scope 1 at $DIR/transmute.rs:+2:5: +2:16
           unreachable;                     // scope 1 at $DIR/transmute.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff
index c4376e6e17a..7e57e06a5cf 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff
@@ -3,24 +3,20 @@
   
   fn unreachable_box() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:38: +3:2
-      let _2: std::boxed::Box<Never>;      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:16
+      let _1: std::boxed::Box<Never>;      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:38: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
--         _2 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
-+         _2 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+-         _1 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
++         _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: Box<Never>, val: Value(Scalar(0x0000000000000001)) }
-          StorageLive(_3);                 // scope 1 at $DIR/transmute.rs:+2:5: +2:16
           unreachable;                     // scope 1 at $DIR/transmute.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.32bit.diff
index 81b7b368993..032681f230b 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.32bit.diff
@@ -3,22 +3,19 @@
   
   fn unreachable_direct() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:39: +0:40
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:41: +3:2
-      let _2: Never;                       // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: ();                      // in scope 0 at $DIR/transmute.rs:+1:39: +1:41
-      let mut _4: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:15
+      let _1: Never;                       // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
+      let mut _2: ();                      // in scope 0 at $DIR/transmute.rs:+1:39: +1:41
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:41: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 2 at $DIR/transmute.rs:+1:39: +1:41
-          _3 = ();                         // scope 2 at $DIR/transmute.rs:+1:39: +1:41
-          _2 = move _3 as Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:29: +1:42
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 2 at $DIR/transmute.rs:+1:39: +1:41
+          _2 = ();                         // scope 2 at $DIR/transmute.rs:+1:39: +1:41
+          _1 = move _2 as Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:29: +1:42
           unreachable;                     // scope 2 at $DIR/transmute.rs:+1:29: +1:42
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff
index 81b7b368993..032681f230b 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.ConstProp.64bit.diff
@@ -3,22 +3,19 @@
   
   fn unreachable_direct() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:39: +0:40
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:41: +3:2
-      let _2: Never;                       // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: ();                      // in scope 0 at $DIR/transmute.rs:+1:39: +1:41
-      let mut _4: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:15
+      let _1: Never;                       // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
+      let mut _2: ();                      // in scope 0 at $DIR/transmute.rs:+1:39: +1:41
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:41: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 2 at $DIR/transmute.rs:+1:39: +1:41
-          _3 = ();                         // scope 2 at $DIR/transmute.rs:+1:39: +1:41
-          _2 = move _3 as Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:29: +1:42
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 2 at $DIR/transmute.rs:+1:39: +1:41
+          _2 = ();                         // scope 2 at $DIR/transmute.rs:+1:39: +1:41
+          _1 = move _2 as Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:29: +1:42
           unreachable;                     // scope 2 at $DIR/transmute.rs:+1:29: +1:42
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.32bit.diff
index 47f023cd93d..ec8a62bd62c 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.32bit.diff
@@ -3,28 +3,24 @@
   
   fn unreachable_mut() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:38: +3:2
-      let _2: &mut Never;                  // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: &mut Never;              // in scope 0 at $DIR/transmute.rs:+1:34: +1:52
-      let mut _4: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:16
+      let _1: &mut Never;                  // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
+      let mut _2: &mut Never;              // in scope 0 at $DIR/transmute.rs:+1:34: +1:52
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:38: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
--         _3 = const 1_usize as &mut Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
-+         _3 = const {0x1 as &mut Never};  // scope 2 at $DIR/transmute.rs:+1:34: +1:52
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
+-         _2 = const 1_usize as &mut Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
++         _2 = const {0x1 as &mut Never};  // scope 2 at $DIR/transmute.rs:+1:34: +1:52
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: &mut Never, val: Value(Scalar(0x00000001)) }
-          _2 = &mut (*_3);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
-          StorageDead(_3);                 // scope 0 at $DIR/transmute.rs:+1:54: +1:55
-          StorageLive(_4);                 // scope 1 at $DIR/transmute.rs:+2:5: +2:16
+          _1 = &mut (*_2);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
+          StorageDead(_2);                 // scope 0 at $DIR/transmute.rs:+1:54: +1:55
           unreachable;                     // scope 1 at $DIR/transmute.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff
index 62300d2e313..288da6e56c5 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.ConstProp.64bit.diff
@@ -3,28 +3,24 @@
   
   fn unreachable_mut() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:38: +3:2
-      let _2: &mut Never;                  // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: &mut Never;              // in scope 0 at $DIR/transmute.rs:+1:34: +1:52
-      let mut _4: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:16
+      let _1: &mut Never;                  // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
+      let mut _2: &mut Never;              // in scope 0 at $DIR/transmute.rs:+1:34: +1:52
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:38: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
--         _3 = const 1_usize as &mut Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
-+         _3 = const {0x1 as &mut Never};  // scope 2 at $DIR/transmute.rs:+1:34: +1:52
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
+-         _2 = const 1_usize as &mut Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:34: +1:52
++         _2 = const {0x1 as &mut Never};  // scope 2 at $DIR/transmute.rs:+1:34: +1:52
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: &mut Never, val: Value(Scalar(0x0000000000000001)) }
-          _2 = &mut (*_3);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
-          StorageDead(_3);                 // scope 0 at $DIR/transmute.rs:+1:54: +1:55
-          StorageLive(_4);                 // scope 1 at $DIR/transmute.rs:+2:5: +2:16
+          _1 = &mut (*_2);                 // scope 0 at $DIR/transmute.rs:+1:34: +1:52
+          StorageDead(_2);                 // scope 0 at $DIR/transmute.rs:+1:54: +1:55
           unreachable;                     // scope 1 at $DIR/transmute.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.32bit.diff
index 8578f898a7e..dcca0fca619 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.32bit.diff
@@ -3,24 +3,20 @@
   
   fn unreachable_ref() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:38: +3:2
-      let _2: &Never;                      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:16
+      let _1: &Never;                      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:38: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
--         _2 = const 1_usize as &Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:30: +1:48
-+         _2 = const {0x1 as &Never};      // scope 2 at $DIR/transmute.rs:+1:30: +1:48
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+-         _1 = const 1_usize as &Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:30: +1:48
++         _1 = const {0x1 as &Never};      // scope 2 at $DIR/transmute.rs:+1:30: +1:48
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: &Never, val: Value(Scalar(0x00000001)) }
-          StorageLive(_3);                 // scope 1 at $DIR/transmute.rs:+2:5: +2:16
           unreachable;                     // scope 1 at $DIR/transmute.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff
index 8b11cea9365..3a0b967e66f 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.ConstProp.64bit.diff
@@ -3,24 +3,20 @@
   
   fn unreachable_ref() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/transmute.rs:+0:36: +0:37
-      let mut _1: !;                       // in scope 0 at $DIR/transmute.rs:+0:38: +3:2
-      let _2: &Never;                      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
-      let mut _3: !;                       // in scope 0 at $DIR/transmute.rs:+2:5: +2:16
+      let _1: &Never;                      // in scope 0 at $DIR/transmute.rs:+1:9: +1:10
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/transmute.rs:+1:9: +1:10
       }
       scope 2 {
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+0:38: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
--         _2 = const 1_usize as &Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:30: +1:48
-+         _2 = const {0x1 as &Never};      // scope 2 at $DIR/transmute.rs:+1:30: +1:48
+          StorageLive(_1);                 // scope 0 at $DIR/transmute.rs:+1:9: +1:10
+-         _1 = const 1_usize as &Never (Transmute); // scope 2 at $DIR/transmute.rs:+1:30: +1:48
++         _1 = const {0x1 as &Never};      // scope 2 at $DIR/transmute.rs:+1:30: +1:48
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: &Never, val: Value(Scalar(0x0000000000000001)) }
-          StorageLive(_3);                 // scope 1 at $DIR/transmute.rs:+2:5: +2:16
           unreachable;                     // scope 1 at $DIR/transmute.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/issue_72181_1.f.built.after.mir b/tests/mir-opt/issue_72181_1.f.built.after.mir
index 4086da52011..25f47225113 100644
--- a/tests/mir-opt/issue_72181_1.f.built.after.mir
+++ b/tests/mir-opt/issue_72181_1.f.built.after.mir
@@ -3,27 +3,13 @@
 fn f(_1: Void) -> ! {
     debug v => _1;                       // in scope 0 at $DIR/issue_72181_1.rs:+0:6: +0:7
     let mut _0: !;                       // return place in scope 0 at $DIR/issue_72181_1.rs:+0:18: +0:19
-    let mut _2: !;                       // in scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2
-    let mut _3: !;                       // in scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15
 
     bb0: {
-        StorageLive(_2);                 // scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2
-        StorageLive(_3);                 // scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15
         FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue_72181_1.rs:+1:11: +1:12
         unreachable;                     // scope 0 at $DIR/issue_72181_1.rs:+1:11: +1:12
     }
 
     bb1: {
-        unreachable;                     // scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15
-    }
-
-    bb2: {
-        StorageDead(_3);                 // scope 0 at $DIR/issue_72181_1.rs:+1:14: +1:15
-        unreachable;                     // scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2
-    }
-
-    bb3: {
-        StorageDead(_2);                 // scope 0 at $DIR/issue_72181_1.rs:+2:1: +2:2
         return;                          // scope 0 at $DIR/issue_72181_1.rs:+2:2: +2:2
     }
 }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff
index 8735a750060..aa5d9619d10 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.diff
@@ -3,26 +3,22 @@
   
   fn transmute_to_box_uninhabited() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:49: +0:50
-      let mut _1: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+0:51: +3:2
-      let _2: std::boxed::Box<Never>;      // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
-      let mut _3: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:16
+      let _1: std::boxed::Box<Never>;      // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+0:51: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
--         _2 = transmute::<usize, Box<Never>>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
+          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
+-         _1 = transmute::<usize, Box<Never>>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
 -                                          // mir::Constant
 -                                          // + span: $DIR/lower_intrinsics.rs:70:25: 70:44
 -                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> Box<Never> {transmute::<usize, Box<Never>>}, val: Value(<ZST>) }
-+         _2 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
++         _1 = const 1_usize as std::boxed::Box<Never> (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
 +         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
       }
   
       bb1: {
-          StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:5: +2:16
           unreachable;                     // scope 1 at $DIR/lower_intrinsics.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff
index a772132770c..5fafd45fe85 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.diff
@@ -3,26 +3,22 @@
   
   fn transmute_to_mut_uninhabited() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:49: +0:50
-      let mut _1: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+0:51: +3:2
-      let _2: &mut Never;                  // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
-      let mut _3: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:16
+      let _1: &mut Never;                  // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+0:51: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
--         _2 = transmute::<usize, &mut Never>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
+          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
+-         _1 = transmute::<usize, &mut Never>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
 -                                          // mir::Constant
 -                                          // + span: $DIR/lower_intrinsics.rs:64:25: 64:44
 -                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> &mut Never {transmute::<usize, &mut Never>}, val: Value(<ZST>) }
-+         _2 = const 1_usize as &mut Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
++         _1 = const 1_usize as &mut Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
 +         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:+1:25: +1:52
       }
   
       bb1: {
-          StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:5: +2:16
           unreachable;                     // scope 1 at $DIR/lower_intrinsics.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff
index c4d53d4e8c7..08dead13211 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.diff
@@ -3,26 +3,22 @@
   
   fn transmute_to_ref_uninhabited() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:49: +0:50
-      let mut _1: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+0:51: +3:2
-      let _2: &Never;                      // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
-      let mut _3: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:16
+      let _1: &Never;                      // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
       scope 1 {
-          debug x => _2;                   // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10
+          debug x => _1;                   // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:10
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+0:51: +3:2
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
--         _2 = transmute::<usize, &Never>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48
+          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:10
+-         _1 = transmute::<usize, &Never>(const 1_usize) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48
 -                                          // mir::Constant
 -                                          // + span: $DIR/lower_intrinsics.rs:58:21: 58:40
 -                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize) -> &Never {transmute::<usize, &Never>}, val: Value(<ZST>) }
-+         _2 = const 1_usize as &Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48
++         _1 = const 1_usize as &Never (Transmute); // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48
 +         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:+1:21: +1:48
       }
   
       bb1: {
-          StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:5: +2:16
           unreachable;                     // scope 1 at $DIR/lower_intrinsics.rs:+2:11: +2:13
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
index c0cc698c481..28e45909c33 100644
--- a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
+++ b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
@@ -3,16 +3,15 @@
   
   fn unreachable() -> ! {
       let mut _0: !;                       // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:25: +0:26
-      let mut _1: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+0:27: +2:2
-      let _2: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45
-      let mut _3: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+      let _1: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+      let mut _2: !;                       // in scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:45
       scope 1 {
       }
   
       bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:47
-          StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
--         _3 = std::intrinsics::unreachable() -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+          StorageLive(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:47
+          StorageLive(_2);                 // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
+-         _2 = std::intrinsics::unreachable() -> unwind unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
 -                                          // mir::Constant
 -                                          // + span: $DIR/lower_intrinsics.rs:31:14: 31:43
 -                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(<ZST>) }
diff --git a/tests/run-make/issue-83045/Makefile b/tests/run-make/issue-83045/Makefile
index 7053da00f6b..b76e184b610 100644
--- a/tests/run-make/issue-83045/Makefile
+++ b/tests/run-make/issue-83045/Makefile
@@ -29,5 +29,5 @@ all:
 				  --crate-type=rlib \
 				  --edition=2018 \
 				  c.rs 2>&1 | tee $(TMPDIR)/output.txt || exit 0
-	$(CGREP) E0519 < $(TMPDIR)/output.txt
+	$(CGREP) E0463 < $(TMPDIR)/output.txt
 	$(CGREP) -v "internal compiler error" < $(TMPDIR)/output.txt
diff --git a/tests/rustdoc-gui/jump-to-def-background.goml b/tests/rustdoc-gui/jump-to-def-background.goml
index 3a7d48284d7..6adc36b0edb 100644
--- a/tests/rustdoc-gui/jump-to-def-background.goml
+++ b/tests/rustdoc-gui/jump-to-def-background.goml
@@ -17,6 +17,6 @@ define-function: (
     },
 )
 
-call-function: ("check-background-color", ("ayu", "rgb(51, 51, 51)"))
-call-function: ("check-background-color", ("dark", "rgb(51, 51, 51)"))
-call-function: ("check-background-color", ("light", "rgb(238, 238, 238)"))
+call-function: ("check-background-color", ("ayu", "#333"))
+call-function: ("check-background-color", ("dark", "#333"))
+call-function: ("check-background-color", ("light", "#eee"))
diff --git a/tests/rustdoc-gui/scrape-examples-color.goml b/tests/rustdoc-gui/scrape-examples-color.goml
index 81cf6fee9d4..0052d18dc56 100644
--- a/tests/rustdoc-gui/scrape-examples-color.goml
+++ b/tests/rustdoc-gui/scrape-examples-color.goml
@@ -81,16 +81,16 @@ define-function: (
 
 call-function: ("check-background", {
     "theme": "ayu",
-    "background_color_start": "rgb(15, 20, 25)",
+    "background_color_start": "rgba(15, 20, 25, 1)",
     "background_color_end": "rgba(15, 20, 25, 0)",
 })
 call-function: ("check-background", {
     "theme": "dark",
-    "background_color_start": "rgb(53, 53, 53)",
+    "background_color_start": "rgba(53, 53, 53, 1)",
     "background_color_end": "rgba(53, 53, 53, 0)",
 })
 call-function: ("check-background", {
     "theme": "light",
-    "background_color_start": "rgb(255, 255, 255)",
+    "background_color_start": "rgba(255, 255, 255, 1)",
     "background_color_end": "rgba(255, 255, 255, 0)",
 })
diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml
index bf1fe7be910..c37d969324c 100644
--- a/tests/rustdoc-gui/settings.goml
+++ b/tests/rustdoc-gui/settings.goml
@@ -301,7 +301,7 @@ wait-for-css: ("#help-button .popover", {"display": "block"})
 // Now we go to the settings page to check that the CSS is loaded as expected.
 go-to: "file://" + |DOC_PATH| + "/settings.html"
 wait-for: "#settings"
-assert-css: (".setting-line", {"position": "relative"})
+assert-css: (".setting-radio", {"cursor": "pointer"})
 
 assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS)
 compare-elements-position: (".sub form", "#settings", ("x"))
@@ -322,4 +322,4 @@ reload:
 set-window-size: (300, 1000)
 click: "#settings-menu"
 wait-for: "#settings"
-assert-css: (".setting-line", {"position": "relative"})
+assert-css: (".setting-radio", {"cursor": "pointer"})
diff --git a/tests/rustdoc-json/assoc_items.rs b/tests/rustdoc-json/assoc_items.rs
index 6d7f6bb969f..05c2d428393 100644
--- a/tests/rustdoc-json/assoc_items.rs
+++ b/tests/rustdoc-json/assoc_items.rs
@@ -3,35 +3,32 @@
 pub struct Simple;
 
 impl Simple {
-    // @is "$.index[*][?(@.name=='CONSTANT')].kind" \"assoc_const\"
+    // @has "$.index[*][?(@.name=='CONSTANT')].inner.assoc_const"
     pub const CONSTANT: usize = 0;
 }
 
 pub trait EasyToImpl {
-    // @is "$.index[*][?(@.docs=='ToDeclare trait')].kind" \"assoc_type\"
-    // @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.default" null
-    // @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.bounds" []
+    // @has "$.index[*][?(@.docs=='ToDeclare trait')].inner.assoc_type"
+    // @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.assoc_type.default" null
+    // @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.assoc_type.bounds" []
     /// ToDeclare trait
     type ToDeclare;
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].kind" \"assoc_const\"
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.default" null
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.type.kind" '"primitive"'
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.type.inner" '"usize"'
+    // @has "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const"
+    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const.default" null
+    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const.type.primitive" '"usize"'
     /// AN_ATTRIBUTE trait
     const AN_ATTRIBUTE: usize;
 }
 
 impl EasyToImpl for Simple {
-    // @is "$.index[*][?(@.docs=='ToDeclare impl')].kind" '"assoc_type"'
-    // @is "$.index[*][?(@.docs=='ToDeclare impl')].inner.default.kind" \"primitive\"
-    // @is "$.index[*][?(@.docs=='ToDeclare impl')].inner.default.inner" \"usize\"
+    // @has "$.index[*][?(@.docs=='ToDeclare impl')].inner.assoc_type"
+    // @is "$.index[*][?(@.docs=='ToDeclare impl')].inner.assoc_type.default.primitive" \"usize\"
     /// ToDeclare impl
     type ToDeclare = usize;
 
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].kind" '"assoc_const"'
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.type.kind" \"primitive\"
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.type.inner" \"usize\"
-    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.default" \"12\"
+    // @has "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const"
+    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const.type.primitive" \"usize\"
+    // @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const.default" \"12\"
     /// AN_ATTRIBUTE impl
     const AN_ATTRIBUTE: usize = 12;
 }
diff --git a/tests/rustdoc-json/blanket_impls.rs b/tests/rustdoc-json/blanket_impls.rs
index c5cc87ca1eb..a2a5c4a7146 100644
--- a/tests/rustdoc-json/blanket_impls.rs
+++ b/tests/rustdoc-json/blanket_impls.rs
@@ -2,7 +2,7 @@
 
 #![no_std]
 
-// @has "$.index[*][?(@.name=='Error')].kind" \"assoc_type\"
-// @has "$.index[*][?(@.name=='Error')].inner.default.kind" \"resolved_path\"
-// @has "$.index[*][?(@.name=='Error')].inner.default.inner.name" \"Infallible\"
+// @has "$.index[*][?(@.name=='Error')].inner.assoc_type"
+// @has "$.index[*][?(@.name=='Error')].inner.assoc_type.default.resolved_path"
+// @has "$.index[*][?(@.name=='Error')].inner.assoc_type.default.resolved_path.name" \"Infallible\"
 pub struct ForBlanketTryFromImpl;
diff --git a/tests/rustdoc-json/enums/discriminant/basic.rs b/tests/rustdoc-json/enums/discriminant/basic.rs
index 06906df3b2c..dbfc5c2cf6b 100644
--- a/tests/rustdoc-json/enums/discriminant/basic.rs
+++ b/tests/rustdoc-json/enums/discriminant/basic.rs
@@ -1,12 +1,12 @@
 #[repr(i8)]
 pub enum Ordering {
-    // @is "$.index[*][?(@.name=='Less')].inner.discriminant.expr" '"-1"'
-    // @is "$.index[*][?(@.name=='Less')].inner.discriminant.value" '"-1"'
+    // @is "$.index[*][?(@.name=='Less')].inner.variant.discriminant.expr" '"-1"'
+    // @is "$.index[*][?(@.name=='Less')].inner.variant.discriminant.value" '"-1"'
     Less = -1,
-    // @is "$.index[*][?(@.name=='Equal')].inner.discriminant.expr" '"0"'
-    // @is "$.index[*][?(@.name=='Equal')].inner.discriminant.value" '"0"'
+    // @is "$.index[*][?(@.name=='Equal')].inner.variant.discriminant.expr" '"0"'
+    // @is "$.index[*][?(@.name=='Equal')].inner.variant.discriminant.value" '"0"'
     Equal = 0,
-    // @is "$.index[*][?(@.name=='Greater')].inner.discriminant.expr" '"1"'
-    // @is "$.index[*][?(@.name=='Greater')].inner.discriminant.value" '"1"'
+    // @is "$.index[*][?(@.name=='Greater')].inner.variant.discriminant.expr" '"1"'
+    // @is "$.index[*][?(@.name=='Greater')].inner.variant.discriminant.value" '"1"'
     Greater = 1,
 }
diff --git a/tests/rustdoc-json/enums/discriminant/expr.rs b/tests/rustdoc-json/enums/discriminant/expr.rs
index e639965e79b..ddcad58a550 100644
--- a/tests/rustdoc-json/enums/discriminant/expr.rs
+++ b/tests/rustdoc-json/enums/discriminant/expr.rs
@@ -1,30 +1,30 @@
 pub enum Foo {
-    // @is "$.index[*][?(@.name=='Addition')].inner.discriminant.value" '"0"'
-    // @is "$.index[*][?(@.name=='Addition')].inner.discriminant.expr" '"{ _ }"'
+    // @is "$.index[*][?(@.name=='Addition')].inner.variant.discriminant.value" '"0"'
+    // @is "$.index[*][?(@.name=='Addition')].inner.variant.discriminant.expr" '"{ _ }"'
     Addition = 0 + 0,
-    // @is "$.index[*][?(@.name=='Bin')].inner.discriminant.value" '"1"'
-    // @is "$.index[*][?(@.name=='Bin')].inner.discriminant.expr" '"0b1"'
+    // @is "$.index[*][?(@.name=='Bin')].inner.variant.discriminant.value" '"1"'
+    // @is "$.index[*][?(@.name=='Bin')].inner.variant.discriminant.expr" '"0b1"'
     Bin = 0b1,
-    // @is "$.index[*][?(@.name=='Oct')].inner.discriminant.value" '"2"'
-    // @is "$.index[*][?(@.name=='Oct')].inner.discriminant.expr" '"0o2"'
+    // @is "$.index[*][?(@.name=='Oct')].inner.variant.discriminant.value" '"2"'
+    // @is "$.index[*][?(@.name=='Oct')].inner.variant.discriminant.expr" '"0o2"'
     Oct = 0o2,
-    // @is "$.index[*][?(@.name=='PubConst')].inner.discriminant.value" '"3"'
-    // @is "$.index[*][?(@.name=='PubConst')].inner.discriminant.expr" '"THREE"'
+    // @is "$.index[*][?(@.name=='PubConst')].inner.variant.discriminant.value" '"3"'
+    // @is "$.index[*][?(@.name=='PubConst')].inner.variant.discriminant.expr" '"THREE"'
     PubConst = THREE,
-    // @is "$.index[*][?(@.name=='Hex')].inner.discriminant.value" '"4"'
-    // @is "$.index[*][?(@.name=='Hex')].inner.discriminant.expr" '"0x4"'
+    // @is "$.index[*][?(@.name=='Hex')].inner.variant.discriminant.value" '"4"'
+    // @is "$.index[*][?(@.name=='Hex')].inner.variant.discriminant.expr" '"0x4"'
     Hex = 0x4,
-    // @is "$.index[*][?(@.name=='Cast')].inner.discriminant.value" '"5"'
-    // @is "$.index[*][?(@.name=='Cast')].inner.discriminant.expr" '"{ _ }"'
+    // @is "$.index[*][?(@.name=='Cast')].inner.variant.discriminant.value" '"5"'
+    // @is "$.index[*][?(@.name=='Cast')].inner.variant.discriminant.expr" '"{ _ }"'
     Cast = 5 as isize,
-    // @is "$.index[*][?(@.name=='PubCall')].inner.discriminant.value" '"6"'
-    // @is "$.index[*][?(@.name=='PubCall')].inner.discriminant.expr" '"{ _ }"'
+    // @is "$.index[*][?(@.name=='PubCall')].inner.variant.discriminant.value" '"6"'
+    // @is "$.index[*][?(@.name=='PubCall')].inner.variant.discriminant.expr" '"{ _ }"'
     PubCall = six(),
-    // @is "$.index[*][?(@.name=='PrivCall')].inner.discriminant.value" '"7"'
-    // @is "$.index[*][?(@.name=='PrivCall')].inner.discriminant.expr" '"{ _ }"'
+    // @is "$.index[*][?(@.name=='PrivCall')].inner.variant.discriminant.value" '"7"'
+    // @is "$.index[*][?(@.name=='PrivCall')].inner.variant.discriminant.expr" '"{ _ }"'
     PrivCall = seven(),
-    // @is "$.index[*][?(@.name=='PrivConst')].inner.discriminant.value" '"8"'
-    // @is "$.index[*][?(@.name=='PrivConst')].inner.discriminant.expr" '"EIGHT"'
+    // @is "$.index[*][?(@.name=='PrivConst')].inner.variant.discriminant.value" '"8"'
+    // @is "$.index[*][?(@.name=='PrivConst')].inner.variant.discriminant.expr" '"EIGHT"'
     PrivConst = EIGHT,
 }
 
diff --git a/tests/rustdoc-json/enums/discriminant/limits.rs b/tests/rustdoc-json/enums/discriminant/limits.rs
index e56d5594f2f..47fb7040896 100644
--- a/tests/rustdoc-json/enums/discriminant/limits.rs
+++ b/tests/rustdoc-json/enums/discriminant/limits.rs
@@ -4,40 +4,40 @@
 
 #[repr(u64)]
 pub enum U64 {
-    // @is "$.index[*][?(@.name=='U64Min')].inner.discriminant.value" '"0"'
-    // @is "$.index[*][?(@.name=='U64Min')].inner.discriminant.expr" '"u64::MIN"'
+    // @is "$.index[*][?(@.name=='U64Min')].inner.variant.discriminant.value" '"0"'
+    // @is "$.index[*][?(@.name=='U64Min')].inner.variant.discriminant.expr" '"u64::MIN"'
     U64Min = u64::MIN,
-    // @is "$.index[*][?(@.name=='U64Max')].inner.discriminant.value" '"18446744073709551615"'
-    // @is "$.index[*][?(@.name=='U64Max')].inner.discriminant.expr" '"u64::MAX"'
+    // @is "$.index[*][?(@.name=='U64Max')].inner.variant.discriminant.value" '"18446744073709551615"'
+    // @is "$.index[*][?(@.name=='U64Max')].inner.variant.discriminant.expr" '"u64::MAX"'
     U64Max = u64::MAX,
 }
 
 #[repr(i64)]
 pub enum I64 {
-    // @is "$.index[*][?(@.name=='I64Min')].inner.discriminant.value" '"-9223372036854775808"'
-    // @is "$.index[*][?(@.name=='I64Min')].inner.discriminant.expr" '"i64::MIN"'
+    // @is "$.index[*][?(@.name=='I64Min')].inner.variant.discriminant.value" '"-9223372036854775808"'
+    // @is "$.index[*][?(@.name=='I64Min')].inner.variant.discriminant.expr" '"i64::MIN"'
     I64Min = i64::MIN,
-    // @is "$.index[*][?(@.name=='I64Max')].inner.discriminant.value" '"9223372036854775807"'
-    // @is "$.index[*][?(@.name=='I64Max')].inner.discriminant.expr" '"i64::MAX"'
+    // @is "$.index[*][?(@.name=='I64Max')].inner.variant.discriminant.value" '"9223372036854775807"'
+    // @is "$.index[*][?(@.name=='I64Max')].inner.variant.discriminant.expr" '"i64::MAX"'
     I64Max = i64::MAX,
 }
 
 #[repr(u128)]
 pub enum U128 {
-    // @is "$.index[*][?(@.name=='U128Min')].inner.discriminant.value" '"0"'
-    // @is "$.index[*][?(@.name=='U128Min')].inner.discriminant.expr" '"u128::MIN"'
+    // @is "$.index[*][?(@.name=='U128Min')].inner.variant.discriminant.value" '"0"'
+    // @is "$.index[*][?(@.name=='U128Min')].inner.variant.discriminant.expr" '"u128::MIN"'
     U128Min = u128::MIN,
-    // @is "$.index[*][?(@.name=='U128Max')].inner.discriminant.value" '"340282366920938463463374607431768211455"'
-    // @is "$.index[*][?(@.name=='U128Max')].inner.discriminant.expr" '"u128::MAX"'
+    // @is "$.index[*][?(@.name=='U128Max')].inner.variant.discriminant.value" '"340282366920938463463374607431768211455"'
+    // @is "$.index[*][?(@.name=='U128Max')].inner.variant.discriminant.expr" '"u128::MAX"'
     U128Max = u128::MAX,
 }
 
 #[repr(i128)]
 pub enum I128 {
-    // @is "$.index[*][?(@.name=='I128Min')].inner.discriminant.value" '"-170141183460469231731687303715884105728"'
-    // @is "$.index[*][?(@.name=='I128Min')].inner.discriminant.expr" '"i128::MIN"'
+    // @is "$.index[*][?(@.name=='I128Min')].inner.variant.discriminant.value" '"-170141183460469231731687303715884105728"'
+    // @is "$.index[*][?(@.name=='I128Min')].inner.variant.discriminant.expr" '"i128::MIN"'
     I128Min = i128::MIN,
-    // @is "$.index[*][?(@.name=='I128Max')].inner.discriminant.value" '"170141183460469231731687303715884105727"'
-    // @is "$.index[*][?(@.name=='I128Max')].inner.discriminant.expr" '"i128::MAX"'
+    // @is "$.index[*][?(@.name=='I128Max')].inner.variant.discriminant.value" '"170141183460469231731687303715884105727"'
+    // @is "$.index[*][?(@.name=='I128Max')].inner.variant.discriminant.expr" '"i128::MAX"'
     I128Max = i128::MAX,
 }
diff --git a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
index 6889b305ffb..9c3db81c663 100644
--- a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
+++ b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
@@ -1,15 +1,17 @@
+// ignore-tidy-linelength
+
 #[repr(u32)]
 pub enum Foo {
-    // @is "$.index[*][?(@.name=='Basic')].inner.discriminant.value" '"0"'
-    // @is "$.index[*][?(@.name=='Basic')].inner.discriminant.expr" '"0"'
+    // @is "$.index[*][?(@.name=='Basic')].inner.variant.discriminant.value" '"0"'
+    // @is "$.index[*][?(@.name=='Basic')].inner.variant.discriminant.expr" '"0"'
     Basic = 0,
-    // @is "$.index[*][?(@.name=='Suffix')].inner.discriminant.value" '"10"'
-    // @is "$.index[*][?(@.name=='Suffix')].inner.discriminant.expr" '"10u32"'
+    // @is "$.index[*][?(@.name=='Suffix')].inner.variant.discriminant.value" '"10"'
+    // @is "$.index[*][?(@.name=='Suffix')].inner.variant.discriminant.expr" '"10u32"'
     Suffix = 10u32,
-    // @is "$.index[*][?(@.name=='Underscore')].inner.discriminant.value" '"100"'
-    // @is "$.index[*][?(@.name=='Underscore')].inner.discriminant.expr" '"1_0_0"'
+    // @is "$.index[*][?(@.name=='Underscore')].inner.variant.discriminant.value" '"100"'
+    // @is "$.index[*][?(@.name=='Underscore')].inner.variant.discriminant.expr" '"1_0_0"'
     Underscore = 1_0_0,
-    // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.discriminant.value" '"1000"'
-    // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.discriminant.expr" '"1_0_0_0u32"'
+    // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant.discriminant.value" '"1000"'
+    // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant.discriminant.expr" '"1_0_0_0u32"'
     SuffixUnderscore = 1_0_0_0u32,
 }
diff --git a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
index 6a4f54de617..38ba1caf140 100644
--- a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
+++ b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
@@ -1,10 +1,12 @@
+// ignore-tidy-linelength
+
 pub enum Foo {
-    // @is "$.index[*][?(@.name=='Has')].inner.discriminant" '{"expr":"0", "value":"0"}'
+    // @is "$.index[*][?(@.name=='Has')].inner.variant.discriminant" '{"expr":"0", "value":"0"}'
     Has = 0,
-    // @is "$.index[*][?(@.name=='Doesnt')].inner.discriminant" null
+    // @is "$.index[*][?(@.name=='Doesnt')].inner.variant.discriminant" null
     Doesnt,
-    // @is "$.index[*][?(@.name=='AlsoDoesnt')].inner.discriminant" null
+    // @is "$.index[*][?(@.name=='AlsoDoesnt')].inner.variant.discriminant" null
     AlsoDoesnt,
-    // @is "$.index[*][?(@.name=='AlsoHas')].inner.discriminant" '{"expr":"44", "value":"44"}'
+    // @is "$.index[*][?(@.name=='AlsoHas')].inner.variant.discriminant" '{"expr":"44", "value":"44"}'
     AlsoHas = 44,
 }
diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs
index e91a632a3b3..c4b087c3635 100644
--- a/tests/rustdoc-json/enums/discriminant/struct.rs
+++ b/tests/rustdoc-json/enums/discriminant/struct.rs
@@ -3,13 +3,13 @@
 #[repr(i32)]
 // @is "$.index[*][?(@.name=='Foo')].attrs" '["#[repr(i32)]"]'
 pub enum Foo {
-    // @is    "$.index[*][?(@.name=='Struct')].inner.discriminant" null
-    // @count "$.index[*][?(@.name=='Struct')].inner.kind.struct.fields[*]" 0
+    // @is    "$.index[*][?(@.name=='Struct')].inner.variant.discriminant" null
+    // @count "$.index[*][?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0
     Struct {},
-    // @is    "$.index[*][?(@.name=='StructWithDiscr')].inner.discriminant" '{"expr": "42", "value": "42"}'
-    // @count "$.index[*][?(@.name=='StructWithDiscr')].inner.kind.struct.fields[*]" 1
+    // @is    "$.index[*][?(@.name=='StructWithDiscr')].inner.variant.discriminant" '{"expr": "42", "value": "42"}'
+    // @count "$.index[*][?(@.name=='StructWithDiscr')].inner.variant.kind.struct.fields[*]" 1
     StructWithDiscr { x: i32 } = 42,
-    // @is    "$.index[*][?(@.name=='StructWithHexDiscr')].inner.discriminant"  '{"expr": "0x42", "value": "66"}'
-    // @count "$.index[*][?(@.name=='StructWithHexDiscr')].inner.kind.struct.fields[*]" 2
+    // @is    "$.index[*][?(@.name=='StructWithHexDiscr')].inner.variant.discriminant"  '{"expr": "0x42", "value": "66"}'
+    // @count "$.index[*][?(@.name=='StructWithHexDiscr')].inner.variant.kind.struct.fields[*]" 2
     StructWithHexDiscr { x: i32, y: bool } = 0x42,
 }
diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs
index b94d5739eab..7da82ec8ea4 100644
--- a/tests/rustdoc-json/enums/discriminant/tuple.rs
+++ b/tests/rustdoc-json/enums/discriminant/tuple.rs
@@ -3,13 +3,13 @@
 #[repr(u32)]
 // @is "$.index[*][?(@.name=='Foo')].attrs" '["#[repr(u32)]"]'
 pub enum Foo {
-    // @is    "$.index[*][?(@.name=='Tuple')].inner.discriminant" null
-    // @count "$.index[*][?(@.name=='Tuple')].inner.kind.tuple[*]" 0
+    // @is    "$.index[*][?(@.name=='Tuple')].inner.variant.discriminant" null
+    // @count "$.index[*][?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0
     Tuple(),
-    // @is    "$.index[*][?(@.name=='TupleWithDiscr')].inner.discriminant" '{"expr": "1", "value": "1"}'
-    // @count "$.index[*][?(@.name=='TupleWithDiscr')].inner.kind.tuple[*]" 1
+    // @is    "$.index[*][?(@.name=='TupleWithDiscr')].inner.variant.discriminant" '{"expr": "1", "value": "1"}'
+    // @count "$.index[*][?(@.name=='TupleWithDiscr')].inner.variant.kind.tuple[*]" 1
     TupleWithDiscr(i32) = 1,
-    // @is    "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.discriminant" '{"expr": "0b10", "value": "2"}'
-    // @count "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.kind.tuple[*]" 2
+    // @is    "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.variant.discriminant" '{"expr": "0b10", "value": "2"}'
+    // @count "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.variant.kind.tuple[*]" 2
     TupleWithBinDiscr(i32, i32) = 0b10,
 }
diff --git a/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs b/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs
index 470b195a292..b00156124fc 100644
--- a/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs
+++ b/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs
@@ -5,7 +5,7 @@
 extern crate color;
 use color::Color::Red;
 
-// @set red = "$.index[*][?(@.inner.is_crate == true)].links.Red"
+// @set red = "$.index[*][?(@.inner.module.is_crate)].links.Red"
 
 // @!has "$.index[*][?(@.name == 'Red')]"
 // @!has "$.index[*][?(@.name == 'Color')]"
diff --git a/tests/rustdoc-json/enums/field_hidden.rs b/tests/rustdoc-json/enums/field_hidden.rs
index 78a05431472..5c0d0ffd3df 100644
--- a/tests/rustdoc-json/enums/field_hidden.rs
+++ b/tests/rustdoc-json/enums/field_hidden.rs
@@ -5,8 +5,8 @@
 
 // @has "$.index[*][?(@.name=='ParseError')]"
 // @has "$.index[*][?(@.name=='UnexpectedEndTag')]"
-// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.kind.tuple" [null]
-// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.discriminant" null
+// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant.kind.tuple" [null]
+// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant.discriminant" null
 
 pub enum ParseError {
     UnexpectedEndTag(#[doc(hidden)] u32),
diff --git a/tests/rustdoc-json/enums/kind.rs b/tests/rustdoc-json/enums/kind.rs
index 1787a859c8b..e283c074006 100644
--- a/tests/rustdoc-json/enums/kind.rs
+++ b/tests/rustdoc-json/enums/kind.rs
@@ -5,28 +5,28 @@
 
 pub enum Foo {
     // @set Unit = "$.index[*][?(@.name=='Unit')].id"
-    // @is "$.index[*][?(@.name=='Unit')].inner.kind" '"plain"'
+    // @is "$.index[*][?(@.name=='Unit')].inner.variant.kind" '"plain"'
     Unit,
     // @set Named = "$.index[*][?(@.name=='Named')].id"
-    // @is "$.index[*][?(@.name=='Named')].inner.kind.struct" '{"fields": [], "fields_stripped": false}'
+    // @is "$.index[*][?(@.name=='Named')].inner.variant.kind.struct" '{"fields": [], "fields_stripped": false}'
     Named {},
     // @set Tuple = "$.index[*][?(@.name=='Tuple')].id"
-    // @is "$.index[*][?(@.name=='Tuple')].inner.kind.tuple" []
+    // @is "$.index[*][?(@.name=='Tuple')].inner.variant.kind.tuple" []
     Tuple(),
     // @set NamedField = "$.index[*][?(@.name=='NamedField')].id"
-    // @set x = "$.index[*][?(@.name=='x' && @.kind=='struct_field')].id"
-    // @is "$.index[*][?(@.name=='NamedField')].inner.kind.struct.fields[*]" $x
-    // @is "$.index[*][?(@.name=='NamedField')].inner.kind.struct.fields_stripped" false
+    // @set x = "$.index[*][?(@.name=='x' && @.inner.struct_field)].id"
+    // @is "$.index[*][?(@.name=='NamedField')].inner.variant.kind.struct.fields[*]" $x
+    // @is "$.index[*][?(@.name=='NamedField')].inner.variant.kind.struct.fields_stripped" false
     NamedField { x: i32 },
     // @set TupleField = "$.index[*][?(@.name=='TupleField')].id"
-    // @set tup_field = "$.index[*][?(@.name=='0' && @.kind=='struct_field')].id"
-    // @is "$.index[*][?(@.name=='TupleField')].inner.kind.tuple[*]" $tup_field
+    // @set tup_field = "$.index[*][?(@.name=='0' && @.inner.struct_field)].id"
+    // @is "$.index[*][?(@.name=='TupleField')].inner.variant.kind.tuple[*]" $tup_field
     TupleField(i32),
 }
 
-// @is    "$.index[*][?(@.name=='Foo')].inner.variants[0]" $Unit
-// @is    "$.index[*][?(@.name=='Foo')].inner.variants[1]" $Named
-// @is    "$.index[*][?(@.name=='Foo')].inner.variants[2]" $Tuple
-// @is    "$.index[*][?(@.name=='Foo')].inner.variants[3]" $NamedField
-// @is    "$.index[*][?(@.name=='Foo')].inner.variants[4]" $TupleField
-// @count "$.index[*][?(@.name=='Foo')].inner.variants[*]" 5
+// @is    "$.index[*][?(@.name=='Foo')].inner.enum.variants[0]" $Unit
+// @is    "$.index[*][?(@.name=='Foo')].inner.enum.variants[1]" $Named
+// @is    "$.index[*][?(@.name=='Foo')].inner.enum.variants[2]" $Tuple
+// @is    "$.index[*][?(@.name=='Foo')].inner.enum.variants[3]" $NamedField
+// @is    "$.index[*][?(@.name=='Foo')].inner.enum.variants[4]" $TupleField
+// @count "$.index[*][?(@.name=='Foo')].inner.enum.variants[*]" 5
diff --git a/tests/rustdoc-json/enums/struct_field_hidden.rs b/tests/rustdoc-json/enums/struct_field_hidden.rs
index de939cde2e7..2676c4e4157 100644
--- a/tests/rustdoc-json/enums/struct_field_hidden.rs
+++ b/tests/rustdoc-json/enums/struct_field_hidden.rs
@@ -9,8 +9,8 @@ pub enum Foo {
         // @set y = "$.index[*][?(@.name=='y')].id"
         y: i32,
     },
-    // @is "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields_stripped" true
-    // @is "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields[0]" $b
-    // @is "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields[1]" $y
-    // @count "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields[*]" 2
+    // @is "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.fields_stripped" true
+    // @is "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.fields[0]" $b
+    // @is "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.fields[1]" $y
+    // @count "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.fields[*]" 2
 }
diff --git a/tests/rustdoc-json/enums/tuple_fields_hidden.rs b/tests/rustdoc-json/enums/tuple_fields_hidden.rs
index 70bfbb81826..3aeb0356420 100644
--- a/tests/rustdoc-json/enums/tuple_fields_hidden.rs
+++ b/tests/rustdoc-json/enums/tuple_fields_hidden.rs
@@ -14,47 +14,47 @@
 // @set 3.3.1 = "$.index[*][?(@.docs=='3.3.1')].id"
 
 pub enum EnumWithStrippedTupleVariants {
-    // @count "$.index[*][?(@.name=='None')].inner.kind.tuple[*]" 0
+    // @count "$.index[*][?(@.name=='None')].inner.variant.kind.tuple[*]" 0
     None(),
 
-    // @count "$.index[*][?(@.name=='One')].inner.kind.tuple[*]" 1
-    // @is    "$.index[*][?(@.name=='One')].inner.kind.tuple[0]" $1.1.0
+    // @count "$.index[*][?(@.name=='One')].inner.variant.kind.tuple[*]" 1
+    // @is    "$.index[*][?(@.name=='One')].inner.variant.kind.tuple[0]" $1.1.0
     One(/** 1.1.0*/ bool),
-    // @count "$.index[*][?(@.name=='OneHidden')].inner.kind.tuple[*]" 1
-    // @is    "$.index[*][?(@.name=='OneHidden')].inner.kind.tuple[0]" null
+    // @count "$.index[*][?(@.name=='OneHidden')].inner.variant.kind.tuple[*]" 1
+    // @is    "$.index[*][?(@.name=='OneHidden')].inner.variant.kind.tuple[0]" null
     OneHidden(#[doc(hidden)] bool),
 
-    // @count "$.index[*][?(@.name=='Two')].inner.kind.tuple[*]" 2
-    // @is    "$.index[*][?(@.name=='Two')].inner.kind.tuple[0]" $2.1.0
-    // @is    "$.index[*][?(@.name=='Two')].inner.kind.tuple[1]" $2.1.1
+    // @count "$.index[*][?(@.name=='Two')].inner.variant.kind.tuple[*]" 2
+    // @is    "$.index[*][?(@.name=='Two')].inner.variant.kind.tuple[0]" $2.1.0
+    // @is    "$.index[*][?(@.name=='Two')].inner.variant.kind.tuple[1]" $2.1.1
     Two(/** 2.1.0*/ bool, /** 2.1.1*/ bool),
-    // @count "$.index[*][?(@.name=='TwoLeftHidden')].inner.kind.tuple[*]" 2
-    // @is    "$.index[*][?(@.name=='TwoLeftHidden')].inner.kind.tuple[0]" null
-    // @is    "$.index[*][?(@.name=='TwoLeftHidden')].inner.kind.tuple[1]" $2.2.1
+    // @count "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[*]" 2
+    // @is    "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[0]" null
+    // @is    "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[1]" $2.2.1
     TwoLeftHidden(#[doc(hidden)] bool, /** 2.2.1*/ bool),
-    // @count "$.index[*][?(@.name=='TwoRightHidden')].inner.kind.tuple[*]" 2
-    // @is    "$.index[*][?(@.name=='TwoRightHidden')].inner.kind.tuple[0]" $2.3.0
-    // @is    "$.index[*][?(@.name=='TwoRightHidden')].inner.kind.tuple[1]" null
+    // @count "$.index[*][?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[*]" 2
+    // @is    "$.index[*][?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[0]" $2.3.0
+    // @is    "$.index[*][?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[1]" null
     TwoRightHidden(/** 2.3.0*/ bool, #[doc(hidden)] bool),
-    // @count "$.index[*][?(@.name=='TwoBothHidden')].inner.kind.tuple[*]" 2
-    // @is    "$.index[*][?(@.name=='TwoBothHidden')].inner.kind.tuple[0]" null
-    // @is    "$.index[*][?(@.name=='TwoBothHidden')].inner.kind.tuple[1]" null
+    // @count "$.index[*][?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[*]" 2
+    // @is    "$.index[*][?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[0]" null
+    // @is    "$.index[*][?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[1]" null
     TwoBothHidden(#[doc(hidden)] bool, #[doc(hidden)] bool),
 
-    // @count "$.index[*][?(@.name=='Three1')].inner.kind.tuple[*]" 3
-    // @is    "$.index[*][?(@.name=='Three1')].inner.kind.tuple[0]" null
-    // @is    "$.index[*][?(@.name=='Three1')].inner.kind.tuple[1]" $3.1.1
-    // @is    "$.index[*][?(@.name=='Three1')].inner.kind.tuple[2]" $3.1.2
+    // @count "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[*]" 3
+    // @is    "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[0]" null
+    // @is    "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[1]" $3.1.1
+    // @is    "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[2]" $3.1.2
     Three1(#[doc(hidden)] bool, /** 3.1.1*/ bool, /** 3.1.2*/ bool),
-    // @count "$.index[*][?(@.name=='Three2')].inner.kind.tuple[*]" 3
-    // @is    "$.index[*][?(@.name=='Three2')].inner.kind.tuple[0]" $3.2.0
-    // @is    "$.index[*][?(@.name=='Three2')].inner.kind.tuple[1]" null
-    // @is    "$.index[*][?(@.name=='Three2')].inner.kind.tuple[2]" $3.2.2
+    // @count "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[*]" 3
+    // @is    "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[0]" $3.2.0
+    // @is    "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[1]" null
+    // @is    "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[2]" $3.2.2
     Three2(/** 3.2.0*/ bool, #[doc(hidden)] bool, /** 3.2.2*/ bool),
-    // @count "$.index[*][?(@.name=='Three3')].inner.kind.tuple[*]" 3
-    // @is    "$.index[*][?(@.name=='Three3')].inner.kind.tuple[0]" $3.3.0
-    // @is    "$.index[*][?(@.name=='Three3')].inner.kind.tuple[1]" $3.3.1
-    // @is    "$.index[*][?(@.name=='Three3')].inner.kind.tuple[2]" null
+    // @count "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[*]" 3
+    // @is    "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[0]" $3.3.0
+    // @is    "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[1]" $3.3.1
+    // @is    "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[2]" null
     Three3(/** 3.3.0*/ bool, /** 3.3.1*/ bool, #[doc(hidden)] bool),
 }
 
@@ -70,14 +70,14 @@ pub enum EnumWithStrippedTupleVariants {
 // @is "$.index[*][?(@.docs=='3.3.0')].name" '"0"'
 // @is "$.index[*][?(@.docs=='3.3.1')].name" '"1"'
 
-// @is "$.index[*][?(@.docs=='1.1.0')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='2.1.0')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='2.1.1')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='2.2.1')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='2.3.0')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='3.1.1')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='3.1.2')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='3.2.0')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='3.2.2')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='3.3.0')].inner" '{"kind": "primitive", "inner": "bool"}'
-// @is "$.index[*][?(@.docs=='3.3.1')].inner" '{"kind": "primitive", "inner": "bool"}'
+// @is "$.index[*][?(@.docs=='1.1.0')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='2.1.0')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='2.1.1')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='2.2.1')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='2.3.0')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='3.1.1')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='3.1.2')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='3.2.0')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='3.2.2')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='3.3.0')].inner.struct_field" '{"primitive": "bool"}'
+// @is "$.index[*][?(@.docs=='3.3.1')].inner.struct_field" '{"primitive": "bool"}'
diff --git a/tests/rustdoc-json/enums/use_glob.rs b/tests/rustdoc-json/enums/use_glob.rs
index 62b8b832afd..49990ec5331 100644
--- a/tests/rustdoc-json/enums/use_glob.rs
+++ b/tests/rustdoc-json/enums/use_glob.rs
@@ -10,9 +10,9 @@ pub enum Color {
     Blue,
 }
 
-// @set use_Color = "$.index[*][?(@.kind == 'import')].id"
-// @is "$.index[*][?(@.kind == 'import')].inner.id" $Color
-// @is "$.index[*][?(@.kind == 'import')].inner.glob" true
+// @set use_Color = "$.index[*][?(@.inner.import)].id"
+// @is "$.index[*][?(@.inner.import)].inner.import.id" $Color
+// @is "$.index[*][?(@.inner.import)].inner.import.glob" true
 pub use Color::*;
 
-// @ismany "$.index[*][?(@.name == 'use_glob')].inner.items[*]" $Color $use_Color
+// @ismany "$.index[*][?(@.name == 'use_glob')].inner.module.items[*]" $Color $use_Color
diff --git a/tests/rustdoc-json/enums/use_variant.rs b/tests/rustdoc-json/enums/use_variant.rs
index 5f0d2b9b1ec..8190e1cbe81 100644
--- a/tests/rustdoc-json/enums/use_variant.rs
+++ b/tests/rustdoc-json/enums/use_variant.rs
@@ -6,10 +6,10 @@ pub enum AlwaysNone {
     // @set None = "$.index[*][?(@.name == 'None')].id"
     None,
 }
-// @is "$.index[*][?(@.name == 'AlwaysNone')].inner.variants[*]" $None
+// @is "$.index[*][?(@.name == 'AlwaysNone')].inner.enum.variants[*]" $None
 
-// @set use_None = "$.index[*][?(@.kind == 'import')].id"
-// @is "$.index[*][?(@.kind == 'import')].inner.id" $None
+// @set use_None = "$.index[*][?(@.inner.import)].id"
+// @is "$.index[*][?(@.inner.import)].inner.import.id" $None
 pub use AlwaysNone::None;
 
-// @ismany "$.index[*][?(@.name == 'use_variant')].inner.items[*]" $AlwaysNone $use_None
+// @ismany "$.index[*][?(@.name == 'use_variant')].inner.module.items[*]" $AlwaysNone $use_None
diff --git a/tests/rustdoc-json/enums/use_variant_foreign.rs b/tests/rustdoc-json/enums/use_variant_foreign.rs
index 11bb6ce1f3a..a79e899d85f 100644
--- a/tests/rustdoc-json/enums/use_variant_foreign.rs
+++ b/tests/rustdoc-json/enums/use_variant_foreign.rs
@@ -2,7 +2,7 @@
 
 extern crate color;
 
-// @is "$.index[*][?(@.inner.name == 'Red')].kind" '"import"'
+// @has "$.index[*].inner.import[?(@.name == 'Red')]"
 pub use color::Color::Red;
 
 // @!has "$.index[*][?(@.name == 'Red')]"
diff --git a/tests/rustdoc-json/enums/variant_struct.rs b/tests/rustdoc-json/enums/variant_struct.rs
index bc870c502a0..fe40f1a5d5d 100644
--- a/tests/rustdoc-json/enums/variant_struct.rs
+++ b/tests/rustdoc-json/enums/variant_struct.rs
@@ -1,10 +1,10 @@
 // @is "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='EnumStruct')].kind" \"enum\"
+// @has "$.index[*][?(@.name=='EnumStruct')].inner.enum"
 pub enum EnumStruct {
-    // @is "$.index[*][?(@.name=='x')].kind" \"struct_field\"
+    // @has "$.index[*][?(@.name=='x')].inner.struct_field"
     // @set x = "$.index[*][?(@.name=='x')].id"
-    // @is "$.index[*][?(@.name=='y')].kind" \"struct_field\"
+    // @has "$.index[*][?(@.name=='y')].inner.struct_field"
     // @set y = "$.index[*][?(@.name=='y')].id"
-    // @ismany "$.index[*][?(@.name=='VariantS')].inner.kind.struct.fields[*]" $x $y
+    // @ismany "$.index[*][?(@.name=='VariantS')].inner.variant.kind.struct.fields[*]" $x $y
     VariantS { x: u32, y: String },
 }
diff --git a/tests/rustdoc-json/enums/variant_tuple_struct.rs b/tests/rustdoc-json/enums/variant_tuple_struct.rs
index d1207bbfb18..358fc1079cb 100644
--- a/tests/rustdoc-json/enums/variant_tuple_struct.rs
+++ b/tests/rustdoc-json/enums/variant_tuple_struct.rs
@@ -1,10 +1,10 @@
 // @is "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='EnumTupleStruct')].kind" \"enum\"
+// @has "$.index[*][?(@.name=='EnumTupleStruct')].inner.enum"
 pub enum EnumTupleStruct {
-    // @is "$.index[*][?(@.name=='0')].kind" \"struct_field\"
+    // @has "$.index[*][?(@.name=='0')].inner.struct_field"
     // @set f0 = "$.index[*][?(@.name=='0')].id"
-    // @is "$.index[*][?(@.name=='1')].kind" \"struct_field\"
+    // @has "$.index[*][?(@.name=='1')].inner.struct_field"
     // @set f1 = "$.index[*][?(@.name=='1')].id"
-    // @ismany "$.index[*][?(@.name=='VariantA')].inner.kind.tuple[*]" $f0 $f1
+    // @ismany "$.index[*][?(@.name=='VariantA')].inner.variant.kind.tuple[*]" $f0 $f1
     VariantA(u32, String),
 }
diff --git a/tests/rustdoc-json/fn_pointer/abi.rs b/tests/rustdoc-json/fn_pointer/abi.rs
index 6a30acc2cc3..77c0e82330f 100644
--- a/tests/rustdoc-json/fn_pointer/abi.rs
+++ b/tests/rustdoc-json/fn_pointer/abi.rs
@@ -2,23 +2,23 @@
 
 #![feature(abi_vectorcall)]
 
-// @is "$.index[*][?(@.name=='AbiRust')].inner.type.inner.header.abi" \"Rust\"
+// @is "$.index[*][?(@.name=='AbiRust')].inner.typedef.type.function_pointer.header.abi" \"Rust\"
 pub type AbiRust = fn();
 
-// @is "$.index[*][?(@.name=='AbiC')].inner.type.inner.header.abi" '{"C": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='AbiC')].inner.typedef.type.function_pointer.header.abi" '{"C": {"unwind": false}}'
 pub type AbiC = extern "C" fn();
 
-// @is "$.index[*][?(@.name=='AbiSystem')].inner.type.inner.header.abi" '{"System": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='AbiSystem')].inner.typedef.type.function_pointer.header.abi" '{"System": {"unwind": false}}'
 pub type AbiSystem = extern "system" fn();
 
-// @is "$.index[*][?(@.name=='AbiCUnwind')].inner.type.inner.header.abi" '{"C": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='AbiCUnwind')].inner.typedef.type.function_pointer.header.abi" '{"C": {"unwind": true}}'
 pub type AbiCUnwind = extern "C-unwind" fn();
 
-// @is "$.index[*][?(@.name=='AbiSystemUnwind')].inner.type.inner.header.abi" '{"System": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='AbiSystemUnwind')].inner.typedef.type.function_pointer.header.abi" '{"System": {"unwind": true}}'
 pub type AbiSystemUnwind = extern "system-unwind" fn();
 
-// @is "$.index[*][?(@.name=='AbiVecorcall')].inner.type.inner.header.abi.Other" '"\"vectorcall\""'
+// @is "$.index[*][?(@.name=='AbiVecorcall')].inner.typedef.type.function_pointer.header.abi.Other" '"\"vectorcall\""'
 pub type AbiVecorcall = extern "vectorcall" fn();
 
-// @is "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.type.inner.header.abi.Other" '"\"vectorcall-unwind\""'
+// @is "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.typedef.type.function_pointer.header.abi.Other" '"\"vectorcall-unwind\""'
 pub type AbiVecorcallUnwind = extern "vectorcall-unwind" fn();
diff --git a/tests/rustdoc-json/fn_pointer/generics.rs b/tests/rustdoc-json/fn_pointer/generics.rs
index a93b01ac2c4..48672f12da1 100644
--- a/tests/rustdoc-json/fn_pointer/generics.rs
+++ b/tests/rustdoc-json/fn_pointer/generics.rs
@@ -3,12 +3,11 @@
 #![feature(no_core)]
 #![no_core]
 
-// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[*]" 1
-// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][0]" '"val"'
-// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].inner.lifetime" \"\'c\"
-// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.output" '{ "kind": "primitive", "inner": "i32" }'
-// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[*]" 1
-// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].name" \"\'c\"
-// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.typedef.type.function_pointer.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.typedef.type.function_pointer.decl.inputs[0][0]" '"val"'
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.typedef.type.function_pointer.decl.inputs[0][1].borrowed_ref.lifetime" \"\'c\"
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.typedef.type.function_pointer.decl.output.primitive" \"i32\"
+// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.typedef.type.function_pointer.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.typedef.type.function_pointer.generic_params[0].name" \"\'c\"
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.typedef.type.function_pointer.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
 pub type WithHigherRankTraitBounds = for<'c> fn(val: &'c i32) -> i32;
diff --git a/tests/rustdoc-json/fn_pointer/qualifiers.rs b/tests/rustdoc-json/fn_pointer/qualifiers.rs
index bd65bb3eefe..0ab776c21ed 100644
--- a/tests/rustdoc-json/fn_pointer/qualifiers.rs
+++ b/tests/rustdoc-json/fn_pointer/qualifiers.rs
@@ -1,9 +1,11 @@
-// @is "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.unsafe" false
-// @is "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.const" false
-// @is "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.async" false
+// ignore-tidy-linelength
+
+// @is "$.index[*][?(@.name=='FnPointer')].inner.typedef.type.function_pointer.header.unsafe" false
+// @is "$.index[*][?(@.name=='FnPointer')].inner.typedef.type.function_pointer.header.const" false
+// @is "$.index[*][?(@.name=='FnPointer')].inner.typedef.type.function_pointer.header.async" false
 pub type FnPointer = fn();
 
-// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.unsafe" true
-// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.const" false
-// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.async" false
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.typedef.type.function_pointer.header.unsafe" true
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.typedef.type.function_pointer.header.const" false
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.typedef.type.function_pointer.header.async" false
 pub type UnsafePointer = unsafe fn();
diff --git a/tests/rustdoc-json/fns/abi.rs b/tests/rustdoc-json/fns/abi.rs
index 7a5dbee730c..d7b98b5924b 100644
--- a/tests/rustdoc-json/fns/abi.rs
+++ b/tests/rustdoc-json/fns/abi.rs
@@ -2,23 +2,23 @@
 
 #![feature(abi_vectorcall)]
 
-// @is "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
+// @is "$.index[*][?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\"
 pub fn abi_rust() {}
 
-// @is "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}'
 pub extern "C" fn abi_c() {}
 
-// @is "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}'
 pub extern "system" fn abi_system() {}
 
-// @is "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}'
 pub extern "C-unwind" fn abi_c_unwind() {}
 
-// @is "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}'
 pub extern "system-unwind" fn abi_system_unwind() {}
 
-// @is "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+// @is "$.index[*][?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""'
 pub extern "vectorcall" fn abi_vectorcall() {}
 
-// @is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+// @is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""'
 pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {}
diff --git a/tests/rustdoc-json/fns/async_return.rs b/tests/rustdoc-json/fns/async_return.rs
index b89781ca92d..8192f2e6ae6 100644
--- a/tests/rustdoc-json/fns/async_return.rs
+++ b/tests/rustdoc-json/fns/async_return.rs
@@ -5,32 +5,30 @@
 
 use std::future::Future;
 
-// @is "$.index[*][?(@.name=='get_int')].inner.decl.output" '{"inner": "i32", "kind": "primitive"}'
-// @is "$.index[*][?(@.name=='get_int')].inner.header.async" false
+// @is "$.index[*][?(@.name=='get_int')].inner.function.decl.output.primitive" \"i32\"
+// @is "$.index[*][?(@.name=='get_int')].inner.function.header.async" false
 pub fn get_int() -> i32 {
     42
 }
 
-// @is "$.index[*][?(@.name=='get_int_async')].inner.decl.output" '{"inner": "i32", "kind": "primitive"}'
-// @is "$.index[*][?(@.name=='get_int_async')].inner.header.async" true
+// @is "$.index[*][?(@.name=='get_int_async')].inner.function.decl.output.primitive" \"i32\"
+// @is "$.index[*][?(@.name=='get_int_async')].inner.function.header.async" true
 pub async fn get_int_async() -> i32 {
     42
 }
 
-// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.kind" '"impl_trait"'
-// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.inner[0].trait_bound.trait.name" '"Future"'
-// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].name" '"Output"'
-// @is "$.index[*][?(@.name=='get_int_future')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].binding.equality.type" '{"inner": "i32", "kind": "primitive"}'
-// @is "$.index[*][?(@.name=='get_int_future')].inner.header.async" false
+// @is "$.index[*][?(@.name=='get_int_future')].inner.function.decl.output.impl_trait[0].trait_bound.trait.name" '"Future"'
+// @is "$.index[*][?(@.name=='get_int_future')].inner.function.decl.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.bindings[0].name" '"Output"'
+// @is "$.index[*][?(@.name=='get_int_future')].inner.function.decl.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.bindings[0].binding.equality.type.primitive"  \"i32\"
+// @is "$.index[*][?(@.name=='get_int_future')].inner.function.header.async" false
 pub fn get_int_future() -> impl Future<Output = i32> {
     async { 42 }
 }
 
-// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.kind" '"impl_trait"'
-// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.inner[0].trait_bound.trait.name" '"Future"'
-// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].name" '"Output"'
-// @is "$.index[*][?(@.name=='get_int_future_async')].inner.decl.output.inner[0].trait_bound.trait.args.angle_bracketed.bindings[0].binding.equality.type" '{"inner": "i32", "kind": "primitive"}'
-// @is "$.index[*][?(@.name=='get_int_future_async')].inner.header.async" true
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.function.decl.output.impl_trait[0].trait_bound.trait.name" '"Future"'
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.function.decl.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.bindings[0].name" '"Output"'
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.function.decl.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.bindings[0].binding.equality.type.primitive" \"i32\"
+// @is "$.index[*][?(@.name=='get_int_future_async')].inner.function.header.async" true
 pub async fn get_int_future_async() -> impl Future<Output = i32> {
     async { 42 }
 }
diff --git a/tests/rustdoc-json/fns/extern_c_variadic.rs b/tests/rustdoc-json/fns/extern_c_variadic.rs
index 33bebbab5e0..d6ea343b991 100644
--- a/tests/rustdoc-json/fns/extern_c_variadic.rs
+++ b/tests/rustdoc-json/fns/extern_c_variadic.rs
@@ -2,8 +2,8 @@
 #![no_core]
 
 extern "C" {
-    // @is "$.index[*][?(@.name == 'not_variadic')].inner.decl.c_variadic" false
+    // @is "$.index[*][?(@.name == 'not_variadic')].inner.function.decl.c_variadic" false
     pub fn not_variadic(_: i32);
-    // @is "$.index[*][?(@.name == 'variadic')].inner.decl.c_variadic" true
+    // @is "$.index[*][?(@.name == 'variadic')].inner.function.decl.c_variadic" true
     pub fn variadic(_: i32, ...);
 }
diff --git a/tests/rustdoc-json/fns/generic_args.rs b/tests/rustdoc-json/fns/generic_args.rs
index eec295efec0..539d17f831e 100644
--- a/tests/rustdoc-json/fns/generic_args.rs
+++ b/tests/rustdoc-json/fns/generic_args.rs
@@ -9,59 +9,55 @@ pub trait Foo {}
 // @set generic_foo = "$.index[*][?(@.name=='GenericFoo')].id"
 pub trait GenericFoo<'a> {}
 
-// @is "$.index[*][?(@.name=='generics')].inner.generics.where_predicates" "[]"
-// @count "$.index[*][?(@.name=='generics')].inner.generics.params[*]" 1
-// @is "$.index[*][?(@.name=='generics')].inner.generics.params[0].name" '"F"'
-// @is "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.default" 'null'
-// @count "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[*]" 1
-// @is "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo'
-// @count "$.index[*][?(@.name=='generics')].inner.decl.inputs[*]" 1
-// @is "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][0]" '"f"'
-// @is "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].kind" '"generic"'
-// @is "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].inner" '"F"'
+// @is "$.index[*][?(@.name=='generics')].inner.function.generics.where_predicates" "[]"
+// @count "$.index[*][?(@.name=='generics')].inner.function.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].name" '"F"'
+// @is "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].kind.type.default" 'null'
+// @count "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].kind.type.bounds[*]" 1
+// @is "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo'
+// @count "$.index[*][?(@.name=='generics')].inner.function.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='generics')].inner.function.decl.inputs[0][0]" '"f"'
+// @is "$.index[*][?(@.name=='generics')].inner.function.decl.inputs[0][1].generic" '"F"'
 pub fn generics<F: Foo>(f: F) {}
 
-// @is "$.index[*][?(@.name=='impl_trait')].inner.generics.where_predicates" "[]"
-// @count "$.index[*][?(@.name=='impl_trait')].inner.generics.params[*]" 1
-// @is "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].name" '"impl Foo"'
-// @is "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo
-// @count "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[*]" 1
-// @is "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][0]" '"f"'
-// @is "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].kind" '"impl_trait"'
-// @count "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[*]" 1
-// @is "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $foo
+// @is "$.index[*][?(@.name=='impl_trait')].inner.function.generics.where_predicates" "[]"
+// @count "$.index[*][?(@.name=='impl_trait')].inner.function.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='impl_trait')].inner.function.generics.params[0].name" '"impl Foo"'
+// @is "$.index[*][?(@.name=='impl_trait')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo
+// @count "$.index[*][?(@.name=='impl_trait')].inner.function.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='impl_trait')].inner.function.decl.inputs[0][0]" '"f"'
+// @count "$.index[*][?(@.name=='impl_trait')].inner.function.decl.inputs[0][1].impl_trait[*]" 1
+// @is "$.index[*][?(@.name=='impl_trait')].inner.function.decl.inputs[0][1].impl_trait[0].trait_bound.trait.id" $foo
 pub fn impl_trait(f: impl Foo) {}
 
-// @count "$.index[*][?(@.name=='where_clase')].inner.generics.params[*]" 3
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].name" '"F"'
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].kind" '{"type": {"bounds": [], "default": null, "synthetic": false}}'
-// @count "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[*]" 3
-// @is "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][0]" '"f"'
-// @is "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].kind" '"generic"'
-// @is "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].inner" '"F"'
-// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[*]" 3
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.generics.params[*]" 3
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.params[0].name" '"F"'
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.params[0].kind" '{"type": {"bounds": [], "default": null, "synthetic": false}}'
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.decl.inputs[*]" 3
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.decl.inputs[0][0]" '"f"'
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.decl.inputs[0][1].generic" '"F"'
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[*]" 3
 
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F", "kind": "generic"}'
-// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[*]" 1
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.type.generic" \"F\"
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.bounds[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo
 
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.type" '{"inner": "G", "kind": "generic"}'
-// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[*]" 1
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo
-// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.generic_params" "[]"
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.type.generic" \"G\"
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind.lifetime.outlives" "[]"
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.generic_params" "[]"
 
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.lifetime" \"\'b\"
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.type" '{"inner": "H", "kind": "generic"}'
-// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[*]" 1
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
-// @count "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
-// @is "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.type.borrowed_ref.lifetime" \"\'b\"
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.type.borrowed_ref.type.generic" \"H\"
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
+// @count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
+// @is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[0].kind.lifetime.outlives" "[]"
 pub fn where_clase<F, G, H>(f: F, g: G, h: H)
 where
     F: Foo,
diff --git a/tests/rustdoc-json/fns/generic_returns.rs b/tests/rustdoc-json/fns/generic_returns.rs
index a9bc2d5d727..27d842066f4 100644
--- a/tests/rustdoc-json/fns/generic_returns.rs
+++ b/tests/rustdoc-json/fns/generic_returns.rs
@@ -3,15 +3,14 @@
 #![feature(no_core)]
 #![no_core]
 
-// @count "$.index[*][?(@.name=='generic_returns')].inner.items[*]" 2
+// @count "$.index[*][?(@.name=='generic_returns')].inner.module.items[*]" 2
 
 // @set foo = "$.index[*][?(@.name=='Foo')].id"
 pub trait Foo {}
 
-// @is "$.index[*][?(@.name=='get_foo')].inner.decl.inputs" []
-// @is "$.index[*][?(@.name=='get_foo')].inner.decl.output.kind" '"impl_trait"'
-// @count "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[*]" 1
-// @is "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.id" $foo
+// @is "$.index[*][?(@.name=='get_foo')].inner.function.decl.inputs" []
+// @count "$.index[*][?(@.name=='get_foo')].inner.function.decl.output.impl_trait[*]" 1
+// @is "$.index[*][?(@.name=='get_foo')].inner.function.decl.output.impl_trait[0].trait_bound.trait.id" $foo
 pub fn get_foo() -> impl Foo {
     Fooer {}
 }
diff --git a/tests/rustdoc-json/fns/generics.rs b/tests/rustdoc-json/fns/generics.rs
index 7b70ff1df6b..5239a6f21f5 100644
--- a/tests/rustdoc-json/fns/generics.rs
+++ b/tests/rustdoc-json/fns/generics.rs
@@ -6,21 +6,20 @@
 // @set wham_id = "$.index[*][?(@.name=='Wham')].id"
 pub trait Wham {}
 
-// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
-// @count "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
-// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
-// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
-// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
-// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
+// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.where_predicates" []
+// @count "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[*]" 1
+// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].name" '"T"'
+// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].kind.type.synthetic" false
+// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
+// @is    "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.decl.inputs" '[["w", {"generic": "T"}]]'
 pub fn one_generic_param_fn<T: Wham>(w: T) {}
 
-// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
-// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
-// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
-// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
-// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
-// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
-// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
-// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
-// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $wham_id
+// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.where_predicates" []
+// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[*]" 1
+// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].name" '"impl Wham"'
+// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].kind.type.synthetic" true
+// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
+// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.decl.inputs[*]" 1
+// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.decl.inputs[0][0]" '"w"'
+// @is    "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.decl.inputs[0][1].impl_trait[0].trait_bound.trait.id" $wham_id
 pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
diff --git a/tests/rustdoc-json/fns/pattern_arg.rs b/tests/rustdoc-json/fns/pattern_arg.rs
index 32b7da0fae4..55f24797ac0 100644
--- a/tests/rustdoc-json/fns/pattern_arg.rs
+++ b/tests/rustdoc-json/fns/pattern_arg.rs
@@ -1,7 +1,7 @@
-// @is "$.index[*][?(@.name=='fst')].inner.decl.inputs[0][0]" '"(x, _)"'
+// @is "$.index[*][?(@.name=='fst')].inner.function.decl.inputs[0][0]" '"(x, _)"'
 pub fn fst<X, Y>((x, _): (X, Y)) -> X {
     x
 }
 
-// @is "$.index[*][?(@.name=='drop_int')].inner.decl.inputs[0][0]" '"_"'
+// @is "$.index[*][?(@.name=='drop_int')].inner.function.decl.inputs[0][0]" '"_"'
 pub fn drop_int(_: i32) {}
diff --git a/tests/rustdoc-json/fns/qualifiers.rs b/tests/rustdoc-json/fns/qualifiers.rs
index 7ff54290042..643865a3f07 100644
--- a/tests/rustdoc-json/fns/qualifiers.rs
+++ b/tests/rustdoc-json/fns/qualifiers.rs
@@ -1,33 +1,33 @@
 // edition:2018
 
-// @is "$.index[*][?(@.name=='nothing_fn')].inner.header.async" false
-// @is "$.index[*][?(@.name=='nothing_fn')].inner.header.const"  false
-// @is "$.index[*][?(@.name=='nothing_fn')].inner.header.unsafe" false
+// @is "$.index[*][?(@.name=='nothing_fn')].inner.function.header.async" false
+// @is "$.index[*][?(@.name=='nothing_fn')].inner.function.header.const"  false
+// @is "$.index[*][?(@.name=='nothing_fn')].inner.function.header.unsafe" false
 pub fn nothing_fn() {}
 
-// @is "$.index[*][?(@.name=='unsafe_fn')].inner.header.async"  false
-// @is "$.index[*][?(@.name=='unsafe_fn')].inner.header.const"  false
-// @is "$.index[*][?(@.name=='unsafe_fn')].inner.header.unsafe" true
+// @is "$.index[*][?(@.name=='unsafe_fn')].inner.function.header.async"  false
+// @is "$.index[*][?(@.name=='unsafe_fn')].inner.function.header.const"  false
+// @is "$.index[*][?(@.name=='unsafe_fn')].inner.function.header.unsafe" true
 pub unsafe fn unsafe_fn() {}
 
-// @is "$.index[*][?(@.name=='const_fn')].inner.header.async"  false
-// @is "$.index[*][?(@.name=='const_fn')].inner.header.const"  true
-// @is "$.index[*][?(@.name=='const_fn')].inner.header.unsafe" false
+// @is "$.index[*][?(@.name=='const_fn')].inner.function.header.async"  false
+// @is "$.index[*][?(@.name=='const_fn')].inner.function.header.const"  true
+// @is "$.index[*][?(@.name=='const_fn')].inner.function.header.unsafe" false
 pub const fn const_fn() {}
 
-// @is "$.index[*][?(@.name=='async_fn')].inner.header.async"  true
-// @is "$.index[*][?(@.name=='async_fn')].inner.header.const"  false
-// @is "$.index[*][?(@.name=='async_fn')].inner.header.unsafe" false
+// @is "$.index[*][?(@.name=='async_fn')].inner.function.header.async"  true
+// @is "$.index[*][?(@.name=='async_fn')].inner.function.header.const"  false
+// @is "$.index[*][?(@.name=='async_fn')].inner.function.header.unsafe" false
 pub async fn async_fn() {}
 
-// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.async"  true
-// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.const"  false
-// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.unsafe" true
+// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.function.header.async"  true
+// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.function.header.const"  false
+// @is "$.index[*][?(@.name=='async_unsafe_fn')].inner.function.header.unsafe" true
 pub async unsafe fn async_unsafe_fn() {}
 
-// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.async"  false
-// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.const"  true
-// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.unsafe" true
+// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.function.header.async"  false
+// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.function.header.const"  true
+// @is "$.index[*][?(@.name=='const_unsafe_fn')].inner.function.header.unsafe" true
 pub const unsafe fn const_unsafe_fn() {}
 
 // It's impossible for a function to be both const and async, so no test for that
diff --git a/tests/rustdoc-json/fns/return_type_alias.rs b/tests/rustdoc-json/fns/return_type_alias.rs
index 2578bb49ad3..e8a7dce8b0a 100644
--- a/tests/rustdoc-json/fns/return_type_alias.rs
+++ b/tests/rustdoc-json/fns/return_type_alias.rs
@@ -3,8 +3,7 @@
 /// @set foo = "$.index[*][?(@.name=='Foo')].id"
 pub type Foo = i32;
 
-// @is "$.index[*][?(@.name=='demo')].inner.decl.output.kind" '"resolved_path"'
-// @is "$.index[*][?(@.name=='demo')].inner.decl.output.inner.id" $foo
+// @is "$.index[*][?(@.name=='demo')].inner.function.decl.output.resolved_path.id" $foo
 pub fn demo() -> Foo {
     42
 }
diff --git a/tests/rustdoc-json/generic-associated-types/gats.rs b/tests/rustdoc-json/generic-associated-types/gats.rs
index e5809783aec..99c57ff6540 100644
--- a/tests/rustdoc-json/generic-associated-types/gats.rs
+++ b/tests/rustdoc-json/generic-associated-types/gats.rs
@@ -9,34 +9,32 @@ pub trait Sized {}
 pub trait Display {}
 
 pub trait LendingIterator {
-    // @count "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*]" 1
-    // @is "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*].name" \"\'a\"
-    // @count "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*]" 1
-    // @is "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.type.inner" \"Self\"
-    // @is "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.bounds[*].outlives" \"\'a\"
-    // @count "$.index[*][?(@.name=='LendingItem')].inner.bounds[*]" 1
+    // @count "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.params[*]" 1
+    // @is "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.params[*].name" \"\'a\"
+    // @count "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*]" 1
+    // @is "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*].bound_predicate.type.generic" \"Self\"
+    // @is "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*].bound_predicate.bounds[*].outlives" \"\'a\"
+    // @count "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.bounds[*]" 1
     type LendingItem<'a>: Display
     where
         Self: 'a;
 
-    // @is "$.index[*][?(@.name=='lending_next')].inner.decl.output.kind" \"qualified_path\"
-    // @count "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 1
-    // @count "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
-    // @is "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.self_type.inner" \"Self\"
-    // @is "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.name" \"LendingItem\"
+    // @count "$.index[*][?(@.name=='lending_next')].inner.function.decl.output.qualified_path.args.angle_bracketed.args[*]" 1
+    // @count "$.index[*][?(@.name=='lending_next')].inner.function.decl.output.qualified_path.args.angle_bracketed.bindings[*]" 0
+    // @is "$.index[*][?(@.name=='lending_next')].inner.function.decl.output.qualified_path.self_type.generic" \"Self\"
+    // @is "$.index[*][?(@.name=='lending_next')].inner.function.decl.output.qualified_path.name" \"LendingItem\"
     fn lending_next<'a>(&'a self) -> Self::LendingItem<'a>;
 }
 
 pub trait Iterator {
-    // @count "$.index[*][?(@.name=='Item')].inner.generics.params[*]" 0
-    // @count "$.index[*][?(@.name=='Item')].inner.generics.where_predicates[*]" 0
-    // @count "$.index[*][?(@.name=='Item')].inner.bounds[*]" 1
+    // @count "$.index[*][?(@.name=='Item')].inner.assoc_type.generics.params[*]" 0
+    // @count "$.index[*][?(@.name=='Item')].inner.assoc_type.generics.where_predicates[*]" 0
+    // @count "$.index[*][?(@.name=='Item')].inner.assoc_type.bounds[*]" 1
     type Item: Display;
 
-    // @is "$.index[*][?(@.name=='next')].inner.decl.output.kind" \"qualified_path\"
-    // @count "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 0
-    // @count "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
-    // @is "$.index[*][?(@.name=='next')].inner.decl.output.inner.self_type.inner" \"Self\"
-    // @is "$.index[*][?(@.name=='next')].inner.decl.output.inner.name" \"Item\"
+    // @count "$.index[*][?(@.name=='next')].inner.function.decl.output.qualified_path.args.angle_bracketed.args[*]" 0
+    // @count "$.index[*][?(@.name=='next')].inner.function.decl.output.qualified_path.args.angle_bracketed.bindings[*]" 0
+    // @is "$.index[*][?(@.name=='next')].inner.function.decl.output.qualified_path.self_type.generic" \"Self\"
+    // @is "$.index[*][?(@.name=='next')].inner.function.decl.output.qualified_path.name" \"Item\"
     fn next<'a>(&'a self) -> Self::Item;
 }
diff --git a/tests/rustdoc-json/glob_import.rs b/tests/rustdoc-json/glob_import.rs
index 00051b12199..f37ce0abb41 100644
--- a/tests/rustdoc-json/glob_import.rs
+++ b/tests/rustdoc-json/glob_import.rs
@@ -5,7 +5,7 @@
 #![no_core]
 
 // @has "$.index[*][?(@.name=='glob')]"
-// @has "$.index[*][?(@.kind=='import')].inner.name" \"*\"
+// @has "$.index[*][?(@.inner.import)].inner.import.name" \"*\"
 
 
 mod m1 {
diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs
index 50d85241427..ace37e5b3df 100644
--- a/tests/rustdoc-json/impls/auto.rs
+++ b/tests/rustdoc-json/impls/auto.rs
@@ -12,7 +12,8 @@ impl Foo {
 }
 
 // Testing spans, so all tests below code
-// @is "$.index[*][?(@.kind=='impl' && @.inner.synthetic==true)].span" null
 // @is "$.index[*][?(@.docs=='has span')].span.begin" "[10, 0]"
 // @is "$.index[*][?(@.docs=='has span')].span.end" "[12, 1]"
+// FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91
+// is "$.index[*][?(@.inner.impl.synthetic==true)].span" null
 pub struct Foo;
diff --git a/tests/rustdoc-json/impls/foreign_for_local.rs b/tests/rustdoc-json/impls/foreign_for_local.rs
index 290c2d571e8..20e1cecd778 100644
--- a/tests/rustdoc-json/impls/foreign_for_local.rs
+++ b/tests/rustdoc-json/impls/foreign_for_local.rs
@@ -3,7 +3,7 @@ extern crate foreign_trait;
 
 /// ForeignTrait id hack
 pub use foreign_trait::ForeignTrait as _;
-// @set ForeignTrait = "$.index[*][?(@.docs=='ForeignTrait id hack')].inner.id"
+// @set ForeignTrait = "$.index[*][?(@.docs=='ForeignTrait id hack')].inner.import.id"
 
 pub struct LocalStruct;
 // @set LocalStruct = "$.index[*][?(@.name=='LocalStruct')].id"
@@ -12,7 +12,7 @@ pub struct LocalStruct;
 impl foreign_trait::ForeignTrait for LocalStruct {}
 
 // @set impl = "$.index[*][?(@.docs=='foreign for local')].id"
-// @is "$.index[*][?(@.docs=='foreign for local')].inner.for.inner.id" $LocalStruct
-// @is "$.index[*][?(@.docs=='foreign for local')].inner.trait.id" $ForeignTrait
+// @is "$.index[*][?(@.docs=='foreign for local')].inner.impl.for.resolved_path.id" $LocalStruct
+// @is "$.index[*][?(@.docs=='foreign for local')].inner.impl.trait.id" $ForeignTrait
 
-// @has "$.index[*][?(@.name=='LocalStruct')].inner.impls[*]" $impl
+// @has "$.index[*][?(@.name=='LocalStruct')].inner.struct.impls[*]" $impl
diff --git a/tests/rustdoc-json/impls/import_from_private.rs b/tests/rustdoc-json/impls/import_from_private.rs
index fa88b6113a5..d2b0665dcaf 100644
--- a/tests/rustdoc-json/impls/import_from_private.rs
+++ b/tests/rustdoc-json/impls/import_from_private.rs
@@ -4,19 +4,19 @@
 #![no_core]
 
 mod bar {
-    // @set baz = "$.index[*][?(@.kind=='struct')].id"
+    // @set baz = "$.index[*][?(@.inner.struct)].id"
     pub struct Baz;
-    // @set impl = "$.index[*][?(@.kind=='impl')].id"
+    // @set impl = "$.index[*][?(@.inner.impl)].id"
     impl Baz {
-        // @set doit = "$.index[*][?(@.kind=='function')].id"
+        // @set doit = "$.index[*][?(@.inner.function)].id"
         pub fn doit() {}
     }
 }
 
-// @set import = "$.index[*][?(@.kind=='import')].id"
+// @set import = "$.index[*][?(@.inner.import)].id"
 pub use bar::Baz;
 
-// @is "$.index[*][?(@.kind=='module')].inner.items[*]" $import
-// @is "$.index[*][?(@.kind=='import')].inner.id" $baz
-// @is "$.index[*][?(@.kind=='struct')].inner.impls[*]" $impl
-// @is "$.index[*][?(@.kind=='impl')].inner.items[*]" $doit
+// @is "$.index[*].inner.module.items[*]" $import
+// @is "$.index[*].inner.import.id" $baz
+// @is "$.index[*].inner.struct.impls[*]" $impl
+// @is "$.index[*].inner.impl.items[*]" $doit
diff --git a/tests/rustdoc-json/impls/local_for_foreign.rs b/tests/rustdoc-json/impls/local_for_foreign.rs
index 74f2f08b5a4..72352ce88da 100644
--- a/tests/rustdoc-json/impls/local_for_foreign.rs
+++ b/tests/rustdoc-json/impls/local_for_foreign.rs
@@ -3,7 +3,7 @@ extern crate foreign_struct;
 
 /// ForeignStruct id hack
 pub use foreign_struct::ForeignStruct as _;
-// @set ForeignStruct = "$.index[*][?(@.docs=='ForeignStruct id hack')].inner.id"
+// @set ForeignStruct = "$.index[*][?(@.docs=='ForeignStruct id hack')].inner.import.id"
 
 pub trait LocalTrait {}
 // @set LocalTrait = "$.index[*][?(@.name=='LocalTrait')].id"
@@ -12,7 +12,7 @@ pub trait LocalTrait {}
 impl LocalTrait for foreign_struct::ForeignStruct {}
 
 // @set impl = "$.index[*][?(@.docs=='local for foreign')].id"
-// @is "$.index[*][?(@.docs=='local for foreign')].inner.trait.id" $LocalTrait
-// @is "$.index[*][?(@.docs=='local for foreign')].inner.for.inner.id" $ForeignStruct
+// @is "$.index[*][?(@.docs=='local for foreign')].inner.impl.trait.id" $LocalTrait
+// @is "$.index[*][?(@.docs=='local for foreign')].inner.impl.for.resolved_path.id" $ForeignStruct
 
-// @is "$.index[*][?(@.name=='LocalTrait')].inner.implementations[*]" $impl
+// @is "$.index[*][?(@.name=='LocalTrait')].inner.trait.implementations[*]" $impl
diff --git a/tests/rustdoc-json/impls/local_for_local.rs b/tests/rustdoc-json/impls/local_for_local.rs
index 93dedb7ec92..37a72000329 100644
--- a/tests/rustdoc-json/impls/local_for_local.rs
+++ b/tests/rustdoc-json/impls/local_for_local.rs
@@ -9,7 +9,7 @@ pub trait Trait {}
 /// impl
 impl Trait for Struct {}
 
-// @is "$.index[*][?(@.name=='Struct')].inner.impls[*]" $impl
-// @is "$.index[*][?(@.name=='Trait')].inner.implementations[*]" $impl
-// @is "$.index[*][?(@.docs=='impl')].inner.trait.id" $trait
-// @is "$.index[*][?(@.docs=='impl')].inner.for.inner.id" $struct
+// @is "$.index[*][?(@.name=='Struct')].inner.struct.impls[*]" $impl
+// @is "$.index[*][?(@.name=='Trait')].inner.trait.implementations[*]" $impl
+// @is "$.index[*][?(@.docs=='impl')].inner.impl.trait.id" $trait
+// @is "$.index[*][?(@.docs=='impl')].inner.impl.for.resolved_path.id" $struct
diff --git a/tests/rustdoc-json/impls/local_for_local_primitive.rs b/tests/rustdoc-json/impls/local_for_local_primitive.rs
index 8383dcc0482..769dd3f0a2c 100644
--- a/tests/rustdoc-json/impls/local_for_local_primitive.rs
+++ b/tests/rustdoc-json/impls/local_for_local_primitive.rs
@@ -5,14 +5,13 @@
 // @set Local = "$.index[*][?(@.name=='Local')].id"
 pub trait Local {}
 
-// @is "$.index[*][?(@.docs=='Local for bool')].inner.trait.id" $Local
-// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.kind" '"primitive"'
-// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.inner" '"bool"'
+// @is "$.index[*][?(@.docs=='Local for bool')].inner.impl.trait.id" $Local
+// @is "$.index[*][?(@.docs=='Local for bool')].inner.impl.for.primitive" '"bool"'
 /// Local for bool
 impl Local for bool {}
 
 // @set impl =  "$.index[*][?(@.docs=='Local for bool')].id"
-// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl
+// @is "$.index[*][?(@.name=='Local')].inner.trait.implementations[*]" $impl
 
 // FIXME(#101695): Test bool's `impls` include "Local for bool"
 // @has "$.index[*][?(@.name=='bool')]"
diff --git a/tests/rustdoc-json/impls/local_for_primitive.rs b/tests/rustdoc-json/impls/local_for_primitive.rs
index 7702a526fd8..85278c0e08c 100644
--- a/tests/rustdoc-json/impls/local_for_primitive.rs
+++ b/tests/rustdoc-json/impls/local_for_primitive.rs
@@ -2,6 +2,6 @@
 pub trait Local {}
 
 // @set impl = "$.index[*][?(@.docs=='local for bool')].id"
-// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl
+// @is "$.index[*][?(@.name=='Local')].inner.trait.implementations[*]" $impl
 /// local for bool
 impl Local for bool {}
diff --git a/tests/rustdoc-json/lifetime/longest.rs b/tests/rustdoc-json/lifetime/longest.rs
index 326dab8e57a..dc28258a8b6 100644
--- a/tests/rustdoc-json/lifetime/longest.rs
+++ b/tests/rustdoc-json/lifetime/longest.rs
@@ -3,30 +3,27 @@
 #![feature(no_core)]
 #![no_core]
 
-// @is "$.index[*][?(@.name=='longest')].inner.generics.params[0].name"  \"\'a\"
-// @is "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind"  '{"lifetime": {"outlives": []}}'
-// @is "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind"  '{"lifetime": {"outlives": []}}'
-// @count "$.index[*][?(@.name=='longest')].inner.generics.params[*]" 1
-// @is "$.index[*][?(@.name=='longest')].inner.generics.where_predicates" []
+// @is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].name"  \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind"  '{"lifetime": {"outlives": []}}'
+// @is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind"  '{"lifetime": {"outlives": []}}'
+// @count "$.index[*][?(@.name=='longest')].inner.function.generics.params[*]" 1
+// @is "$.index[*][?(@.name=='longest')].inner.function.generics.where_predicates" []
 
-// @count "$.index[*][?(@.name=='longest')].inner.decl.inputs[*]" 2
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][0]" '"l"'
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][0]" '"r"'
+// @count "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[*]" 2
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[0][0]" '"l"'
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[1][0]" '"r"'
 
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.mutable" false
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.type" '{"inner": "str", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[0][1].borrowed_ref.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[0][1].borrowed_ref.mutable" false
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[0][1].borrowed_ref.type.primitive" \"str\"
 
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.lifetime" \"\'a\"
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.mutable" false
-// @is "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.type" '{"inner": "str", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[1][1].borrowed_ref.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[1][1].borrowed_ref.mutable" false
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.inputs[1][1].borrowed_ref.type.primitive" \"str\"
 
-// @is "$.index[*][?(@.name=='longest')].inner.decl.output.kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='longest')].inner.decl.output.inner.lifetime" \"\'a\"
-// @is "$.index[*][?(@.name=='longest')].inner.decl.output.inner.mutable" false
-// @is "$.index[*][?(@.name=='longest')].inner.decl.output.inner.type" '{"inner": "str", "kind": "primitive"}'
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.output.borrowed_ref.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.output.borrowed_ref.mutable" false
+// @is "$.index[*][?(@.name=='longest')].inner.function.decl.output.borrowed_ref.type.primitive" \"str\"
 
 pub fn longest<'a>(l: &'a str, r: &'a str) -> &'a str {
     if l.len() > r.len() { l } else { r }
diff --git a/tests/rustdoc-json/lifetime/outlives.rs b/tests/rustdoc-json/lifetime/outlives.rs
index e15a533efdc..6e105b382b0 100644
--- a/tests/rustdoc-json/lifetime/outlives.rs
+++ b/tests/rustdoc-json/lifetime/outlives.rs
@@ -3,21 +3,19 @@
 #![feature(no_core)]
 #![no_core]
 
-// @count "$.index[*][?(@.name=='foo')].inner.generics.params[*]" 3
-// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates" []
-// @is "$.index[*][?(@.name=='foo')].inner.generics.params[0].name" \"\'a\"
-// @is "$.index[*][?(@.name=='foo')].inner.generics.params[1].name" \"\'b\"
-// @is "$.index[*][?(@.name=='foo')].inner.generics.params[2].name" '"T"'
-// @is "$.index[*][?(@.name=='foo')].inner.generics.params[0].kind.lifetime.outlives" []
-// @is "$.index[*][?(@.name=='foo')].inner.generics.params[1].kind.lifetime.outlives" [\"\'a\"]
-// @is "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.default" null
-// @count "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[*]" 1
-// @is "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[0].outlives" \"\'b\"
-// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
-// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.mutable" false
-// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.lifetime" \"\'b\"
-// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.mutable" false
-// @is "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.type" '{"inner": "T", "kind": "generic"}'
+// @count "$.index[*][?(@.name=='foo')].inner.function.generics.params[*]" 3
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates" []
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.params[1].name" \"\'b\"
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].name" '"T"'
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].kind.lifetime.outlives" []
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.params[1].kind.lifetime.outlives" [\"\'a\"]
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].kind.type.default" null
+// @count "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].kind.type.bounds[*]" 1
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].kind.type.bounds[0].outlives" \"\'b\"
+// @is "$.index[*][?(@.name=='foo')].inner.function.decl.inputs[0][1].borrowed_ref.lifetime" \"\'a\"
+// @is "$.index[*][?(@.name=='foo')].inner.function.decl.inputs[0][1].borrowed_ref.mutable" false
+// @is "$.index[*][?(@.name=='foo')].inner.function.decl.inputs[0][1].borrowed_ref.type.borrowed_ref.lifetime" \"\'b\"
+// @is "$.index[*][?(@.name=='foo')].inner.function.decl.inputs[0][1].borrowed_ref.type.borrowed_ref.mutable" false
+// @is "$.index[*][?(@.name=='foo')].inner.function.decl.inputs[0][1].borrowed_ref.type.borrowed_ref.type.generic" \"T\"
 pub fn foo<'a, 'b: 'a, T: 'b>(_: &'a &'b T) {}
diff --git a/tests/rustdoc-json/methods/abi.rs b/tests/rustdoc-json/methods/abi.rs
index fd03d92d65b..b8279298c1e 100644
--- a/tests/rustdoc-json/methods/abi.rs
+++ b/tests/rustdoc-json/methods/abi.rs
@@ -8,47 +8,47 @@
 pub struct Foo;
 
 impl Foo {
-    // @is "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
+    // @is "$.index[*][?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\"
     pub fn abi_rust() {}
 
-    // @is "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+    // @is "$.index[*][?(@.name=='abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}'
     pub extern "C" fn abi_c() {}
 
-    // @is "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+    // @is "$.index[*][?(@.name=='abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}'
     pub extern "system" fn abi_system() {}
 
-    // @is "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+    // @is "$.index[*][?(@.name=='abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}'
     pub extern "C-unwind" fn abi_c_unwind() {}
 
-    // @is "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+    // @is "$.index[*][?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}'
     pub extern "system-unwind" fn abi_system_unwind() {}
 
-    // @is "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+    // @is "$.index[*][?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""'
     pub extern "vectorcall" fn abi_vectorcall() {}
 
-    // @is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+    // @is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""'
     pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {}
 }
 
 pub trait Bar {
-    // @is "$.index[*][?(@.name=='trait_abi_rust')].inner.header.abi" \"Rust\"
+    // @is "$.index[*][?(@.name=='trait_abi_rust')].inner.function.header.abi" \"Rust\"
     fn trait_abi_rust() {}
 
-    // @is "$.index[*][?(@.name=='trait_abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+    // @is "$.index[*][?(@.name=='trait_abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}'
     extern "C" fn trait_abi_c() {}
 
-    // @is "$.index[*][?(@.name=='trait_abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+    // @is "$.index[*][?(@.name=='trait_abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}'
     extern "system" fn trait_abi_system() {}
 
-    // @is "$.index[*][?(@.name=='trait_abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+    // @is "$.index[*][?(@.name=='trait_abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}'
     extern "C-unwind" fn trait_abi_c_unwind() {}
 
-    // @is "$.index[*][?(@.name=='trait_abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+    // @is "$.index[*][?(@.name=='trait_abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}'
     extern "system-unwind" fn trait_abi_system_unwind() {}
 
-    // @is "$.index[*][?(@.name=='trait_abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+    // @is "$.index[*][?(@.name=='trait_abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""'
     extern "vectorcall" fn trait_abi_vectorcall() {}
 
-    // @is "$.index[*][?(@.name=='trait_abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+    // @is "$.index[*][?(@.name=='trait_abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""'
     extern "vectorcall-unwind" fn trait_abi_vectorcall_unwind() {}
 }
diff --git a/tests/rustdoc-json/methods/qualifiers.rs b/tests/rustdoc-json/methods/qualifiers.rs
index b9a5e56012e..65977bc826f 100644
--- a/tests/rustdoc-json/methods/qualifiers.rs
+++ b/tests/rustdoc-json/methods/qualifiers.rs
@@ -3,34 +3,34 @@
 pub struct Foo;
 
 impl Foo {
-    // @is "$.index[*][?(@.name=='const_meth')].inner.header.async" false
-    // @is "$.index[*][?(@.name=='const_meth')].inner.header.const"  true
-    // @is "$.index[*][?(@.name=='const_meth')].inner.header.unsafe" false
+    // @is "$.index[*][?(@.name=='const_meth')].inner.function.header.async" false
+    // @is "$.index[*][?(@.name=='const_meth')].inner.function.header.const"  true
+    // @is "$.index[*][?(@.name=='const_meth')].inner.function.header.unsafe" false
     pub const fn const_meth() {}
 
-    // @is "$.index[*][?(@.name=='nothing_meth')].inner.header.async"  false
-    // @is "$.index[*][?(@.name=='nothing_meth')].inner.header.const"  false
-    // @is "$.index[*][?(@.name=='nothing_meth')].inner.header.unsafe" false
+    // @is "$.index[*][?(@.name=='nothing_meth')].inner.function.header.async"  false
+    // @is "$.index[*][?(@.name=='nothing_meth')].inner.function.header.const"  false
+    // @is "$.index[*][?(@.name=='nothing_meth')].inner.function.header.unsafe" false
     pub fn nothing_meth() {}
 
-    // @is "$.index[*][?(@.name=='unsafe_meth')].inner.header.async"  false
-    // @is "$.index[*][?(@.name=='unsafe_meth')].inner.header.const"  false
-    // @is "$.index[*][?(@.name=='unsafe_meth')].inner.header.unsafe" true
+    // @is "$.index[*][?(@.name=='unsafe_meth')].inner.function.header.async"  false
+    // @is "$.index[*][?(@.name=='unsafe_meth')].inner.function.header.const"  false
+    // @is "$.index[*][?(@.name=='unsafe_meth')].inner.function.header.unsafe" true
     pub unsafe fn unsafe_meth() {}
 
-    // @is "$.index[*][?(@.name=='async_meth')].inner.header.async"  true
-    // @is "$.index[*][?(@.name=='async_meth')].inner.header.const"  false
-    // @is "$.index[*][?(@.name=='async_meth')].inner.header.unsafe" false
+    // @is "$.index[*][?(@.name=='async_meth')].inner.function.header.async"  true
+    // @is "$.index[*][?(@.name=='async_meth')].inner.function.header.const"  false
+    // @is "$.index[*][?(@.name=='async_meth')].inner.function.header.unsafe" false
     pub async fn async_meth() {}
 
-    // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.async"  true
-    // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.const"  false
-    // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.unsafe" true
+    // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.function.header.async"  true
+    // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.function.header.const"  false
+    // @is "$.index[*][?(@.name=='async_unsafe_meth')].inner.function.header.unsafe" true
     pub async unsafe fn async_unsafe_meth() {}
 
-    // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.async"  false
-    // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.const"  true
-    // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.unsafe" true
+    // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.function.header.async"  false
+    // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.function.header.const"  true
+    // @is "$.index[*][?(@.name=='const_unsafe_meth')].inner.function.header.unsafe" true
     pub const unsafe fn const_unsafe_meth() {}
 
     // It's impossible for a method to be both const and async, so no test for that
diff --git a/tests/rustdoc-json/nested.rs b/tests/rustdoc-json/nested.rs
index ee2d2efa960..e012cfc5014 100644
--- a/tests/rustdoc-json/nested.rs
+++ b/tests/rustdoc-json/nested.rs
@@ -2,30 +2,31 @@
 // compile-flags: --crate-version 1.0.0
 
 // @is "$.crate_version" \"1.0.0\"
-// @is "$.index[*][?(@.name=='nested')].kind" \"module\"
-// @is "$.index[*][?(@.name=='nested')].inner.is_crate" true
+// @has "$.index[*][?(@.name=='nested')].inner.module"
+// @is "$.index[*][?(@.name=='nested')].inner.module.is_crate" true
 
 // @set l1_id = "$.index[*][?(@.name=='l1')].id"
-// @ismany "$.index[*][?(@.name=='nested')].inner.items[*]" $l1_id
+// @ismany "$.index[*][?(@.name=='nested')].inner.module.items[*]" $l1_id
 
-// @is "$.index[*][?(@.name=='l1')].kind" \"module\"
-// @is "$.index[*][?(@.name=='l1')].inner.is_crate" false
+// @has "$.index[*][?(@.name=='l1')].inner.module"
+// @is "$.index[*][?(@.name=='l1')].inner.module.is_crate" false
 pub mod l1 {
-    // @is "$.index[*][?(@.name=='l3')].kind" \"module\"
-    // @is "$.index[*][?(@.name=='l3')].inner.is_crate" false
+    // @has "$.index[*][?(@.name=='l3')].inner.module"
+    // @is "$.index[*][?(@.name=='l3')].inner.module.is_crate" false
     // @set l3_id = "$.index[*][?(@.name=='l3')].id"
     pub mod l3 {
 
-        // @is "$.index[*][?(@.name=='L4')].kind" \"struct\"
-        // @is "$.index[*][?(@.name=='L4')].inner.kind" \"unit\"
+        // @has "$.index[*][?(@.name=='L4')].inner.struct"
+        // @is "$.index[*][?(@.name=='L4')].inner.struct.kind" '"unit"'
         // @set l4_id = "$.index[*][?(@.name=='L4')].id"
-        // @ismany "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
+        // @ismany "$.index[*][?(@.name=='l3')].inner.module.items[*]" $l4_id
         pub struct L4;
     }
-    // @is "$.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"
+    // @is "$.index[*][?(@.inner.import)].inner.import.glob" false
+    // @is "$.index[*][?(@.inner.import)].inner.import.source" '"l3::L4"'
+    // @is "$.index[*][?(@.inner.import)].inner.import.glob" false
+    // @is "$.index[*][?(@.inner.import)].inner.import.id" $l4_id
+    // @set l4_use_id = "$.index[*][?(@.inner.import)].id"
     pub use l3::L4;
 }
-// @ismany "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id $l4_use_id
+// @ismany "$.index[*][?(@.name=='l1')].inner.module.items[*]" $l3_id $l4_use_id
diff --git a/tests/rustdoc-json/non_lifetime_binders.rs b/tests/rustdoc-json/non_lifetime_binders.rs
index ca5a008344a..cabee0b1caa 100644
--- a/tests/rustdoc-json/non_lifetime_binders.rs
+++ b/tests/rustdoc-json/non_lifetime_binders.rs
@@ -16,9 +16,9 @@ struct PhantomData<T_>;
 
 pub struct Wrapper<T_>(PhantomData<T_>);
 
-// @count "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[*]" 2
-// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\"
-// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
-// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\"
-// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "synthetic": false } }'
+// @count "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[*]" 2
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\"
+// @is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "synthetic": false } }'
 pub fn foo() where for<'a, T> &'a Wrapper<T>: Trait {}
diff --git a/tests/rustdoc-json/primitives/local_primitive.rs b/tests/rustdoc-json/primitives/local_primitive.rs
index 0cf479faf29..562c7e4d79b 100644
--- a/tests/rustdoc-json/primitives/local_primitive.rs
+++ b/tests/rustdoc-json/primitives/local_primitive.rs
@@ -14,7 +14,7 @@ mod prim_i32 {}
 // @set local_i32 = "$.index[*][?(@.name=='i32')].id"
 
 // @has "$.index[*][?(@.name=='local_primitive')]"
-// @ismany "$.index[*][?(@.name=='local_primitive')].inner.items[*]" $local_i32
+// @ismany "$.index[*][?(@.name=='local_primitive')].inner.module.items[*]" $local_i32
 // @is "$.index[*][?(@.name=='local_primitive')].links['prim@i32']" $local_i32
 
 // Let's ensure the `prim_i32` module isn't present in the output JSON:
diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs
index 85d179ee45f..4b7b7646b89 100644
--- a/tests/rustdoc-json/primitives/primitive_impls.rs
+++ b/tests/rustdoc-json/primitives/primitive_impls.rs
@@ -15,7 +15,7 @@ impl i32 {
         self
     }
 
-    // @is "$.index[*][?(@.docs=='Only core can do this')].inner.items[*]" $identity
+    // @is "$.index[*][?(@.docs=='Only core can do this')].inner.impl.items[*]" $identity
 }
 
 // @set Trait = "$.index[*][?(@.name=='Trait')].id"
@@ -30,5 +30,5 @@ mod prim_i32 {}
 
 // @set i32 = "$.index[*][?(@.docs=='i32')].id"
 // @is "$.index[*][?(@.docs=='i32')].name" '"i32"'
-// @is "$.index[*][?(@.docs=='i32')].inner.name" '"i32"'
-// @ismany "$.index[*][?(@.docs=='i32')].inner.impls[*]" $impl_i32 $impl_trait_for_i32
+// @is "$.index[*][?(@.docs=='i32')].inner.primitive.name" '"i32"'
+// @ismany "$.index[*][?(@.docs=='i32')].inner.primitive.impls[*]" $impl_i32 $impl_trait_for_i32
diff --git a/tests/rustdoc-json/primitives/primitive_type.rs b/tests/rustdoc-json/primitives/primitive_type.rs
index 8024044bc05..5f251b3b890 100644
--- a/tests/rustdoc-json/primitives/primitive_type.rs
+++ b/tests/rustdoc-json/primitives/primitive_type.rs
@@ -1,22 +1,17 @@
 #![feature(never_type)]
 
 // @is "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
-// @is "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
+// @is "$.index[*][?(@.name=='PrimNever')].inner.typedef.type.primitive" \"never\"
 pub type PrimNever = !;
 
-// @is "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
-// @is "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
+// @is "$.index[*][?(@.name=='PrimStr')].inner.typedef.type.primitive" \"str\"
 pub type PrimStr = str;
 
-// @is "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
-// @is "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
+// @is "$.index[*][?(@.name=='PrimBool')].inner.typedef.type.primitive" \"bool\"
 pub type PrimBool = bool;
 
-// @is "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
-// @is "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
+// @is "$.index[*][?(@.name=='PrimChar')].inner.typedef.type.primitive" \"char\"
 pub type PrimChar = char;
 
-// @is "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
-// @is "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
+// @is "$.index[*][?(@.name=='PrimU8')].inner.typedef.type.primitive" \"u8\"
 pub type PrimU8 = u8;
diff --git a/tests/rustdoc-json/primitives/use_primitive.rs b/tests/rustdoc-json/primitives/use_primitive.rs
index 5180a804f07..f8118b82094 100644
--- a/tests/rustdoc-json/primitives/use_primitive.rs
+++ b/tests/rustdoc-json/primitives/use_primitive.rs
@@ -13,8 +13,8 @@ mod usize {}
 // @!is "$.index[*][?(@.name=='checked_add')]" $local_crate_id
 // @!has "$.index[*][?(@.name=='is_ascii_uppercase')]"
 
-// @is "$.index[*][?(@.kind=='import' && @.inner.name=='my_i32')].inner.id" null
+// @is "$.index[*].inner.import[?(@.name=='my_i32')].id" null
 pub use i32 as my_i32;
 
-// @is "$.index[*][?(@.kind=='import' && @.inner.name=='u32')].inner.id" null
+// @is "$.index[*].inner.import[?(@.name=='u32')].id" null
 pub use u32;
diff --git a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs
index 40b681d7dbb..1c5fed8c6b2 100644
--- a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs
+++ b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs
@@ -1,10 +1,11 @@
 // Regression Test for https://github.com/rust-lang/rust/issues/110138
 // aux-build: enum_with_discriminant.rs
+// ignore-tidy-linelength
 
 #[doc(inline)]
 pub extern crate enum_with_discriminant;
 
 // @!has '$.index[*][?(@.docs == "Should not be inlined")]'
-// @is '$.index[*][?(@.name == "enum_with_discriminant")].kind' '"extern_crate"'
+// @has '$.index[*][?(@.name == "enum_with_discriminant")].inner.extern_crate'
 // @set enum_with_discriminant = '$.index[*][?(@.name == "enum_with_discriminant")].id'
-// @is '$.index[*][?(@.name == "doc_inline_external_crate")].inner.items[*]' $enum_with_discriminant
+// @is '$.index[*][?(@.name == "doc_inline_external_crate")].inner.module.items[*]' $enum_with_discriminant
diff --git a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs
index f076feb7185..37ca279b352 100644
--- a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs
+++ b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs
@@ -7,5 +7,5 @@
 
 // ignore-tidy-linelength
 
-// @is "$.index[*][?(@.kind=='module')].name" \"export_extern_crate_as_self\"
+// @is "$.index[*][?(@.inner.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/tests/rustdoc-json/reexport/extern_crate_glob.rs b/tests/rustdoc-json/reexport/extern_crate_glob.rs
index 8efb94fd3f1..553ee79b44e 100644
--- a/tests/rustdoc-json/reexport/extern_crate_glob.rs
+++ b/tests/rustdoc-json/reexport/extern_crate_glob.rs
@@ -6,5 +6,6 @@ extern crate enum_with_discriminant;
 pub use enum_with_discriminant::*;
 
 // @!has '$.index[*][?(@.docs == "Should not be inlined")]'
-// @set use = '$.index[*][?(@.inner.name == "enum_with_discriminant")].id'
-// @is '$.index[*][?(@.name == "extern_crate_glob")].inner.items[*]' $use
+// @is '$.index[*][?(@.inner.import)].inner.import.name' \"enum_with_discriminant\"
+// @set use = '$.index[*][?(@.inner.import)].id'
+// @is '$.index[*][?(@.name == "extern_crate_glob")].inner.module.items[*]' $use
diff --git a/tests/rustdoc-json/reexport/glob_collision.rs b/tests/rustdoc-json/reexport/glob_collision.rs
index f91144dbfad..dee35ba78dc 100644
--- a/tests/rustdoc-json/reexport/glob_collision.rs
+++ b/tests/rustdoc-json/reexport/glob_collision.rs
@@ -3,26 +3,28 @@
 #![feature(no_core)]
 #![no_core]
 
-// @set m1 = "$.index[*][?(@.name == 'm1' && @.kind == 'module')].id"
-// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.items" []
-// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.is_stripped" true
+// @set m1 = "$.index[*][?(@.name == 'm1' && @.inner.module)].id"
+// @is "$.index[*][?(@.name == 'm1')].inner.module.items" []
+// @is "$.index[*][?(@.name == 'm1')].inner.module.is_stripped" true
 mod m1 {
     pub fn f() {}
 }
-// @set m2 = "$.index[*][?(@.name == 'm2' && @.kind == 'module')].id"
-// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.items" []
-// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.is_stripped" true
+// @set m2 = "$.index[*][?(@.name == 'm2' && @.inner.module)].id"
+// @is "$.index[*][?(@.name == 'm2')].inner.module.items" []
+// @is "$.index[*][?(@.name == 'm2')].inner.module.is_stripped" true
 mod m2 {
     pub fn f(_: u8) {}
 }
 
-// @set m1_use = "$.index[*][?(@.inner.name=='m1')].id"
-// @is "$.index[*][?(@.inner.name=='m1')].inner.id" $m1
-// @is "$.index[*][?(@.inner.name=='m1')].inner.glob" true
+// @set m1_use = "$.index[*][?(@.docs=='m1 re-export')].id"
+// @is "$.index[*].inner.import[?(@.name=='m1')].id" $m1
+// @is "$.index[*].inner.import[?(@.name=='m1')].glob" true
+/// m1 re-export
 pub use m1::*;
-// @set m2_use = "$.index[*][?(@.inner.name=='m2')].id"
-// @is "$.index[*][?(@.inner.name=='m2')].inner.id" $m2
-// @is "$.index[*][?(@.inner.name=='m2')].inner.glob" true
+// @set m2_use = "$.index[*][?(@.docs=='m2 re-export')].id"
+// @is "$.index[*].inner.import[?(@.name=='m2')].id" $m2
+// @is "$.index[*].inner.import[?(@.name=='m2')].glob" true
+/// m2 re-export
 pub use m2::*;
 
-// @ismany "$.index[*][?(@.inner.is_crate==true)].inner.items[*]" $m1_use $m2_use
+// @ismany "$.index[*].inner.module[?(@.is_crate==true)].items[*]" $m1_use $m2_use
diff --git a/tests/rustdoc-json/reexport/glob_empty_mod.rs b/tests/rustdoc-json/reexport/glob_empty_mod.rs
index da68228352c..8b7150c8fd7 100644
--- a/tests/rustdoc-json/reexport/glob_empty_mod.rs
+++ b/tests/rustdoc-json/reexport/glob_empty_mod.rs
@@ -1,8 +1,8 @@
 // Regression test for https://github.com/rust-lang/rust/issues/100973
 
-// @is "$.index[*][?(@.name=='m1' && @.kind == 'module')].inner.is_stripped" true
+// @is "$.index[*][?(@.name=='m1' && @.inner.module)].inner.module.is_stripped" true
 // @set m1 = "$.index[*][?(@.name=='m1')].id"
 mod m1 {}
 
-// @is "$.index[*][?(@.inner.name=='m1' && @.kind=='import')].inner.id" $m1
+// @is "$.index[*][?(@.inner.import)].inner.import.id" $m1
 pub use m1::*;
diff --git a/tests/rustdoc-json/reexport/glob_extern.rs b/tests/rustdoc-json/reexport/glob_extern.rs
index 7a1e8c11ffa..78edfaf0aa8 100644
--- a/tests/rustdoc-json/reexport/glob_extern.rs
+++ b/tests/rustdoc-json/reexport/glob_extern.rs
@@ -3,8 +3,7 @@
 #![no_core]
 #![feature(no_core)]
 
-// @is "$.index[*][?(@.name=='mod1')].kind" \"module\"
-// @is "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+// @is "$.index[*][?(@.name=='mod1')].inner.module.is_stripped" "true"
 mod mod1 {
     extern "C" {
         // @set public_fn_id = "$.index[*][?(@.name=='public_fn')].id"
@@ -12,12 +11,12 @@ mod mod1 {
         // @!has "$.index[*][?(@.name=='private_fn')]"
         fn private_fn();
     }
-    // @ismany "$.index[*][?(@.name=='mod1')].inner.items[*]" $public_fn_id
+    // @ismany "$.index[*][?(@.name=='mod1')].inner.module.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
+// @is "$.index[*][?(@.inner.import)].inner.import.glob" true
+// @is "$.index[*][?(@.inner.import)].inner.import.id" $mod1_id
+// @set use_id = "$.index[*][?(@.inner.import)].id"
+// @ismany "$.index[*][?(@.name=='glob_extern')].inner.module.items[*]" $use_id
 pub use mod1::*;
diff --git a/tests/rustdoc-json/reexport/glob_private.rs b/tests/rustdoc-json/reexport/glob_private.rs
index 3a83a20818b..ae4e87d23bc 100644
--- a/tests/rustdoc-json/reexport/glob_private.rs
+++ b/tests/rustdoc-json/reexport/glob_private.rs
@@ -3,11 +3,9 @@
 #![no_core]
 #![feature(no_core)]
 
-// @is "$.index[*][?(@.name=='mod1')].kind" \"module\"
-// @is "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+// @is "$.index[*][?(@.name=='mod1')].inner.module.is_stripped" "true"
 mod mod1 {
-    // @is "$.index[*][?(@.name=='mod2')].kind" \"module\"
-    // @is "$.index[*][?(@.name=='mod2')].inner.is_stripped" "true"
+    // @is "$.index[*][?(@.name=='mod2')].inner.module.is_stripped" "true"
     mod mod2 {
         // @set m2pub_id = "$.index[*][?(@.name=='Mod2Public')].id"
         pub struct Mod2Public;
@@ -16,7 +14,9 @@ mod mod1 {
         struct Mod2Private;
     }
 
-    // @set mod2_use_id = "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')].id"
+    // @set mod2_use_id = "$.index[*][?(@.docs=='Mod2 re-export')].id"
+    // @is "$.index[*][?(@.docs=='Mod2 re-export')].inner.import.name" \"mod2\"
+    /// Mod2 re-export
     pub use self::mod2::*;
 
     // @set m1pub_id = "$.index[*][?(@.name=='Mod1Public')].id"
@@ -25,9 +25,11 @@ mod mod1 {
     struct Mod1Private;
 }
 
-// @set mod1_use_id = "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')].id"
+// @set mod1_use_id = "$.index[*][?(@.docs=='Mod1 re-export')].id"
+// @is "$.index[*][?(@.docs=='Mod1 re-export')].inner.import.name" \"mod1\"
+/// Mod1 re-export
 pub use mod1::*;
 
-// @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
+// @ismany "$.index[*][?(@.name=='mod2')].inner.module.items[*]" $m2pub_id
+// @ismany "$.index[*][?(@.name=='mod1')].inner.module.items[*]" $m1pub_id $mod2_use_id
+// @ismany "$.index[*][?(@.name=='glob_private')].inner.module.items[*]" $mod1_use_id
diff --git a/tests/rustdoc-json/reexport/in_root_and_mod.rs b/tests/rustdoc-json/reexport/in_root_and_mod.rs
index 7b97ebf2129..f81445bd48d 100644
--- a/tests/rustdoc-json/reexport/in_root_and_mod.rs
+++ b/tests/rustdoc-json/reexport/in_root_and_mod.rs
@@ -7,10 +7,10 @@ mod foo {
     pub struct Foo;
 }
 
-// @has "$.index[*][?(@.kind=='import' && @.inner.source=='foo::Foo')]"
+// @has "$.index[*].inner[?(@.import.source=='foo::Foo')]"
 pub use foo::Foo;
 
 pub mod bar {
-    // @has "$.index[*][?(@.kind=='import' && @.inner.source=='crate::foo::Foo')]"
+    // @has "$.index[*].inner[?(@.import.source=='crate::foo::Foo')]"
     pub use crate::foo::Foo;
 }
diff --git a/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs b/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs
index f6d932d927b..c5c41b25f7e 100644
--- a/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs
+++ b/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs
@@ -3,18 +3,20 @@
 
 pub mod foo {
     // @set bar_id = "$.index[*][?(@.name=='Bar')].id"
-    // @ismany "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
+    // @ismany "$.index[*][?(@.name=='foo')].inner.module.items[*]" $bar_id
     pub struct Bar;
 }
 
-// @set root_import_id = "$.index[*][?(@.inner.source=='foo::Bar')].id"
-// @is "$.index[*][?(@.inner.source=='foo::Bar')].inner.id" $bar_id
-// @has "$.index[*][?(@.name=='in_root_and_mod_pub')].inner.items[*]" $root_import_id
+// @set root_import_id = "$.index[*][?(@.docs=='Outer re-export')].id"
+// @is "$.index[*].inner[?(@.import.source=='foo::Bar')].import.id" $bar_id
+// @has "$.index[*][?(@.name=='in_root_and_mod_pub')].inner.module.items[*]" $root_import_id
+/// Outer re-export
 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
-    // @ismany "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
+    // @set baz_import_id = "$.index[*][?(@.docs=='Inner re-export')].id"
+    // @is "$.index[*].inner[?(@.import.source=='crate::foo::Bar')].import.id" $bar_id
+    // @ismany "$.index[*][?(@.name=='baz')].inner.module.items[*]" $baz_import_id
+    /// Inner re-export
     pub use crate::foo::Bar;
 }
diff --git a/tests/rustdoc-json/reexport/macro.rs b/tests/rustdoc-json/reexport/macro.rs
index b4882100f06..ac0632b98a9 100644
--- a/tests/rustdoc-json/reexport/macro.rs
+++ b/tests/rustdoc-json/reexport/macro.rs
@@ -9,7 +9,8 @@ macro_rules! repro {
     () => {};
 }
 
-// @set repro2_id = "$.index[*][?(@.inner.name=='repro2')].id"
+// @set repro2_id = "$.index[*][?(@.docs=='Re-export')].id"
+/// Re-export
 pub use crate::repro as repro2;
 
-// @ismany "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id $repro2_id
+// @ismany "$.index[*][?(@.name=='macro')].inner.module.items[*]" $repro_id $repro2_id
diff --git a/tests/rustdoc-json/reexport/mod_not_included.rs b/tests/rustdoc-json/reexport/mod_not_included.rs
index 7b7600ef20f..1c49f213d1a 100644
--- a/tests/rustdoc-json/reexport/mod_not_included.rs
+++ b/tests/rustdoc-json/reexport/mod_not_included.rs
@@ -9,6 +9,6 @@ mod m1 {
 
 pub use m1::x;
 
-// @has "$.index[*][?(@.name=='x' && @.kind=='function')]"
-// @has "$.index[*][?(@.kind=='import' && @.inner.name=='x')].inner.source" '"m1::x"'
+// @has "$.index[*][?(@.name=='x' && @.inner.function)]"
+// @has "$.index[*].inner[?(@.import.name=='x')].import.source" '"m1::x"'
 // @!has "$.index[*][?(@.name=='m1')]"
diff --git a/tests/rustdoc-json/reexport/private_twice_one_inline.rs b/tests/rustdoc-json/reexport/private_twice_one_inline.rs
index 687a3b2ac8b..8c8152bd16c 100644
--- a/tests/rustdoc-json/reexport/private_twice_one_inline.rs
+++ b/tests/rustdoc-json/reexport/private_twice_one_inline.rs
@@ -11,18 +11,18 @@ extern crate pub_struct as foo;
 #[doc(inline)]
 
 // @set crate_use_id = "$.index[*][?(@.docs=='Hack A')].id"
-// @set foo_id = "$.index[*][?(@.docs=='Hack A')].inner.id"
+// @set foo_id = "$.index[*][?(@.docs=='Hack A')].inner.import.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
+    // @is "$.index[*][?(@.docs=='Hack B')].inner.import.id" $foo_id
     // @set bar_use_id = "$.index[*][?(@.docs=='Hack B')].id"
-    // @ismany "$.index[*][?(@.name=='bar')].inner.items[*]" $bar_use_id
+    // @ismany "$.index[*][?(@.name=='bar')].inner.module.items[*]" $bar_use_id
     /// Hack B
     pub use foo::Foo;
 }
 
-// @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
+// @ismany "$.index[*][?(@.inner.import)].id" $crate_use_id $bar_use_id
+// @ismany "$.index[*][?(@.name=='private_twice_one_inline')].inner.module.items[*]" $bar_id $crate_use_id
diff --git a/tests/rustdoc-json/reexport/private_two_names.rs b/tests/rustdoc-json/reexport/private_two_names.rs
index 9858538a9d0..cdcbf2a2bc8 100644
--- a/tests/rustdoc-json/reexport/private_two_names.rs
+++ b/tests/rustdoc-json/reexport/private_two_names.rs
@@ -8,15 +8,19 @@
 
 // @!has "$.index[*][?(@.name=='style')]"
 mod style {
-    // @set color_struct_id = "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
+    // @set color_struct_id = "$.index[*][?(@.inner.struct && @.name=='Color')].id"
     pub struct Color;
 }
 
-// @is "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].inner.id" $color_struct_id
-// @set color_export_id = "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].id"
+// @is "$.index[*][?(@.docs=='First re-export')].inner.import.id" $color_struct_id
+// @is "$.index[*][?(@.docs=='First re-export')].inner.import.name" \"Color\"
+// @set color_export_id = "$.index[*][?(@.docs=='First re-export')].id"
+/// First re-export
 pub use style::Color;
-// @is "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].inner.id" $color_struct_id
-// @set colour_export_id = "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].id"
+// @is "$.index[*][?(@.docs=='Second re-export')].inner.import.id" $color_struct_id
+// @is "$.index[*][?(@.docs=='Second re-export')].inner.import.name" \"Colour\"
+// @set colour_export_id = "$.index[*][?(@.docs=='Second re-export')].id"
+/// Second re-export
 pub use style::Color as Colour;
 
-// @ismany "$.index[*][?(@.name=='private_two_names')].inner.items[*]" $color_export_id $colour_export_id
+// @ismany "$.index[*][?(@.name=='private_two_names')].inner.module.items[*]" $color_export_id $colour_export_id
diff --git a/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs b/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs
index 239b1a23b43..61075088af9 100644
--- a/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs
+++ b/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs
@@ -1,9 +1,9 @@
 // Regression test for <https://github.com/rust-lang/rust/issues/102583>.
 
 // @set impl_S = "$.index[*][?(@.docs=='impl S')].id"
-// @has "$.index[*][?(@.name=='S')].inner.impls[*]" $impl_S
+// @has "$.index[*][?(@.name=='S')].inner.struct.impls[*]" $impl_S
 // @set is_present = "$.index[*][?(@.name=='is_present')].id"
-// @is "$.index[*][?(@.docs=='impl S')].inner.items[*]" $is_present
+// @is "$.index[*][?(@.docs=='impl S')].inner.impl.items[*]" $is_present
 // @!has "$.index[*][?(@.name=='hidden_impl')]"
 // @!has "$.index[*][?(@.name=='hidden_fn')]"
 
diff --git a/tests/rustdoc-json/reexport/rename_private.rs b/tests/rustdoc-json/reexport/rename_private.rs
index 8fd850f9b13..9114460231d 100644
--- a/tests/rustdoc-json/reexport/rename_private.rs
+++ b/tests/rustdoc-json/reexport/rename_private.rs
@@ -3,11 +3,11 @@
 #![no_core]
 #![feature(no_core)]
 
-// @!has "$.index[*][?(@.kind=='inner')]"
+// @!has "$.index[*][?(@.name=='inner')]"
 mod inner {
     // @has "$.index[*][?(@.name=='Public')]"
     pub struct Public;
 }
 
-// @is "$.index[*][?(@.kind=='import')].inner.name" \"NewName\"
+// @is "$.index[*][?(@.inner.import)].inner.import.name" \"NewName\"
 pub use inner::Public as NewName;
diff --git a/tests/rustdoc-json/reexport/rename_public.rs b/tests/rustdoc-json/reexport/rename_public.rs
index e30907fe256..d0fd314bd8c 100644
--- a/tests/rustdoc-json/reexport/rename_public.rs
+++ b/tests/rustdoc-json/reexport/rename_public.rs
@@ -6,12 +6,13 @@
 // @set inner_id = "$.index[*][?(@.name=='inner')].id"
 pub mod inner {
     // @set public_id = "$.index[*][?(@.name=='Public')].id"
-    // @ismany "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+    // @ismany "$.index[*][?(@.name=='inner')].inner.module.items[*]" $public_id
     pub struct Public;
 }
-// @set import_id = "$.index[*][?(@.inner.name=='NewName')].id"
-// @!has "$.index[*][?(@.inner.name=='Public')]"
-// @is "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
+// @set import_id = "$.index[*][?(@.docs=='Re-export')].id"
+// @!has "$.index[*].inner[?(@.import.name=='Public')]"
+// @is "$.index[*].inner[?(@.import.name=='NewName')].import.source" \"inner::Public\"
+/// Re-export
 pub use inner::Public as NewName;
 
-// @ismany "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id $import_id
+// @ismany "$.index[*][?(@.name=='rename_public')].inner.module.items[*]" $inner_id $import_id
diff --git a/tests/rustdoc-json/reexport/same_name_different_types.rs b/tests/rustdoc-json/reexport/same_name_different_types.rs
index 2314a4eb909..6a765b73301 100644
--- a/tests/rustdoc-json/reexport/same_name_different_types.rs
+++ b/tests/rustdoc-json/reexport/same_name_different_types.rs
@@ -16,10 +16,10 @@ pub mod nested {
     pub fn Foo() {}
 }
 
-// @ismany "$.index[*][?(@.inner.name == 'Foo' && @.kind == 'import')].inner.id" $foo_fn $foo_struct
-// @ismany "$.index[*][?(@.inner.name == 'Bar' && @.kind == 'import')].inner.id" $foo_fn $foo_struct
+// @ismany "$.index[*].inner[?(@.import.name == 'Foo')].import.id" $foo_fn $foo_struct
+// @ismany "$.index[*].inner[?(@.import.name == 'Bar')].import.id" $foo_fn $foo_struct
 
-// @count "$.index[*][?(@.inner.name == 'Foo' && @.kind == 'import')]" 2
+// @count "$.index[*].inner[?(@.import.name == 'Foo')]" 2
 pub use nested::Foo;
-// @count "$.index[*][?(@.inner.name == 'Bar' && @.kind == 'import')]" 2
+// @count "$.index[*].inner[?(@.import.name == 'Bar')]" 2
 pub use Foo as Bar;
diff --git a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
index 880dbdc4416..a00547dc348 100644
--- a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
+++ b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
@@ -11,11 +11,13 @@ mod inner {
     pub trait Trait {}
 }
 
-// @set export_id = "$.index[*][?(@.inner.name=='Trait')].id"
-// @is "$.index[*][?(@.inner.name=='Trait')].inner.id" $trait_id
+// @set export_id = "$.index[*][?(@.docs=='First re-export')].id"
+// @is "$.index[*].inner[?(@.import.name=='Trait')].import.id" $trait_id
+/// First re-export
 pub use inner::Trait;
-// @set reexport_id = "$.index[*][?(@.inner.name=='Reexport')].id"
-// @is "$.index[*][?(@.inner.name=='Reexport')].inner.id" $trait_id
+// @set reexport_id = "$.index[*][?(@.docs=='Second re-export')].id"
+// @is "$.index[*].inner[?(@.import.name=='Reexport')].import.id" $trait_id
+/// Second re-export
 pub use inner::Trait as Reexport;
 
-// @ismany "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.items[*]" $reexport_id $export_id
+// @ismany "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.module.items[*]" $reexport_id $export_id
diff --git a/tests/rustdoc-json/reexport/simple_private.rs b/tests/rustdoc-json/reexport/simple_private.rs
index d058ce0598d..462efee51bf 100644
--- a/tests/rustdoc-json/reexport/simple_private.rs
+++ b/tests/rustdoc-json/reexport/simple_private.rs
@@ -8,9 +8,9 @@ mod inner {
     pub struct Public;
 }
 
-// @is "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
-// @is "$.index[*][?(@.kind=='import')].inner.id" $pub_id
-// @set use_id = "$.index[*][?(@.kind=='import')].id"
+// @is "$.index[*][?(@.inner.import)].inner.import.name" \"Public\"
+// @is "$.index[*][?(@.inner.import)].inner.import.id" $pub_id
+// @set use_id = "$.index[*][?(@.inner.import)].id"
 pub use inner::Public;
 
-// @ismany "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id
+// @ismany "$.index[*][?(@.name=='simple_private')].inner.module.items[*]" $use_id
diff --git a/tests/rustdoc-json/reexport/simple_public.rs b/tests/rustdoc-json/reexport/simple_public.rs
index e64a0dcb769..1373f96f87f 100644
--- a/tests/rustdoc-json/reexport/simple_public.rs
+++ b/tests/rustdoc-json/reexport/simple_public.rs
@@ -7,12 +7,13 @@
 pub mod inner {
 
     // @set public_id = "$.index[*][?(@.name=='Public')].id"
-    // @ismany "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+    // @ismany "$.index[*][?(@.name=='inner')].inner.module.items[*]" $public_id
     pub struct Public;
 }
 
-// @set import_id = "$.index[*][?(@.inner.name=='Public')].id"
-// @is "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
+// @set import_id = "$.index[*][?(@.docs=='Outer')].id"
+// @is "$.index[*][?(@.docs=='Outer')].inner.import.source" \"inner::Public\"
+/// Outer
 pub use inner::Public;
 
-// @ismany "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id $inner_id
+// @ismany "$.index[*][?(@.name=='simple_public')].inner.module.items[*]" $import_id $inner_id
diff --git a/tests/rustdoc-json/return_private.rs b/tests/rustdoc-json/return_private.rs
index a8d1fae30df..0ce81b5e59f 100644
--- a/tests/rustdoc-json/return_private.rs
+++ b/tests/rustdoc-json/return_private.rs
@@ -8,8 +8,8 @@ mod secret {
     pub struct Secret;
 }
 
-// @is "$.index[*][?(@.name=='get_secret')].kind" \"function\"
-// @is "$.index[*][?(@.name=='get_secret')].inner.decl.output.inner.name" \"secret::Secret\"
+// @has "$.index[*][?(@.name=='get_secret')].inner.function"
+// @is "$.index[*][?(@.name=='get_secret')].inner.function.decl.output.resolved_path.name" \"secret::Secret\"
 pub fn get_secret() -> secret::Secret {
     secret::Secret
 }
diff --git a/tests/rustdoc-json/structs/plain_all_pub.rs b/tests/rustdoc-json/structs/plain_all_pub.rs
index b86ab93c264..777260100d6 100644
--- a/tests/rustdoc-json/structs/plain_all_pub.rs
+++ b/tests/rustdoc-json/structs/plain_all_pub.rs
@@ -5,7 +5,7 @@ pub struct Demo {
 
 // @set x = "$.index[*][?(@.name=='x')].id"
 // @set y = "$.index[*][?(@.name=='y')].id"
-// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
-// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[1]" $y
-// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 2
-// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" false
+// @is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x
+// @is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[1]" $y
+// @count "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 2
+// @is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields_stripped" false
diff --git a/tests/rustdoc-json/structs/plain_doc_hidden.rs b/tests/rustdoc-json/structs/plain_doc_hidden.rs
index 7800b55a481..1ff4489ef6b 100644
--- a/tests/rustdoc-json/structs/plain_doc_hidden.rs
+++ b/tests/rustdoc-json/structs/plain_doc_hidden.rs
@@ -6,6 +6,6 @@ pub struct Demo {
 
 // @set x = "$.index[*][?(@.name=='x')].id"
 // @!has "$.index[*][?(@.name=='y')].id"
-// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
-// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 1
-// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" true
+// @is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x
+// @count "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 1
+// @is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields_stripped" true
diff --git a/tests/rustdoc-json/structs/plain_empty.rs b/tests/rustdoc-json/structs/plain_empty.rs
index 1d01b8bc14a..c037c0251b9 100644
--- a/tests/rustdoc-json/structs/plain_empty.rs
+++ b/tests/rustdoc-json/structs/plain_empty.rs
@@ -1,5 +1,5 @@
 // @is "$.index[*][?(@.name=='PlainEmpty')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='PlainEmpty')].kind" \"struct\"
-// @is "$.index[*][?(@.name=='PlainEmpty')].inner.kind.plain.fields_stripped" false
-// @is "$.index[*][?(@.name=='PlainEmpty')].inner.kind.plain.fields" []
+// @has "$.index[*][?(@.name=='PlainEmpty')].inner.struct"
+// @is "$.index[*][?(@.name=='PlainEmpty')].inner.struct.kind.plain.fields_stripped" false
+// @is "$.index[*][?(@.name=='PlainEmpty')].inner.struct.kind.plain.fields" []
 pub struct PlainEmpty {}
diff --git a/tests/rustdoc-json/structs/plain_pub_priv.rs b/tests/rustdoc-json/structs/plain_pub_priv.rs
index 9b771224d97..ff061be62d1 100644
--- a/tests/rustdoc-json/structs/plain_pub_priv.rs
+++ b/tests/rustdoc-json/structs/plain_pub_priv.rs
@@ -4,6 +4,6 @@ pub struct Demo {
 }
 
 // @set x = "$.index[*][?(@.name=='x')].id"
-// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
-// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 1
-// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" true
+// @is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x
+// @count "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 1
+// @is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields_stripped" true
diff --git a/tests/rustdoc-json/structs/tuple.rs b/tests/rustdoc-json/structs/tuple.rs
index 6bdb753ee01..16ab95ed271 100644
--- a/tests/rustdoc-json/structs/tuple.rs
+++ b/tests/rustdoc-json/structs/tuple.rs
@@ -1,4 +1,4 @@
 // @is "$.index[*][?(@.name=='Tuple')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='Tuple')].kind" \"struct\"
-// @is "$.index[*][?(@.name=='Tuple')].inner.kind.tuple" '[null, null]'
+// @has "$.index[*][?(@.name=='Tuple')].inner.struct"
+// @is "$.index[*][?(@.name=='Tuple')].inner.struct.kind.tuple" '[null, null]'
 pub struct Tuple(u32, String);
diff --git a/tests/rustdoc-json/structs/tuple_empty.rs b/tests/rustdoc-json/structs/tuple_empty.rs
index 0ad6a89547f..4d4af8558bb 100644
--- a/tests/rustdoc-json/structs/tuple_empty.rs
+++ b/tests/rustdoc-json/structs/tuple_empty.rs
@@ -1,2 +1,2 @@
-// @is "$.index[*][?(@.name=='TupleUnit')].inner.kind.tuple" []
+// @is "$.index[*][?(@.name=='TupleUnit')].inner.struct.kind.tuple" []
 pub struct TupleUnit();
diff --git a/tests/rustdoc-json/structs/tuple_pub_priv.rs b/tests/rustdoc-json/structs/tuple_pub_priv.rs
index 9d5a1d1c8be..a669ba1dfcc 100644
--- a/tests/rustdoc-json/structs/tuple_pub_priv.rs
+++ b/tests/rustdoc-json/structs/tuple_pub_priv.rs
@@ -7,7 +7,7 @@ pub struct Demo(
 
 // @set field = "$.index[*][?(@.docs=='field')].id"
 
-// @is    "$.index[*][?(@.name=='Demo')].inner.kind.tuple[0]" null
-// @is    "$.index[*][?(@.name=='Demo')].inner.kind.tuple[1]" $field
-// @is    "$.index[*][?(@.name=='Demo')].inner.kind.tuple[2]" null
-// @count "$.index[*][?(@.name=='Demo')].inner.kind.tuple[*]" 3
+// @is    "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[0]" null
+// @is    "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[1]" $field
+// @is    "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[2]" null
+// @count "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[*]" 3
diff --git a/tests/rustdoc-json/structs/unit.rs b/tests/rustdoc-json/structs/unit.rs
index 26570971721..640d3fb7865 100644
--- a/tests/rustdoc-json/structs/unit.rs
+++ b/tests/rustdoc-json/structs/unit.rs
@@ -1,4 +1,4 @@
 // @is "$.index[*][?(@.name=='Unit')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='Unit')].kind" \"struct\"
-// @is "$.index[*][?(@.name=='Unit')].inner.kind" \"unit\"
+// @has "$.index[*][?(@.name=='Unit')].inner.struct"
+// @is "$.index[*][?(@.name=='Unit')].inner.struct.kind" \"unit\"
 pub struct Unit;
diff --git a/tests/rustdoc-json/structs/with_generics.rs b/tests/rustdoc-json/structs/with_generics.rs
index 00474800a0e..d721cbdbe25 100644
--- a/tests/rustdoc-json/structs/with_generics.rs
+++ b/tests/rustdoc-json/structs/with_generics.rs
@@ -1,13 +1,13 @@
 use std::collections::HashMap;
 
 // @is "$.index[*][?(@.name=='WithGenerics')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='WithGenerics')].kind" \"struct\"
-// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].name" \"T\"
-// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].kind.type.bounds" []
-// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].name" \"U\"
-// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].kind.type.bounds" []
-// @is "$.index[*][?(@.name=='WithGenerics')].inner.kind.plain.fields_stripped" true
-// @is "$.index[*][?(@.name=='WithGenerics')].inner.kind.plain.fields" []
+// @has "$.index[*][?(@.name=='WithGenerics')].inner.struct"
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[0].name" \"T\"
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[0].kind.type.bounds" []
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[1].name" \"U\"
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[1].kind.type.bounds" []
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.struct.kind.plain.fields_stripped" true
+// @is "$.index[*][?(@.name=='WithGenerics')].inner.struct.kind.plain.fields" []
 pub struct WithGenerics<T, U> {
     stuff: Vec<T>,
     things: HashMap<U, U>,
diff --git a/tests/rustdoc-json/structs/with_primitives.rs b/tests/rustdoc-json/structs/with_primitives.rs
index 9c5a37f3957..e0285a9e688 100644
--- a/tests/rustdoc-json/structs/with_primitives.rs
+++ b/tests/rustdoc-json/structs/with_primitives.rs
@@ -1,9 +1,11 @@
+// ignore-tidy-linelength
+
 // @is "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\"
-// @is "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\"
-// @is "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" []
-// @is "$.index[*][?(@.name=='WithPrimitives')].inner.kind.plain.fields_stripped" true
-// @is "$.index[*][?(@.name=='WithPrimitives')].inner.kind.plain.fields" []
+// @has "$.index[*][?(@.name=='WithPrimitives')].inner.struct"
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.generics.params[0].name" \"\'a\"
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.generics.params[0].kind.lifetime.outlives" []
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.kind.plain.fields_stripped" true
+// @is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.kind.plain.fields" []
 pub struct WithPrimitives<'a> {
     num: u32,
     s: &'a str,
diff --git a/tests/rustdoc-json/traits/has_body.rs b/tests/rustdoc-json/traits/has_body.rs
index a57cb97d4a6..219e2d9bc54 100644
--- a/tests/rustdoc-json/traits/has_body.rs
+++ b/tests/rustdoc-json/traits/has_body.rs
@@ -1,21 +1,21 @@
 // @has "$.index[*][?(@.name=='Foo')]"
 pub trait Foo {
-    // @is "$.index[*][?(@.name=='no_self')].inner.has_body" false
+    // @is "$.index[*][?(@.name=='no_self')].inner.function.has_body" false
     fn no_self();
-    // @is "$.index[*][?(@.name=='move_self')].inner.has_body" false
+    // @is "$.index[*][?(@.name=='move_self')].inner.function.has_body" false
     fn move_self(self);
-    // @is "$.index[*][?(@.name=='ref_self')].inner.has_body" false
+    // @is "$.index[*][?(@.name=='ref_self')].inner.function.has_body" false
     fn ref_self(&self);
 
-    // @is "$.index[*][?(@.name=='no_self_def')].inner.has_body" true
+    // @is "$.index[*][?(@.name=='no_self_def')].inner.function.has_body" true
     fn no_self_def() {}
-    // @is "$.index[*][?(@.name=='move_self_def')].inner.has_body" true
+    // @is "$.index[*][?(@.name=='move_self_def')].inner.function.has_body" true
     fn move_self_def(self) {}
-    // @is "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true
+    // @is "$.index[*][?(@.name=='ref_self_def')].inner.function.has_body" true
     fn ref_self_def(&self) {}
 }
 
 pub trait Bar: Clone {
-    // @is "$.index[*][?(@.name=='method')].inner.has_body" false
+    // @is "$.index[*][?(@.name=='method')].inner.function.has_body" false
     fn method(&self, param: usize);
 }
diff --git a/tests/rustdoc-json/traits/implementors.rs b/tests/rustdoc-json/traits/implementors.rs
index db3fe5df739..7d351ad61be 100644
--- a/tests/rustdoc-json/traits/implementors.rs
+++ b/tests/rustdoc-json/traits/implementors.rs
@@ -2,18 +2,18 @@
 #![no_core]
 
 // @set wham = "$.index[*][?(@.name=='Wham')].id"
-// @count "$.index[*][?(@.name=='Wham')].inner.implementations[*]" 1
-// @set gmWham = "$.index[*][?(@.name=='Wham')].inner.implementations[0]"
+// @count "$.index[*][?(@.name=='Wham')].inner.trait.implementations[*]" 1
+// @set gmWham = "$.index[*][?(@.name=='Wham')].inner.trait.implementations[0]"
 pub trait Wham {}
 
-// @count "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[*]" 1
-// @is "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[0]" $gmWham
+// @count "$.index[*][?(@.name=='GeorgeMichael')].inner.struct.impls[*]" 1
+// @is "$.index[*][?(@.name=='GeorgeMichael')].inner.struct.impls[0]" $gmWham
 // @set gm = "$.index[*][?(@.name=='Wham')].id"
 
 // jsonpath_lib isnt expressive enough (for now) to get the "impl" item, so we
 // just check it isn't pointing to the type, but when you port to jsondocck-ng
 // check what the impl item is
-// @!is "$.index[*][?(@.name=='Wham')].inner.implementations[0]" $gm
+// @!is "$.index[*][?(@.name=='Wham')].inner.trait.implementations[0]" $gm
 pub struct GeorgeMichael {}
 
 impl Wham for GeorgeMichael {}
diff --git a/tests/rustdoc-json/traits/supertrait.rs b/tests/rustdoc-json/traits/supertrait.rs
index 4048fdd74b4..2123ac40427 100644
--- a/tests/rustdoc-json/traits/supertrait.rs
+++ b/tests/rustdoc-json/traits/supertrait.rs
@@ -8,19 +8,19 @@
 pub trait Loud {}
 
 // @set very_loud_id = "$.index[*][?(@.name=='VeryLoud')].id"
-// @count "$.index[*][?(@.name=='VeryLoud')].inner.bounds[*]" 1
-// @is    "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.id" $loud_id
+// @count "$.index[*][?(@.name=='VeryLoud')].inner.trait.bounds[*]" 1
+// @is    "$.index[*][?(@.name=='VeryLoud')].inner.trait.bounds[0].trait_bound.trait.id" $loud_id
 pub trait VeryLoud: Loud {}
 
 // @set sounds_good_id = "$.index[*][?(@.name=='SoundsGood')].id"
 pub trait SoundsGood {}
 
-// @count "$.index[*][?(@.name=='MetalBand')].inner.bounds[*]" 2
-// @is    "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.id" $very_loud_id
-// @is    "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.id" $sounds_good_id
+// @count "$.index[*][?(@.name=='MetalBand')].inner.trait.bounds[*]" 2
+// @is    "$.index[*][?(@.name=='MetalBand')].inner.trait.bounds[0].trait_bound.trait.id" $very_loud_id
+// @is    "$.index[*][?(@.name=='MetalBand')].inner.trait.bounds[1].trait_bound.trait.id" $sounds_good_id
 pub trait MetalBand: VeryLoud + SoundsGood {}
 
-// @count "$.index[*][?(@.name=='DnabLatem')].inner.bounds[*]" 2
-// @is    "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.id" $very_loud_id
-// @is    "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.id" $sounds_good_id
+// @count "$.index[*][?(@.name=='DnabLatem')].inner.trait.bounds[*]" 2
+// @is    "$.index[*][?(@.name=='DnabLatem')].inner.trait.bounds[1].trait_bound.trait.id" $very_loud_id
+// @is    "$.index[*][?(@.name=='DnabLatem')].inner.trait.bounds[0].trait_bound.trait.id" $sounds_good_id
 pub trait DnabLatem: SoundsGood + VeryLoud {}
diff --git a/tests/rustdoc-json/traits/trait_alias.rs b/tests/rustdoc-json/traits/trait_alias.rs
index 35db9296cdd..4fcc26f7de2 100644
--- a/tests/rustdoc-json/traits/trait_alias.rs
+++ b/tests/rustdoc-json/traits/trait_alias.rs
@@ -4,24 +4,24 @@
 #![feature(trait_alias)]
 
 // @set Orig = "$.index[*][?(@.name == 'Orig')].id"
-// @is "$.index[*][?(@.name == 'Orig')].kind" '"trait"'
+// @has "$.index[*][?(@.name == 'Orig')].inner.trait"
 pub trait Orig<T> {}
 
 // @set Alias = "$.index[*][?(@.name == 'Alias')].id"
-// @is "$.index[*][?(@.name == 'Alias')].kind" '"trait_alias"'
-// @is "$.index[*][?(@.name == 'Alias')].inner.generics" '{"params": [], "where_predicates": []}'
-// @count "$.index[*][?(@.name == 'Alias')].inner.params[*]" 1
-// @is "$.index[*][?(@.name == 'Alias')].inner.params[0].trait_bound.trait.id" $Orig
-// @is "$.index[*][?(@.name == 'Alias')].inner.params[0].trait_bound.trait.args.angle_bracketed.args[0].type.inner" '"i32"'
+// @has "$.index[*][?(@.name == 'Alias')].inner.trait_alias"
+// @is "$.index[*][?(@.name == 'Alias')].inner.trait_alias.generics" '{"params": [], "where_predicates": []}'
+// @count "$.index[*][?(@.name == 'Alias')].inner.trait_alias.params[*]" 1
+// @is "$.index[*][?(@.name == 'Alias')].inner.trait_alias.params[0].trait_bound.trait.id" $Orig
+// @is "$.index[*][?(@.name == 'Alias')].inner.trait_alias.params[0].trait_bound.trait.args.angle_bracketed.args[0].type.primitive" '"i32"'
 pub trait Alias = Orig<i32>;
 
 pub struct Struct;
 
 impl Orig<i32> for Struct {}
 
-// @is "$.index[*][?(@.name=='takes_alias')].inner.decl.inputs[0][1].kind" '"impl_trait"'
-// @is "$.index[*][?(@.name=='takes_alias')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $Alias
-// @is "$.index[*][?(@.name=='takes_alias')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $Alias
+// @has "$.index[*][?(@.name=='takes_alias')].inner.function.decl.inputs[0][1].impl_trait"
+// @is "$.index[*][?(@.name=='takes_alias')].inner.function.decl.inputs[0][1].impl_trait[0].trait_bound.trait.id" $Alias
+// @is "$.index[*][?(@.name=='takes_alias')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $Alias
 pub fn takes_alias(_: impl Alias) {}
 // FIXME: Should the trait be mentioned in both the decl and generics?
 
diff --git a/tests/rustdoc-json/type/dyn.rs b/tests/rustdoc-json/type/dyn.rs
index eaf249252e3..e5ee60fad59 100644
--- a/tests/rustdoc-json/type/dyn.rs
+++ b/tests/rustdoc-json/type/dyn.rs
@@ -1,46 +1,46 @@
 // ignore-tidy-linelength
 use std::fmt::Debug;
 
-// @count "$.index[*][?(@.name=='dyn')].inner.items[*]" 3
+// @count "$.index[*][?(@.name=='dyn')].inner.module.items[*]" 3
 // @set sync_int_gen = "$.index[*][?(@.name=='SyncIntGen')].id"
 // @set ref_fn       = "$.index[*][?(@.name=='RefFn')].id"
 // @set weird_order  = "$.index[*][?(@.name=='WeirdOrder')].id"
-// @ismany "$.index[*][?(@.name=='dyn')].inner.items[*]" $sync_int_gen $ref_fn $weird_order
+// @ismany "$.index[*][?(@.name=='dyn')].inner.module.items[*]" $sync_int_gen $ref_fn $weird_order
 
-// @is    "$.index[*][?(@.name=='SyncIntGen')].kind" \"typedef\"
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.generics" '{"params": [], "where_predicates": []}'
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.kind" \"resolved_path\"
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.name" \"Box\"
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.bindings" []
-// @count "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args" 1
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"dyn_trait\"
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.lifetime" \"\'static\"
-// @count "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[*]" 3
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].generic_params" []
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].generic_params" []
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].generic_params" []
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Fn"'
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Send"'
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].trait.name" '"Sync"'
-// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
+// @has    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.generics" '{"params": [], "where_predicates": []}'
+// @has    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.name" \"Box\"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.bindings" []
+// @count "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args" 1
+// @has    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.lifetime" \"\'static\"
+// @count "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[*]" 3
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].generic_params" []
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].generic_params" []
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].generic_params" []
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.name" '"Fn"'
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].trait.name" '"Send"'
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].trait.name" '"Sync"'
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.args" '{"parenthesized": {"inputs": [],"output": {"primitive": "i32"}}}'
 pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>;
 
-// @is "$.index[*][?(@.name=='RefFn')].kind" \"typedef\"
-// @is "$.index[*][?(@.name=='RefFn')].inner.generics" '{"params": [{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"}],"where_predicates": []}'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.mutable" 'false'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.lifetime" "\"'a\""
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.kind" '"dyn_trait"'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.lifetime" null
-// @count "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[*]" 1
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.name" '"Fn"'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.inputs[0].inner.lifetime" "\"'b\""
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.args.parenthesized.output.inner.lifetime" "\"'b\""
+// @has "$.index[*][?(@.name=='RefFn')].inner.typedef"
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.generics" '{"params": [{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"}],"where_predicates": []}'
+// @has "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref"
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.mutable" 'false'
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.lifetime" "\"'a\""
+// @has "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait"
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.lifetime" null
+// @count "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.traits[*]" 1
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.traits[0].trait.name" '"Fn"'
+// @has "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref"
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref.lifetime" "\"'b\""
+// @has "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.output.borrowed_ref"
+// @is "$.index[*][?(@.name=='RefFn')].inner.typedef.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.output.borrowed_ref.lifetime" "\"'b\""
 pub type RefFn<'a> = &'a dyn for<'b> Fn(&'b i32) -> &'b i32;
 
-// @is    "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.name" '"Send"'
-// @is    "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.name" '"Debug"'
+// @is    "$.index[*][?(@.name=='WeirdOrder')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.name" '"Send"'
+// @is    "$.index[*][?(@.name=='WeirdOrder')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].trait.name" '"Debug"'
 pub type WeirdOrder = Box<dyn Send + Debug>;
diff --git a/tests/rustdoc-json/type/extern.rs b/tests/rustdoc-json/type/extern.rs
index d287d5ebec5..c30146ce9e0 100644
--- a/tests/rustdoc-json/type/extern.rs
+++ b/tests/rustdoc-json/type/extern.rs
@@ -6,5 +6,4 @@ extern {
 }
 
 // @is "$.index[*][?(@.docs=='No inner information')].name" '"Foo"'
-// @is "$.index[*][?(@.docs=='No inner information')].kind" '"foreign_type"'
-// @!has "$.index[*][?(@.docs=='No inner information')].inner"
+// @is "$.index[*][?(@.docs=='No inner information')].inner" \"foreign_type\"
diff --git a/tests/rustdoc-json/type/fn_lifetime.rs b/tests/rustdoc-json/type/fn_lifetime.rs
index d7216ec7675..424c5dce273 100644
--- a/tests/rustdoc-json/type/fn_lifetime.rs
+++ b/tests/rustdoc-json/type/fn_lifetime.rs
@@ -1,27 +1,26 @@
 // ignore-tidy-linelength
 
-// @is "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
+// @has "$.index[*][?(@.name=='GenericFn')].inner.typedef"
 
-// @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
-// @is     "$.index[*][?(@.name=='GenericFn')].inner.type.kind" \"function_pointer\"
-// @count  "$.index[*][?(@.name=='GenericFn')].inner.type.inner.generic_params[*]" 0
-// @count  "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*]" 1
-// @is     "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
-// @is     "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
+// @ismany "$.index[*][?(@.name=='GenericFn')].inner.typedef.generics.params[*].name" \"\'a\"
+// @has    "$.index[*][?(@.name=='GenericFn')].inner.typedef.generics.params[*].kind.lifetime"
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.typedef.generics.params[*].kind.lifetime.outlives[*]" 0
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.typedef.generics.where_predicates[*]" 0
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.typedef.type.function_pointer.generic_params[*]" 0
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.typedef.type.function_pointer.decl.inputs[*]" 1
+// @is     "$.index[*][?(@.name=='GenericFn')].inner.typedef.type.function_pointer.decl.inputs[*][1].borrowed_ref.lifetime" \"\'a\"
+// @is     "$.index[*][?(@.name=='GenericFn')].inner.typedef.type.function_pointer.decl.output.borrowed_ref.lifetime" \"\'a\"
 
 pub type GenericFn<'a> = fn(&'a i32) -> &'a i32;
 
-// @is    "$.index[*][?(@.name=='ForAll')].kind" \"typedef\"
-// @count "$.index[*][?(@.name=='ForAll')].inner.generics.params[*]" 0
-// @count "$.index[*][?(@.name=='ForAll')].inner.generics.where_predicates[*]" 0
-// @count "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*]" 1
-// @is    "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].name" \"\'a\"
-// @has   "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime"
-// @count "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime.outlives[*]" 0
-// @count "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*]" 1
-// @is    "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
-// @is    "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
+// @has    "$.index[*][?(@.name=='ForAll')].inner.typedef"
+// @count "$.index[*][?(@.name=='ForAll')].inner.typedef.generics.params[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.typedef.generics.where_predicates[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.typedef.type.function_pointer.generic_params[*]" 1
+// @is    "$.index[*][?(@.name=='ForAll')].inner.typedef.type.function_pointer.generic_params[*].name" \"\'a\"
+// @has   "$.index[*][?(@.name=='ForAll')].inner.typedef.type.function_pointer.generic_params[*].kind.lifetime"
+// @count "$.index[*][?(@.name=='ForAll')].inner.typedef.type.function_pointer.generic_params[*].kind.lifetime.outlives[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.typedef.type.function_pointer.decl.inputs[*]" 1
+// @is    "$.index[*][?(@.name=='ForAll')].inner.typedef.type.function_pointer.decl.inputs[*][1].borrowed_ref.lifetime" \"\'a\"
+// @is    "$.index[*][?(@.name=='ForAll')].inner.typedef.type.function_pointer.decl.output.borrowed_ref.lifetime" \"\'a\"
 pub type ForAll = for<'a> fn(&'a i32) -> &'a i32;
diff --git a/tests/rustdoc-json/type/generic_default.rs b/tests/rustdoc-json/type/generic_default.rs
index 9c6d4540bfb..b4642874532 100644
--- a/tests/rustdoc-json/type/generic_default.rs
+++ b/tests/rustdoc-json/type/generic_default.rs
@@ -9,25 +9,25 @@ pub enum Result<T, E> {
 // @set my_error = "$.index[*][?(@.name=='MyError')].id"
 pub struct MyError {}
 
-// @is    "$.index[*][?(@.name=='MyResult')].kind" \"typedef\"
-// @count "$.index[*][?(@.name=='MyResult')].inner.generics.where_predicates[*]" 0
-// @count "$.index[*][?(@.name=='MyResult')].inner.generics.params[*]" 2
-// @is    "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].name" \"T\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].name" \"E\"
-// @has   "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type"
-// @has   "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type"
-// @count "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.bounds[*]" 0
-// @count "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.bounds[*]" 0
-// @is    "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.default" null
-// @is    "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.kind" \"resolved_path\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.id" $my_error
-// @is    "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.name" \"MyError\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.kind" \"resolved_path\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.inner.id" $result
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.inner.name" \"Result\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.bindings" []
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"generic\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.kind" \"generic\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.inner" \"T\"
-// @is    "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.inner" \"E\"
+// @has    "$.index[*][?(@.name=='MyResult')].inner.typedef"
+// @count "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.where_predicates[*]" 0
+// @count "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[*]" 2
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[0].name" \"T\"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[1].name" \"E\"
+// @has   "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[0].kind.type"
+// @has   "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[1].kind.type"
+// @count "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[0].kind.type.bounds[*]" 0
+// @count "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[1].kind.type.bounds[*]" 0
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[0].kind.type.default" null
+// @has    "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[1].kind.type.default.resolved_path"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[1].kind.type.default.resolved_path.id" $my_error
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.generics.params[1].kind.type.default.resolved_path.name" \"MyError\"
+// @has    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path.id" $result
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path.name" \"Result\"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path.args.angle_bracketed.bindings" []
+// @has    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.generic"
+// @has    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path.args.angle_bracketed.args[1].type.generic"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path.args.angle_bracketed.args[0].type.generic" \"T\"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.typedef.type.resolved_path.args.angle_bracketed.args[1].type.generic" \"E\"
 pub type MyResult<T, E = MyError> = Result<T, E>;
diff --git a/tests/rustdoc-json/type/hrtb.rs b/tests/rustdoc-json/type/hrtb.rs
index 2c4ee00d468..f7ac878ceaa 100644
--- a/tests/rustdoc-json/type/hrtb.rs
+++ b/tests/rustdoc-json/type/hrtb.rs
@@ -1,7 +1,7 @@
 // ignore-tidy-linelength
 
-// @is "$.index[*][?(@.name=='genfn')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F","kind": "generic"}'
-// @is "$.index[*][?(@.name=='genfn')].inner.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
+// @is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.type" '{"generic": "F"}'
+// @is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
 pub fn genfn<F>(f: F)
 where
     for<'a, 'b> F: Fn(&'a i32, &'b i32),
@@ -10,14 +10,12 @@ where
     f(&zero, &zero);
 }
 
-// @is "$.index[*][?(@.name=='dynfn')].inner.generics" '{"params": [], "where_predicates": []}'
-// @is "$.index[*][?(@.name=='dynfn')].inner.generics" '{"params": [], "where_predicates": []}'
-// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
-// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.kind" '"dyn_trait"'
-// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.lifetime" null
-// @count "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[*]" 1
-// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
-// @is "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].trait.name" '"Fn"'
+// @is "$.index[*][?(@.name=='dynfn')].inner.function.generics" '{"params": [], "where_predicates": []}'
+// @is "$.index[*][?(@.name=='dynfn')].inner.function.generics" '{"params": [], "where_predicates": []}'
+// @is "$.index[*][?(@.name=='dynfn')].inner.function.decl.inputs[0][1].borrowed_ref.type.dyn_trait.lifetime" null
+// @count "$.index[*][?(@.name=='dynfn')].inner.function.decl.inputs[0][1].borrowed_ref.type.dyn_trait.traits[*]" 1
+// @is "$.index[*][?(@.name=='dynfn')].inner.function.decl.inputs[0][1].borrowed_ref.type.dyn_trait.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
+// @is "$.index[*][?(@.name=='dynfn')].inner.function.decl.inputs[0][1].borrowed_ref.type.dyn_trait.traits[0].trait.name" '"Fn"'
 pub fn dynfn(f: &dyn for<'a, 'b> Fn(&'a i32, &'b i32)) {
     let zero = 0;
     f(&zero, &zero);
diff --git a/tests/rustdoc-json/type/inherent_associated_type.rs b/tests/rustdoc-json/type/inherent_associated_type.rs
index ed63def93df..64c6c53ce47 100644
--- a/tests/rustdoc-json/type/inherent_associated_type.rs
+++ b/tests/rustdoc-json/type/inherent_associated_type.rs
@@ -12,11 +12,9 @@ pub struct Owner;
 pub fn create() -> Owner::Metadata {
     OwnerMetadata
 }
-// @is '$.index[*][?(@.name=="create")].inner.decl.output.kind' '"qualified_path"'
-// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.name' '"Metadata"'
-// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.trait' null
-// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.self_type.kind' '"resolved_path"'
-// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.self_type.inner.id' $Owner
+// @is '$.index[*][?(@.name=="create")].inner.function.decl.output.qualified_path.name' '"Metadata"'
+// @is '$.index[*][?(@.name=="create")].inner.function.decl.output.qualified_path.trait' null
+// @is '$.index[*][?(@.name=="create")].inner.function.decl.output.qualified_path.self_type.resolved_path.id' $Owner
 
 /// impl
 impl Owner {
@@ -24,6 +22,5 @@ impl Owner {
     pub type Metadata = OwnerMetadata;
 }
 // @set iat = '$.index[*][?(@.docs=="iat")].id'
-// @is '$.index[*][?(@.docs=="impl")].inner.items[*]' $iat
-// @is '$.index[*][?(@.docs=="iat")].kind' '"assoc_type"'
-// @is '$.index[*][?(@.docs=="iat")].inner.default.inner.id' $OwnerMetadata
+// @is '$.index[*][?(@.docs=="impl")].inner.impl.items[*]' $iat
+// @is '$.index[*][?(@.docs=="iat")].inner.assoc_type.default.resolved_path.id' $OwnerMetadata
diff --git a/tests/rustdoc-json/type/inherent_associated_type_bound.rs b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
index a089600b692..2e9b13d0cac 100644
--- a/tests/rustdoc-json/type/inherent_associated_type_bound.rs
+++ b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
@@ -5,14 +5,12 @@
 // @set Carrier = '$.index[*][?(@.name=="Carrier")].id'
 pub struct Carrier<'a>(&'a ());
 
-// @is '$.index[*][?(@.name=="User")].inner.type.kind' '"function_pointer"'
-// @is '$.index[*][?(@.name=="User")].inner.type.inner.generic_params[*].name' \""'b"\"
-// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].kind' '"qualified_path"'
-// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.self_type.inner.id' $Carrier
-// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.self_type.inner.args.angle_bracketed.args[0].lifetime' \""'b"\"
-// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.name' '"Focus"'
-// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.trait' null
-// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.args.angle_bracketed.args[0].type.inner' '"i32"'
+// @is '$.index[*][?(@.name=="User")].inner.typedef.type.function_pointer.generic_params[*].name' \""'b"\"
+// @is '$.index[*][?(@.name=="User")].inner.typedef.type.function_pointer.decl.inputs[0][1].qualified_path.self_type.resolved_path.id' $Carrier
+// @is '$.index[*][?(@.name=="User")].inner.typedef.type.function_pointer.decl.inputs[0][1].qualified_path.self_type.resolved_path.args.angle_bracketed.args[0].lifetime' \""'b"\"
+// @is '$.index[*][?(@.name=="User")].inner.typedef.type.function_pointer.decl.inputs[0][1].qualified_path.name' '"Focus"'
+// @is '$.index[*][?(@.name=="User")].inner.typedef.type.function_pointer.decl.inputs[0][1].qualified_path.trait' null
+// @is '$.index[*][?(@.name=="User")].inner.typedef.type.function_pointer.decl.inputs[0][1].qualified_path.args.angle_bracketed.args[0].type.primitive' '"i32"'
 
 pub type User = for<'b> fn(Carrier<'b>::Focus<i32>);
 
diff --git a/tests/rustdoc-json/type/inherent_associated_type_projections.rs b/tests/rustdoc-json/type/inherent_associated_type_projections.rs
index 30c68bfe56c..942e323efca 100644
--- a/tests/rustdoc-json/type/inherent_associated_type_projections.rs
+++ b/tests/rustdoc-json/type/inherent_associated_type_projections.rs
@@ -5,11 +5,10 @@
 // @set Parametrized = '$.index[*][?(@.name=="Parametrized")].id'
 pub struct Parametrized<T>(T);
 
-// @is '$.index[*][?(@.name=="Test")].inner.type.kind' '"qualified_path"'
-// @is '$.index[*][?(@.name=="Test")].inner.type.inner.self_type.inner.id' $Parametrized
-// @is '$.index[*][?(@.name=="Test")].inner.type.inner.self_type.inner.args.angle_bracketed.args[0].type' '{"inner": "i32", "kind": "primitive"}'
-// @is '$.index[*][?(@.name=="Test")].inner.type.inner.name' '"Proj"'
-// @is '$.index[*][?(@.name=="Test")].inner.type.inner.trait' null
+// @is '$.index[*][?(@.name=="Test")].inner.typedef.type.qualified_path.self_type.resolved_path.id' $Parametrized
+// @is '$.index[*][?(@.name=="Test")].inner.typedef.type.qualified_path.self_type.resolved_path.args.angle_bracketed.args[0].type.primitive' \"i32\"
+// @is '$.index[*][?(@.name=="Test")].inner.typedef.type.qualified_path.name' '"Proj"'
+// @is '$.index[*][?(@.name=="Test")].inner.typedef.type.qualified_path.trait' null
 pub type Test = Parametrized<i32>::Proj;
 
 /// param_bool
@@ -29,5 +28,5 @@ impl Parametrized<i32> {
 // @set param_bool_proj = '$.index[*][?(@.docs=="param_bool_proj")].id'
 // @set param_i32_proj = '$.index[*][?(@.docs=="param_i32_proj")].id'
 
-// @is '$.index[*][?(@.docs=="param_bool")].inner.items[*]' $param_bool_proj
-// @is '$.index[*][?(@.docs=="param_i32")].inner.items[*]' $param_i32_proj
+// @is '$.index[*][?(@.docs=="param_bool")].inner.impl.items[*]' $param_bool_proj
+// @is '$.index[*][?(@.docs=="param_i32")].inner.impl.items[*]' $param_i32_proj
diff --git a/tests/rustdoc-json/unions/impl.rs b/tests/rustdoc-json/unions/impl.rs
index 4454a69ecd1..7456892df1b 100644
--- a/tests/rustdoc-json/unions/impl.rs
+++ b/tests/rustdoc-json/unions/impl.rs
@@ -1,15 +1,15 @@
 #![no_std]
 
 // @is "$.index[*][?(@.name=='Ux')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='Ux')].kind" \"union\"
+// @has "$.index[*][?(@.name=='Ux')].inner.union"
 pub union Ux {
     a: u32,
     b: u64
 }
 
 // @is "$.index[*][?(@.name=='Num')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='Num')].kind" \"trait\"
+// @has "$.index[*][?(@.name=='Num')].inner.trait"
 pub trait Num {}
 
-// @count "$.index[*][?(@.name=='Ux')].inner.impls" 1
+// @count "$.index[*][?(@.name=='Ux')].inner.union.impls" 1
 impl Num for Ux {}
diff --git a/tests/rustdoc-json/unions/union.rs b/tests/rustdoc-json/unions/union.rs
index c9df2b81c4b..22b70e1ce8c 100644
--- a/tests/rustdoc-json/unions/union.rs
+++ b/tests/rustdoc-json/unions/union.rs
@@ -1,6 +1,6 @@
 // @has "$.index[*][?(@.name=='Union')].visibility" \"public\"
-// @has "$.index[*][?(@.name=='Union')].kind" \"union\"
-// @!has "$.index[*][?(@.name=='Union')].inner.struct_type"
+// @has "$.index[*][?(@.name=='Union')].inner.union"
+// @!has "$.index[*][?(@.name=='Union')].inner.union.struct_type"
 // @set Union = "$.index[*][?(@.name=='Union')].id"
 pub union Union {
     int: i32,
@@ -8,8 +8,8 @@ pub union Union {
 }
 
 
-// @is "$.index[*][?(@.name=='make_int_union')].inner.decl.output.kind" '"resolved_path"'
-// @is "$.index[*][?(@.name=='make_int_union')].inner.decl.output.inner.id" $Union
+// @has "$.index[*][?(@.name=='make_int_union')].inner.function.decl.output.resolved_path"
+// @is "$.index[*][?(@.name=='make_int_union')].inner.function.decl.output.resolved_path.id" $Union
 pub fn make_int_union(int: i32) -> Union {
     Union { int }
 }
diff --git a/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs
new file mode 100644
index 00000000000..4e74278dc7b
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs
@@ -0,0 +1,10 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/111189>.
+// This test ensures that it doesn't crash.
+
+#![deny(warnings)]
+
+/// #[rustfmt::skip]
+//~^ ERROR unresolved link to `rustfmt::skip`
+/// #[clippy::whatever]
+//~^ ERROR unresolved link to `clippy::whatever`
+pub fn foo() {}
diff --git a/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr
new file mode 100644
index 00000000000..edd3dfa7d7e
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr
@@ -0,0 +1,21 @@
+error: unresolved link to `rustfmt::skip`
+  --> $DIR/issue-111189-resolution-ice.rs:6:7
+   |
+LL | /// #[rustfmt::skip]
+   |       ^^^^^^^^^^^^^ no item named `rustfmt` in scope
+   |
+note: the lint level is defined here
+  --> $DIR/issue-111189-resolution-ice.rs:4:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
+
+error: unresolved link to `clippy::whatever`
+  --> $DIR/issue-111189-resolution-ice.rs:8:7
+   |
+LL | /// #[clippy::whatever]
+   |       ^^^^^^^^^^^^^^^^ no item named `clippy` in scope
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs
index 7d6d26003f6..ebd8e1d5594 100644
--- a/tests/ui/associated-inherent-types/inference.rs
+++ b/tests/ui/associated-inherent-types/inference.rs
@@ -3,7 +3,7 @@
 
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 use std::convert::identity;
 
diff --git a/tests/ui/associated-inherent-types/issue-111879-0.rs b/tests/ui/associated-inherent-types/issue-111879-0.rs
new file mode 100644
index 00000000000..e37f7d34ab5
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-111879-0.rs
@@ -0,0 +1,14 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// Check that we don't crash when printing inherent projections in diagnostics.
+
+pub struct Carrier<'a>(&'a ());
+
+pub type User = for<'b> fn(Carrier<'b>::Focus<i32>);
+
+impl<'a> Carrier<'a> {
+    pub type Focus<T> = &'a mut User; //~ ERROR overflow evaluating associated type
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/issue-111879-0.stderr b/tests/ui/associated-inherent-types/issue-111879-0.stderr
new file mode 100644
index 00000000000..7bdbad44017
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-111879-0.stderr
@@ -0,0 +1,8 @@
+error: overflow evaluating associated type `Carrier<'b>::Focus<i32>`
+  --> $DIR/issue-111879-0.rs:11:25
+   |
+LL |     pub type Focus<T> = &'a mut User;
+   |                         ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-inherent-types/issue-111879-1.rs b/tests/ui/associated-inherent-types/issue-111879-1.rs
new file mode 100644
index 00000000000..7acc4f94505
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-111879-1.rs
@@ -0,0 +1,12 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// Check that we don't crash when printing inherent projections in diagnostics.
+
+struct Foo<T>(T);
+
+impl<'a> Foo<fn(&'a ())> {
+    type Assoc = &'a ();
+}
+
+fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} //~ ERROR `main` function has wrong type
diff --git a/tests/ui/associated-inherent-types/issue-111879-1.stderr b/tests/ui/associated-inherent-types/issue-111879-1.stderr
new file mode 100644
index 00000000000..689b45e09aa
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-111879-1.stderr
@@ -0,0 +1,12 @@
+error[E0580]: `main` function has wrong type
+  --> $DIR/issue-111879-1.rs:12:1
+   |
+LL | fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
+   |
+   = note: expected fn pointer `fn()`
+              found fn pointer `fn(for<'a> fn(Foo<fn(&'a ())>::Assoc))`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0580`.
diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.rs b/tests/ui/async-await/return-type-notation/supertrait-bound.rs
new file mode 100644
index 00000000000..19bcfe3046b
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/supertrait-bound.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait, return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete and may not be safe to use
+
+trait IntFactory {
+    fn stream(&self) -> impl Iterator<Item = i32>;
+}
+trait SendIntFactory: IntFactory<stream(): Send> + Send {}
+
+fn main() {}
diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.stderr b/tests/ui/async-await/return-type-notation/supertrait-bound.stderr
new file mode 100644
index 00000000000..c8cec4946b4
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/supertrait-bound.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/supertrait-bound.rs:3:49
+   |
+LL | #![feature(return_position_impl_trait_in_trait, return_type_notation)]
+   |                                                 ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
index 9163c8ed6fb..60128c9419d 100644
--- a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
+++ b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
@@ -1,7 +1,7 @@
 // Check that closure captures for slice patterns are inferred correctly
 
 #![allow(unused_variables)]
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 // run-pass
 
diff --git a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
index a88b323e0bf..78e965cc4bc 100644
--- a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
+++ b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
@@ -1,7 +1,7 @@
 // run-pass
 #![allow(unused_mut)]
 #![allow(unused_variables)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 // pretty-expanded FIXME #23616
 
 struct A { a: isize, b: Box<isize> }
diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
index 40c6bfeeb43..9acb1ec5e43 100644
--- a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
+++ b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
@@ -1,7 +1,7 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 struct A { a: isize, b: Box<isize> }
 
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
index bc7295a0826..98f8d5d4733 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
+++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
@@ -1,7 +1,7 @@
 // run-pass
 
 #![warn(rust_2021_incompatible_closure_captures)]
-#![allow(drop_ref, drop_copy)]
+#![allow(dropping_references, dropping_copy_types)]
 
 fn main() {
     if let a = "" {
diff --git a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
index 0f15f664e75..5496d0e5fc7 100644
--- a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
+++ b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
@@ -3,7 +3,7 @@
 
 #![allow(unused)]
 #![allow(dead_code)]
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 struct Int(i32);
 struct B<'a>(&'a i32);
diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
index a097424a021..b5e97ec1c1b 100644
--- a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
+++ b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
@@ -2,7 +2,7 @@
 // check-pass
 
 #![feature(rustc_attrs)]
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 fn main() {
     let mut x = 1;
diff --git a/tests/ui/consts/const_forget.rs b/tests/ui/consts/const_forget.rs
index acdd6a54cf4..f06149f2cb9 100644
--- a/tests/ui/consts/const_forget.rs
+++ b/tests/ui/consts/const_forget.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![allow(forget_copy)]
+#![allow(forgetting_copy_types)]
 
 use std::mem::forget;
 
diff --git a/tests/ui/consts/issue-104155.rs b/tests/ui/consts/issue-104155.rs
index b3821f467b6..7b375dc0566 100644
--- a/tests/ui/consts/issue-104155.rs
+++ b/tests/ui/consts/issue-104155.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![allow(forget_copy)]
+#![allow(forgetting_copy_types)]
 
 const _: () = core::mem::forget(Box::<u32>::default);
 const _: () = core::mem::forget(|| Box::<u32>::default());
diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/crate-leading-sep.rs
index 8d1d0b4fcdf..fce97d9ba23 100644
--- a/tests/ui/crate-leading-sep.rs
+++ b/tests/ui/crate-leading-sep.rs
@@ -1,7 +1,7 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 fn main() {
     use ::std::mem;
diff --git a/tests/ui/drop/repeat-drop.rs b/tests/ui/drop/repeat-drop.rs
index 659d35db657..0afb4bb11bc 100644
--- a/tests/ui/drop/repeat-drop.rs
+++ b/tests/ui/drop/repeat-drop.rs
@@ -1,7 +1,7 @@
 // run-pass
 // needs-unwind
 
-#![allow(drop_ref, drop_copy)]
+#![allow(dropping_references, dropping_copy_types)]
 
 static mut CHECK: usize = 0;
 
diff --git a/tests/ui/dyn-star/param-env-infer.current.stderr b/tests/ui/dyn-star/param-env-infer.current.stderr
new file mode 100644
index 00000000000..d0785c887d8
--- /dev/null
+++ b/tests/ui/dyn-star/param-env-infer.current.stderr
@@ -0,0 +1,18 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/param-env-infer.rs:5:12
+   |
+LL | #![feature(dyn_star, pointer_like_trait)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0282]: type annotations needed
+  --> $DIR/param-env-infer.rs:12:10
+   |
+LL |     t as _
+   |          ^ cannot infer type
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/dyn-star/param-env-infer.next.stderr b/tests/ui/dyn-star/param-env-infer.next.stderr
new file mode 100644
index 00000000000..d0785c887d8
--- /dev/null
+++ b/tests/ui/dyn-star/param-env-infer.next.stderr
@@ -0,0 +1,18 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/param-env-infer.rs:5:12
+   |
+LL | #![feature(dyn_star, pointer_like_trait)]
+   |            ^^^^^^^^
+   |
+   = note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0282]: type annotations needed
+  --> $DIR/param-env-infer.rs:12:10
+   |
+LL |     t as _
+   |          ^ cannot infer type
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/dyn-star/param-env-infer.rs b/tests/ui/dyn-star/param-env-infer.rs
new file mode 100644
index 00000000000..9039dde5e93
--- /dev/null
+++ b/tests/ui/dyn-star/param-env-infer.rs
@@ -0,0 +1,16 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+// incremental
+
+#![feature(dyn_star, pointer_like_trait)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+use std::fmt::Debug;
+use std::marker::PointerLike;
+
+fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
+    t as _
+    //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0746.fixed b/tests/ui/error-codes/E0746.fixed
deleted file mode 100644
index ca8319aa020..00000000000
--- a/tests/ui/error-codes/E0746.fixed
+++ /dev/null
@@ -1,18 +0,0 @@
-// run-rustfix
-#![allow(dead_code)]
-struct Struct;
-trait Trait {}
-impl Trait for Struct {}
-impl Trait for u32 {}
-
-fn foo() -> impl Trait { Struct }
-//~^ ERROR E0746
-
-fn bar() -> impl Trait { //~ ERROR E0746
-    if true {
-        return 0;
-    }
-    42
-}
-
-fn main() {}
diff --git a/tests/ui/error-codes/E0746.rs b/tests/ui/error-codes/E0746.rs
index bf5ba8fff56..86b5b7444d1 100644
--- a/tests/ui/error-codes/E0746.rs
+++ b/tests/ui/error-codes/E0746.rs
@@ -1,5 +1,5 @@
-// run-rustfix
 #![allow(dead_code)]
+
 struct Struct;
 trait Trait {}
 impl Trait for Struct {}
diff --git a/tests/ui/error-codes/E0746.stderr b/tests/ui/error-codes/E0746.stderr
index 2153b59ad18..9fe90ab7bec 100644
--- a/tests/ui/error-codes/E0746.stderr
+++ b/tests/ui/error-codes/E0746.stderr
@@ -4,11 +4,14 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn foo() -> dyn Trait { Struct }
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Trait` as the return type, as all return paths are of type `Struct`, which implements `Trait`
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL | fn foo() -> impl Trait { Struct }
-   |             ~~~~~~~~~~
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL | fn foo() -> Box<dyn Trait> { Box::new(Struct) }
+   |             ++++         +   +++++++++      +
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/E0746.rs:11:13
@@ -16,11 +19,18 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bar() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Trait` as the return type, as all return paths are of type `{integer}`, which implements `Trait`
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL | fn bar() -> impl Trait {
-   |             ~~~~~~~~~~
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn bar() -> Box<dyn Trait> {
+LL |     if true {
+LL ~         return Box::new(0);
+LL |     }
+LL ~     Box::new(42)
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
index 0bc4feed329..bb093a4af4a 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 struct Foo {
     x: isize
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
index 26ae6698d66..1a9f89c054f 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 struct Foo {
     x: isize
diff --git a/tests/ui/generator/drop-env.rs b/tests/ui/generator/drop-env.rs
index cb46953dac3..137a407931a 100644
--- a/tests/ui/generator/drop-env.rs
+++ b/tests/ui/generator/drop-env.rs
@@ -4,7 +4,7 @@
 //[nomiropt]compile-flags: -Z mir-opt-level=0
 
 #![feature(generators, generator_trait)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 use std::ops::Generator;
 use std::pin::Pin;
diff --git a/tests/ui/generator/issue-57017.rs b/tests/ui/generator/issue-57017.rs
index 918d233bf4e..381897c77a5 100644
--- a/tests/ui/generator/issue-57017.rs
+++ b/tests/ui/generator/issue-57017.rs
@@ -5,7 +5,7 @@
 // [drop_tracking_mir] build-pass
 
 #![feature(generators, negative_impls)]
-#![allow(drop_ref, drop_copy)]
+#![allow(dropping_references, dropping_copy_types)]
 
 macro_rules! type_combinations {
     (
diff --git a/tests/ui/generator/non-static-is-unpin.rs b/tests/ui/generator/non-static-is-unpin.rs
index adba800e25a..a5dde3912cc 100644
--- a/tests/ui/generator/non-static-is-unpin.rs
+++ b/tests/ui/generator/non-static-is-unpin.rs
@@ -3,7 +3,7 @@
 // run-pass
 
 #![feature(generators, generator_trait)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 use std::marker::{PhantomPinned, Unpin};
 
diff --git a/tests/ui/generator/resume-arg-size.rs b/tests/ui/generator/resume-arg-size.rs
index 19618f8d0aa..195166f975b 100644
--- a/tests/ui/generator/resume-arg-size.rs
+++ b/tests/ui/generator/resume-arg-size.rs
@@ -1,5 +1,5 @@
 #![feature(generators)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 // run-pass
 
diff --git a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
index 214267372bf..721bb7281c0 100644
--- a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
+++ b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
@@ -1,7 +1,7 @@
 // check-pass
 
 #![feature(decl_macro)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 macro mac() {
     mod m {
diff --git a/tests/ui/illegal-ufcs-drop.fixed b/tests/ui/illegal-ufcs-drop.fixed
index 8783682dec4..c088c82791b 100644
--- a/tests/ui/illegal-ufcs-drop.fixed
+++ b/tests/ui/illegal-ufcs-drop.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 struct Foo;
 
diff --git a/tests/ui/illegal-ufcs-drop.rs b/tests/ui/illegal-ufcs-drop.rs
index 29774306ec6..1389b112188 100644
--- a/tests/ui/illegal-ufcs-drop.rs
+++ b/tests/ui/illegal-ufcs-drop.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 struct Foo;
 
diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs
index cbf1daabe2b..af368203de0 100644
--- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs
+++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs
@@ -26,7 +26,7 @@ fn bax() -> dyn Trait { //~ ERROR E0746
     if true {
         Struct
     } else {
-        42 //~ ERROR `if` and `else` have incompatible types
+        42
     }
 }
 fn bam() -> Box<dyn Trait> {
diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
index dc1e40ea560..ed9261d0de5 100644
--- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
+++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
@@ -46,11 +46,10 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bap() -> Trait { Struct }
    |             ^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Trait` as the return type, as all return paths are of type `Struct`, which implements `Trait`
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL | fn bap() -> impl Trait { Struct }
-   |             ~~~~~~~~~~
+LL | fn bap() -> Box<Trait> { Box::new(Struct) }
+   |             ++++     +   +++++++++      +
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
@@ -58,11 +57,14 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn ban() -> dyn Trait { Struct }
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Trait` as the return type, as all return paths are of type `Struct`, which implements `Trait`
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL | fn ban() -> impl Trait { Struct }
-   |             ~~~~~~~~~~
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL | fn ban() -> Box<dyn Trait> { Box::new(Struct) }
+   |             ++++         +   +++++++++      +
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13
@@ -70,14 +72,14 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bak() -> dyn Trait { unimplemented!() }
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-help: use `impl Trait` as the return type if all return paths have the same type but you want to expose only the trait in the signature
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL | fn bak() -> impl Trait { unimplemented!() }
-   |             ~~~~~~~~~~
-help: use a boxed trait object if all return paths implement trait `Trait`
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL | fn bak() -> Box<dyn Trait> { unimplemented!() }
-   |             ++++         +
+LL | fn bak() -> Box<dyn Trait> { Box::new(unimplemented!()) }
+   |             ++++         +   +++++++++                +
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13
@@ -85,34 +87,18 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bal() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
-   = note: if all the returned values were of the same type you could use `impl Trait` as the return type
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-   = note: you can create a new `enum` with a variant for each returned type
-help: return a boxed trait object instead
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
-LL | fn bal() -> Box<dyn Trait> {
-   |             ++++         +
-help: ... and box this value
+LL | fn bal() -> impl Trait {
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL |         return Box::new(Struct);
-   |                +++++++++      +
-help: ... and box this value
+LL ~ fn bal() -> Box<dyn Trait> {
+LL |     if true {
+LL ~         return Box::new(Struct);
+LL |     }
+LL ~     Box::new(42)
    |
-LL |     Box::new(42)
-   |     +++++++++  +
-
-error[E0308]: `if` and `else` have incompatible types
-  --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:9
-   |
-LL | /     if true {
-LL | |         Struct
-   | |         ------ expected because of this
-LL | |     } else {
-LL | |         42
-   | |         ^^ expected `Struct`, found integer
-LL | |     }
-   | |_____- `if` and `else` have incompatible types
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13
@@ -120,22 +106,18 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bax() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
-   = note: if all the returned values were of the same type you could use `impl Trait` as the return type
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-   = note: you can create a new `enum` with a variant for each returned type
-help: return a boxed trait object instead
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
-LL | fn bax() -> Box<dyn Trait> {
-   |             ++++         +
-help: ... and box this value
+LL | fn bax() -> impl Trait {
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL |         Box::new(Struct)
-   |         +++++++++      +
-help: ... and box this value
+LL ~ fn bax() -> Box<dyn Trait> {
+LL |     if true {
+LL ~         Box::new(Struct)
+LL |     } else {
+LL ~         Box::new(42)
    |
-LL |         Box::new(42)
-   |         +++++++++  +
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:16
@@ -279,11 +261,18 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bat() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Trait` as the return type, as all return paths are of type `{integer}`, which implements `Trait`
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL | fn bat() -> impl Trait {
-   |             ~~~~~~~~~~
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn bat() -> Box<dyn Trait> {
+LL |     if true {
+LL ~         return Box::new(0);
+LL |     }
+LL ~     Box::new(42)
+   |
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:66:13
@@ -291,13 +280,20 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn bay() -> dyn Trait {
    |             ^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Trait` as the return type, as all return paths are of type `{integer}`, which implements `Trait`
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL | fn bay() -> impl Trait {
-   |             ~~~~~~~~~~
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL ~ fn bay() -> Box<dyn Trait> {
+LL |     if true {
+LL ~         Box::new(0)
+LL |     } else {
+LL ~         Box::new(42)
+   |
 
-error: aborting due to 20 previous errors
+error: aborting due to 19 previous errors
 
 Some errors have detailed explanations: E0277, E0308, E0746.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
index fa7664a83ee..a8a6288eb56 100644
--- a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
+++ b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
@@ -77,7 +77,7 @@ fn hat() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed
 fn pug() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed trait object
     match 13 {
         0 => 0i32,
-        1 => 1u32, //~ ERROR `match` arms have incompatible types
+        1 => 1u32,
         _ => 2u32,
     }
 }
@@ -86,7 +86,7 @@ fn man() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed
     if false {
         0i32
     } else {
-        1u32 //~ ERROR `if` and `else` have incompatible types
+        1u32
     }
 }
 
diff --git a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
index 3c65fd998c5..9205d74504f 100644
--- a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -171,39 +171,20 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn hat() -> dyn std::fmt::Display {
    |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
-   = note: if all the returned values were of the same type you could use `impl std::fmt::Display` as the return type
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-   = note: you can create a new `enum` with a variant for each returned type
-help: return a boxed trait object instead
-   |
-LL | fn hat() -> Box<dyn std::fmt::Display> {
-   |             ++++                     +
-help: ... and box this value
-   |
-LL |             return Box::new(0i32);
-   |                    +++++++++    +
-help: ... and box this value
-   |
-LL |             Box::new(1u32)
-   |             +++++++++    +
-
-error[E0308]: `match` arms have incompatible types
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:80:14
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
-LL | /     match 13 {
-LL | |         0 => 0i32,
-   | |              ---- this is found to be of type `i32`
-LL | |         1 => 1u32,
-   | |              ^^^^ expected `i32`, found `u32`
-LL | |         _ => 2u32,
-LL | |     }
-   | |_____- `match` arms have incompatible types
+LL | fn hat() -> impl std::fmt::Display {
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-help: change the type of the numeric literal from `u32` to `i32`
+LL ~ fn hat() -> Box<dyn std::fmt::Display> {
+LL |     match 13 {
+LL |         0 => {
+LL ~             return Box::new(0i32);
+LL |         }
+LL |         _ => {
+LL ~             Box::new(1u32)
    |
-LL |         1 => 1i32,
-   |               ~~~
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
@@ -211,43 +192,18 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn pug() -> dyn std::fmt::Display {
    |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
-   = note: if all the returned values were of the same type you could use `impl std::fmt::Display` as the return type
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-   = note: you can create a new `enum` with a variant for each returned type
-help: return a boxed trait object instead
-   |
-LL | fn pug() -> Box<dyn std::fmt::Display> {
-   |             ++++                     +
-help: ... and box this value
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
-LL |         0 => Box::new(0i32),
-   |              +++++++++    +
-help: ... and box this value
-   |
-LL |         1 => Box::new(1u32),
-   |              +++++++++    +
-help: ... and box this value
-   |
-LL |         _ => Box::new(2u32),
-   |              +++++++++    +
-
-error[E0308]: `if` and `else` have incompatible types
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:89:9
+LL | fn pug() -> impl std::fmt::Display {
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL | /     if false {
-LL | |         0i32
-   | |         ---- expected because of this
-LL | |     } else {
-LL | |         1u32
-   | |         ^^^^ expected `i32`, found `u32`
-LL | |     }
-   | |_____- `if` and `else` have incompatible types
-   |
-help: change the type of the numeric literal from `u32` to `i32`
+LL ~ fn pug() -> Box<dyn std::fmt::Display> {
+LL |     match 13 {
+LL ~         0 => Box::new(0i32),
+LL ~         1 => Box::new(1u32),
+LL ~         _ => Box::new(2u32),
    |
-LL |         1i32
-   |          ~~~
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13
@@ -255,24 +211,20 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn man() -> dyn std::fmt::Display {
    |             ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
-   = note: if all the returned values were of the same type you could use `impl std::fmt::Display` as the return type
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-   = note: you can create a new `enum` with a variant for each returned type
-help: return a boxed trait object instead
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
-LL | fn man() -> Box<dyn std::fmt::Display> {
-   |             ++++                     +
-help: ... and box this value
+LL | fn man() -> impl std::fmt::Display {
+   |             ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL |         Box::new(0i32)
-   |         +++++++++    +
-help: ... and box this value
+LL ~ fn man() -> Box<dyn std::fmt::Display> {
+LL |     if false {
+LL ~         Box::new(0i32)
+LL |     } else {
+LL ~         Box::new(1u32)
    |
-LL |         Box::new(1u32)
-   |         +++++++++    +
 
-error: aborting due to 14 previous errors
+error: aborting due to 12 previous errors
 
 Some errors have detailed explanations: E0308, E0746.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/imports/issue-109148.rs b/tests/ui/imports/issue-109148.rs
new file mode 100644
index 00000000000..694cb494a15
--- /dev/null
+++ b/tests/ui/imports/issue-109148.rs
@@ -0,0 +1,15 @@
+// edition: 2021
+
+// https://github.com/rust-lang/rust/pull/111761#issuecomment-1557777314
+macro_rules! m {
+    () => {
+        extern crate core as std;
+        //~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern`
+    }
+}
+
+m!();
+
+use std::mem;
+
+fn main() {}
diff --git a/tests/ui/imports/issue-109148.stderr b/tests/ui/imports/issue-109148.stderr
new file mode 100644
index 00000000000..6cc1221cfe9
--- /dev/null
+++ b/tests/ui/imports/issue-109148.stderr
@@ -0,0 +1,13 @@
+error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`
+  --> $DIR/issue-109148.rs:6:9
+   |
+LL |         extern crate core as std;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | m!();
+   | ---- in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/tests/ui/issues/issue-18107.stderr b/tests/ui/issues/issue-18107.stderr
index 1669b550a9b..cf4e06316a7 100644
--- a/tests/ui/issues/issue-18107.stderr
+++ b/tests/ui/issues/issue-18107.stderr
@@ -4,14 +4,18 @@ error[E0746]: return type cannot have an unboxed trait object
 LL |     dyn AbstractRenderer
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-help: use `impl AbstractRenderer` as the return type if all return paths have the same type but you want to expose only the trait in the signature
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL |     impl AbstractRenderer
+   |     ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-help: use a boxed trait object if all return paths implement trait `AbstractRenderer`
+LL ~     Box<dyn AbstractRenderer>
+LL |
+LL | {
+LL |     match 0 {
+LL ~         _ => Box::new(unimplemented!())
    |
-LL |     Box<dyn AbstractRenderer>
-   |     ++++                    +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/iterators/collect-into-slice.rs b/tests/ui/iterators/collect-into-slice.rs
index 5a8aacb1a6d..045d40a6f71 100644
--- a/tests/ui/iterators/collect-into-slice.rs
+++ b/tests/ui/iterators/collect-into-slice.rs
@@ -14,4 +14,10 @@ fn main() {
     //~| NOTE doesn't have a size known at compile-time
     //~| NOTE doesn't have a size known at compile-time
     process_slice(&some_generated_vec);
+
+    let some_generated_vec = (0..10).collect();
+    //~^ ERROR a slice of type `&[i32]` cannot be built since we need to store the elements somewhere
+    //~| NOTE try explicitly collecting into a `Vec<{integer}>`
+    //~| NOTE required by a bound in `collect`
+    process_slice(some_generated_vec);
 }
diff --git a/tests/ui/iterators/collect-into-slice.stderr b/tests/ui/iterators/collect-into-slice.stderr
index 29fff8c51c6..07dc561f06a 100644
--- a/tests/ui/iterators/collect-into-slice.stderr
+++ b/tests/ui/iterators/collect-into-slice.stderr
@@ -28,6 +28,16 @@ LL |     let some_generated_vec = (0..10).collect();
 note: required by a bound in `collect`
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 
-error: aborting due to 3 previous errors
+error[E0277]: a slice of type `&[i32]` cannot be built since we need to store the elements somewhere
+  --> $DIR/collect-into-slice.rs:18:38
+   |
+LL |     let some_generated_vec = (0..10).collect();
+   |                                      ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
+   |
+   = help: the trait `FromIterator<{integer}>` is not implemented for `&[i32]`
+note: required by a bound in `collect`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/lint/drop_copy.rs b/tests/ui/lint/dropping_copy_types.rs
index 0adcd34505f..2937320e5d8 100644
--- a/tests/ui/lint/drop_copy.rs
+++ b/tests/ui/lint/dropping_copy_types.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![warn(drop_copy)]
+#![warn(dropping_copy_types)]
 
 use std::mem::drop;
 use std::vec::Vec;
diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/dropping_copy_types.stderr
index db8e89ad295..b6291aa5ed6 100644
--- a/tests/ui/lint/drop_copy.stderr
+++ b/tests/ui/lint/dropping_copy_types.stderr
@@ -1,5 +1,5 @@
 warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
-  --> $DIR/drop_copy.rs:34:5
+  --> $DIR/dropping_copy_types.rs:34:5
    |
 LL |     drop(s1);
    |     ^^^^^--^
@@ -8,13 +8,13 @@ LL |     drop(s1);
    |
    = note: use `let _ = ...` to ignore the expression or result
 note: the lint level is defined here
-  --> $DIR/drop_copy.rs:3:9
+  --> $DIR/dropping_copy_types.rs:3:9
    |
-LL | #![warn(drop_copy)]
-   |         ^^^^^^^^^
+LL | #![warn(dropping_copy_types)]
+   |         ^^^^^^^^^^^^^^^^^^^
 
 warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
-  --> $DIR/drop_copy.rs:35:5
+  --> $DIR/dropping_copy_types.rs:35:5
    |
 LL |     drop(s2);
    |     ^^^^^--^
@@ -24,7 +24,7 @@ LL |     drop(s2);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_copy.rs:36:5
+  --> $DIR/dropping_copy_types.rs:36:5
    |
 LL |     drop(s3);
    |     ^^^^^--^
@@ -32,10 +32,10 @@ LL |     drop(s3);
    |          argument has type `&SomeStruct`
    |
    = note: use `let _ = ...` to ignore the expression or result
-   = note: `#[warn(drop_ref)]` on by default
+   = note: `#[warn(dropping_references)]` on by default
 
 warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
-  --> $DIR/drop_copy.rs:37:5
+  --> $DIR/dropping_copy_types.rs:37:5
    |
 LL |     drop(s4);
    |     ^^^^^--^
@@ -45,7 +45,7 @@ LL |     drop(s4);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_copy.rs:38:5
+  --> $DIR/dropping_copy_types.rs:38:5
    |
 LL |     drop(s5);
    |     ^^^^^--^
@@ -55,7 +55,7 @@ LL |     drop(s5);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_copy.rs:50:5
+  --> $DIR/dropping_copy_types.rs:50:5
    |
 LL |     drop(a2);
    |     ^^^^^--^
@@ -65,7 +65,7 @@ LL |     drop(a2);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_copy.rs:52:5
+  --> $DIR/dropping_copy_types.rs:52:5
    |
 LL |     drop(a4);
    |     ^^^^^--^
@@ -75,7 +75,7 @@ LL |     drop(a4);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
-  --> $DIR/drop_copy.rs:71:13
+  --> $DIR/dropping_copy_types.rs:71:13
    |
 LL |             drop(println_and(13));
    |             ^^^^^---------------^
@@ -85,7 +85,7 @@ LL |             drop(println_and(13));
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
-  --> $DIR/drop_copy.rs:74:14
+  --> $DIR/dropping_copy_types.rs:74:14
    |
 LL |         3 if drop(println_and(14)) == () => (),
    |              ^^^^^---------------^
@@ -95,7 +95,7 @@ LL |         3 if drop(println_and(14)) == () => (),
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
-  --> $DIR/drop_copy.rs:76:14
+  --> $DIR/dropping_copy_types.rs:76:14
    |
 LL |         4 => drop(2),
    |              ^^^^^-^
diff --git a/tests/ui/lint/drop_ref.rs b/tests/ui/lint/dropping_references.rs
index db4f7569f6f..0d5d484f451 100644
--- a/tests/ui/lint/drop_ref.rs
+++ b/tests/ui/lint/dropping_references.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![warn(drop_ref)]
+#![warn(dropping_references)]
 
 struct SomeStruct;
 
diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/dropping_references.stderr
index 04c988fe99d..7e25a46216e 100644
--- a/tests/ui/lint/drop_ref.stderr
+++ b/tests/ui/lint/dropping_references.stderr
@@ -1,5 +1,5 @@
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:8:5
+  --> $DIR/dropping_references.rs:8:5
    |
 LL |     drop(&SomeStruct);
    |     ^^^^^-----------^
@@ -8,13 +8,13 @@ LL |     drop(&SomeStruct);
    |
    = note: use `let _ = ...` to ignore the expression or result
 note: the lint level is defined here
-  --> $DIR/drop_ref.rs:3:9
+  --> $DIR/dropping_references.rs:3:9
    |
-LL | #![warn(drop_ref)]
-   |         ^^^^^^^^
+LL | #![warn(dropping_references)]
+   |         ^^^^^^^^^^^^^^^^^^^
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:11:5
+  --> $DIR/dropping_references.rs:11:5
    |
 LL |     drop(&owned1);
    |     ^^^^^-------^
@@ -24,7 +24,7 @@ LL |     drop(&owned1);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:12:5
+  --> $DIR/dropping_references.rs:12:5
    |
 LL |     drop(&&owned1);
    |     ^^^^^--------^
@@ -34,7 +34,7 @@ LL |     drop(&&owned1);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:13:5
+  --> $DIR/dropping_references.rs:13:5
    |
 LL |     drop(&mut owned1);
    |     ^^^^^-----------^
@@ -44,7 +44,7 @@ LL |     drop(&mut owned1);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:17:5
+  --> $DIR/dropping_references.rs:17:5
    |
 LL |     drop(reference1);
    |     ^^^^^----------^
@@ -54,7 +54,7 @@ LL |     drop(reference1);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:20:5
+  --> $DIR/dropping_references.rs:20:5
    |
 LL |     drop(reference2);
    |     ^^^^^----------^
@@ -64,7 +64,7 @@ LL |     drop(reference2);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:23:5
+  --> $DIR/dropping_references.rs:23:5
    |
 LL |     drop(reference3);
    |     ^^^^^----------^
@@ -74,7 +74,7 @@ LL |     drop(reference3);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:28:5
+  --> $DIR/dropping_references.rs:28:5
    |
 LL |     drop(&val);
    |     ^^^^^----^
@@ -84,7 +84,7 @@ LL |     drop(&val);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:36:5
+  --> $DIR/dropping_references.rs:36:5
    |
 LL |     std::mem::drop(&SomeStruct);
    |     ^^^^^^^^^^^^^^^-----------^
@@ -94,7 +94,7 @@ LL |     std::mem::drop(&SomeStruct);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:91:13
+  --> $DIR/dropping_references.rs:91:13
    |
 LL |             drop(println_and(&13));
    |             ^^^^^----------------^
@@ -104,7 +104,7 @@ LL |             drop(println_and(&13));
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:94:14
+  --> $DIR/dropping_references.rs:94:14
    |
 LL |         3 if drop(println_and(&14)) == () => (),
    |              ^^^^^----------------^
@@ -114,7 +114,7 @@ LL |         3 if drop(println_and(&14)) == () => (),
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
-  --> $DIR/drop_ref.rs:96:14
+  --> $DIR/dropping_references.rs:96:14
    |
 LL |         4 => drop(&2),
    |              ^^^^^--^
diff --git a/tests/ui/lint/forget_copy.rs b/tests/ui/lint/forgetting_copy_types.rs
index a6b17b76971..224c7bcd5f6 100644
--- a/tests/ui/lint/forget_copy.rs
+++ b/tests/ui/lint/forgetting_copy_types.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![warn(forget_copy)]
+#![warn(forgetting_copy_types)]
 
 use std::mem::forget;
 use std::vec::Vec;
diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forgetting_copy_types.stderr
index 37bc8a8854e..36d1ef5c53e 100644
--- a/tests/ui/lint/forget_copy.stderr
+++ b/tests/ui/lint/forgetting_copy_types.stderr
@@ -1,5 +1,5 @@
 warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
-  --> $DIR/forget_copy.rs:34:5
+  --> $DIR/forgetting_copy_types.rs:34:5
    |
 LL |     forget(s1);
    |     ^^^^^^^--^
@@ -8,13 +8,13 @@ LL |     forget(s1);
    |
    = note: use `let _ = ...` to ignore the expression or result
 note: the lint level is defined here
-  --> $DIR/forget_copy.rs:3:9
+  --> $DIR/forgetting_copy_types.rs:3:9
    |
-LL | #![warn(forget_copy)]
-   |         ^^^^^^^^^^^
+LL | #![warn(forgetting_copy_types)]
+   |         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
-  --> $DIR/forget_copy.rs:35:5
+  --> $DIR/forgetting_copy_types.rs:35:5
    |
 LL |     forget(s2);
    |     ^^^^^^^--^
@@ -24,7 +24,7 @@ LL |     forget(s2);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_copy.rs:36:5
+  --> $DIR/forgetting_copy_types.rs:36:5
    |
 LL |     forget(s3);
    |     ^^^^^^^--^
@@ -32,10 +32,10 @@ LL |     forget(s3);
    |            argument has type `&SomeStruct`
    |
    = note: use `let _ = ...` to ignore the expression or result
-   = note: `#[warn(forget_ref)]` on by default
+   = note: `#[warn(forgetting_references)]` on by default
 
 warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
-  --> $DIR/forget_copy.rs:37:5
+  --> $DIR/forgetting_copy_types.rs:37:5
    |
 LL |     forget(s4);
    |     ^^^^^^^--^
@@ -45,7 +45,7 @@ LL |     forget(s4);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_copy.rs:38:5
+  --> $DIR/forgetting_copy_types.rs:38:5
    |
 LL |     forget(s5);
    |     ^^^^^^^--^
@@ -55,7 +55,7 @@ LL |     forget(s5);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_copy.rs:50:5
+  --> $DIR/forgetting_copy_types.rs:50:5
    |
 LL |     forget(a2);
    |     ^^^^^^^--^
@@ -65,7 +65,7 @@ LL |     forget(a2);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_copy.rs:52:5
+  --> $DIR/forgetting_copy_types.rs:52:5
    |
 LL |     forget(a3);
    |     ^^^^^^^--^
@@ -75,7 +75,7 @@ LL |     forget(a3);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_copy.rs:53:5
+  --> $DIR/forgetting_copy_types.rs:53:5
    |
 LL |     forget(a4);
    |     ^^^^^^^--^
diff --git a/tests/ui/lint/forget_ref.rs b/tests/ui/lint/forgetting_references.rs
index 13f6d4be3d1..bd51e980031 100644
--- a/tests/ui/lint/forget_ref.rs
+++ b/tests/ui/lint/forgetting_references.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![warn(forget_ref)]
+#![warn(forgetting_references)]
 
 use std::mem::forget;
 
diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forgetting_references.stderr
index 63fc7791980..5624b690789 100644
--- a/tests/ui/lint/forget_ref.stderr
+++ b/tests/ui/lint/forgetting_references.stderr
@@ -1,5 +1,5 @@
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:10:5
+  --> $DIR/forgetting_references.rs:10:5
    |
 LL |     forget(&SomeStruct);
    |     ^^^^^^^-----------^
@@ -8,13 +8,13 @@ LL |     forget(&SomeStruct);
    |
    = note: use `let _ = ...` to ignore the expression or result
 note: the lint level is defined here
-  --> $DIR/forget_ref.rs:3:9
+  --> $DIR/forgetting_references.rs:3:9
    |
-LL | #![warn(forget_ref)]
-   |         ^^^^^^^^^^
+LL | #![warn(forgetting_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:13:5
+  --> $DIR/forgetting_references.rs:13:5
    |
 LL |     forget(&owned);
    |     ^^^^^^^------^
@@ -24,7 +24,7 @@ LL |     forget(&owned);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:14:5
+  --> $DIR/forgetting_references.rs:14:5
    |
 LL |     forget(&&owned);
    |     ^^^^^^^-------^
@@ -34,7 +34,7 @@ LL |     forget(&&owned);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:15:5
+  --> $DIR/forgetting_references.rs:15:5
    |
 LL |     forget(&mut owned);
    |     ^^^^^^^----------^
@@ -44,7 +44,7 @@ LL |     forget(&mut owned);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:19:5
+  --> $DIR/forgetting_references.rs:19:5
    |
 LL |     forget(&*reference1);
    |     ^^^^^^^------------^
@@ -54,7 +54,7 @@ LL |     forget(&*reference1);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:22:5
+  --> $DIR/forgetting_references.rs:22:5
    |
 LL |     forget(reference2);
    |     ^^^^^^^----------^
@@ -64,7 +64,7 @@ LL |     forget(reference2);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:25:5
+  --> $DIR/forgetting_references.rs:25:5
    |
 LL |     forget(reference3);
    |     ^^^^^^^----------^
@@ -74,7 +74,7 @@ LL |     forget(reference3);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:30:5
+  --> $DIR/forgetting_references.rs:30:5
    |
 LL |     forget(&val);
    |     ^^^^^^^----^
@@ -84,7 +84,7 @@ LL |     forget(&val);
    = note: use `let _ = ...` to ignore the expression or result
 
 warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
-  --> $DIR/forget_ref.rs:38:5
+  --> $DIR/forgetting_references.rs:38:5
    |
 LL |     std::mem::forget(&SomeStruct);
    |     ^^^^^^^^^^^^^^^^^-----------^
diff --git a/tests/ui/liveness/liveness-unused.rs b/tests/ui/liveness/liveness-unused.rs
index 8ef6ab1b6ff..ba635e6638c 100644
--- a/tests/ui/liveness/liveness-unused.rs
+++ b/tests/ui/liveness/liveness-unused.rs
@@ -1,7 +1,7 @@
 #![warn(unused)]
 #![deny(unused_variables)]
 #![deny(unused_assignments)]
-#![allow(dead_code, non_camel_case_types, trivial_numeric_casts, drop_copy)]
+#![allow(dead_code, non_camel_case_types, trivial_numeric_casts, dropping_copy_types)]
 
 use std::ops::AddAssign;
 
diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs
index c50dfdf0116..10810388d20 100644
--- a/tests/ui/macros/parse-complex-macro-invoc-op.rs
+++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs
@@ -4,7 +4,7 @@
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 #![allow(stable_features)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 // Test parsing binary operators after macro invocations.
 
diff --git a/tests/ui/never_type/never-assign-dead-code.rs b/tests/ui/never_type/never-assign-dead-code.rs
index e95a992d780..39df7de5a7f 100644
--- a/tests/ui/never_type/never-assign-dead-code.rs
+++ b/tests/ui/never_type/never-assign-dead-code.rs
@@ -3,7 +3,7 @@
 // check-pass
 
 #![feature(never_type)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 #![warn(unused)]
 
 fn main() {
diff --git a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
index 73ceaeeb875..2e9eff59386 100644
--- a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
+++ b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
@@ -5,7 +5,7 @@
 // check-pass
 // compile-flags:-Zno-leak-check
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 {
     panic!()
diff --git a/tests/ui/nll/ty-outlives/projection-body.rs b/tests/ui/nll/ty-outlives/projection-body.rs
index bff9058a507..722d6747102 100644
--- a/tests/ui/nll/ty-outlives/projection-body.rs
+++ b/tests/ui/nll/ty-outlives/projection-body.rs
@@ -3,7 +3,7 @@
 //
 // check-pass
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 trait MyTrait<'a> {
     type Output;
diff --git a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
index c138d99d303..df6aab0e6a8 100644
--- a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
+++ b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
@@ -3,8 +3,8 @@
 // check-pass
 
 #![allow(irrefutable_let_patterns)]
-#![allow(drop_copy)]
-#![allow(drop_ref)]
+#![allow(dropping_copy_types)]
+#![allow(dropping_references)]
 
 fn main() {
     // A regression test for a mistake we made at one point:
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
index 965204bf240..43b53b7cf1f 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
@@ -2,8 +2,8 @@
 
 // Test `@` patterns combined with `box` patterns.
 
-#![allow(drop_ref)]
-#![allow(drop_copy)]
+#![allow(dropping_references)]
+#![allow(dropping_copy_types)]
 
 #![feature(box_patterns)]
 
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
index 3eb5d2cbf54..1df51c0edd9 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
@@ -2,7 +2,7 @@
 
 // Test `Copy` bindings in the rhs of `@` patterns.
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 #[derive(Copy, Clone)]
 struct C;
diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
index 0550238549e..204cd3e6657 100644
--- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
+++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 fn main() {}
 
diff --git a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
index 788975d960a..4de1f653db0 100644
--- a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
+++ b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 fn main() {
     struct U;
diff --git a/tests/ui/print_type_sizes/async.rs b/tests/ui/print_type_sizes/async.rs
index c73268dc46a..f38a6e674da 100644
--- a/tests/ui/print_type_sizes/async.rs
+++ b/tests/ui/print_type_sizes/async.rs
@@ -3,7 +3,7 @@
 // build-pass
 // ignore-pass
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 async fn wait() {}
 
diff --git a/tests/ui/print_type_sizes/generator_discr_placement.rs b/tests/ui/print_type_sizes/generator_discr_placement.rs
index a77a03f0a8a..6adc14f9b99 100644
--- a/tests/ui/print_type_sizes/generator_discr_placement.rs
+++ b/tests/ui/print_type_sizes/generator_discr_placement.rs
@@ -6,7 +6,7 @@
 
 // Avoid emitting panic handlers, like the rest of these tests...
 #![feature(generators)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 pub fn foo() {
     let a = || {
diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
index af2bb09805a..0c1e9314441 100644
--- a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
+++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
@@ -3,7 +3,7 @@
 
 // check-pass
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 use std::marker::PhantomData;
 
diff --git a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
index 8f45b989f13..b9ff24c7624 100644
--- a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
+++ b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
@@ -3,7 +3,7 @@
 
 // check-pass
 
-#![allow(drop_ref)]
+#![allow(dropping_references)]
 
 // aux-build:monovariants.rs
 extern crate monovariants;
diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
index 4c1562790d5..542be3942b7 100644
--- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
+++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
@@ -4,7 +4,7 @@
 // Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
 // as well as some compile time properties we expect.
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 #[derive(Copy, Clone, Debug)]
 struct Unit;
diff --git a/tests/ui/rust-2018/remove-extern-crate.fixed b/tests/ui/rust-2018/remove-extern-crate.fixed
index 4ed4d610025..209b91af1dd 100644
--- a/tests/ui/rust-2018/remove-extern-crate.fixed
+++ b/tests/ui/rust-2018/remove-extern-crate.fixed
@@ -5,7 +5,7 @@
 // compile-flags:--extern remove_extern_crate
 
 #![warn(rust_2018_idioms)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
  //~ WARNING unused extern crate
 // Shouldn't suggest changing to `use`, as `another_name`
diff --git a/tests/ui/rust-2018/remove-extern-crate.rs b/tests/ui/rust-2018/remove-extern-crate.rs
index 5dafdb2b7b7..ef3c2db696a 100644
--- a/tests/ui/rust-2018/remove-extern-crate.rs
+++ b/tests/ui/rust-2018/remove-extern-crate.rs
@@ -5,7 +5,7 @@
 // compile-flags:--extern remove_extern_crate
 
 #![warn(rust_2018_idioms)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 extern crate core; //~ WARNING unused extern crate
 // Shouldn't suggest changing to `use`, as `another_name`
diff --git a/tests/ui/self/arbitrary-self-from-method-substs.rs b/tests/ui/self/arbitrary-self-from-method-substs.rs
new file mode 100644
index 00000000000..0f911a20842
--- /dev/null
+++ b/tests/ui/self/arbitrary-self-from-method-substs.rs
@@ -0,0 +1,16 @@
+#![feature(arbitrary_self_types)]
+
+use std::ops::Deref;
+
+struct Foo(u32);
+impl Foo {
+    fn get<R: Deref<Target=Self>>(self: R) -> u32 {
+        self.0
+    }
+}
+
+fn main() {
+    let mut foo = Foo(1);
+    foo.get::<&Foo>();
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/self/arbitrary-self-from-method-substs.stderr b/tests/ui/self/arbitrary-self-from-method-substs.stderr
new file mode 100644
index 00000000000..6c252fadf46
--- /dev/null
+++ b/tests/ui/self/arbitrary-self-from-method-substs.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/arbitrary-self-from-method-substs.rs:14:5
+   |
+LL |     foo.get::<&Foo>();
+   |     ^^^ expected `&Foo`, found `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/statics/issue-91050-1.rs b/tests/ui/statics/issue-91050-1.rs
index f59bcf0b803..c6268dba567 100644
--- a/tests/ui/statics/issue-91050-1.rs
+++ b/tests/ui/statics/issue-91050-1.rs
@@ -12,7 +12,7 @@
 //
 // In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!"
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 pub mod before {
     #[no_mangle]
diff --git a/tests/ui/traits/copy-guessing.rs b/tests/ui/traits/copy-guessing.rs
index c1ed4c28a03..af25010e3bd 100644
--- a/tests/ui/traits/copy-guessing.rs
+++ b/tests/ui/traits/copy-guessing.rs
@@ -1,5 +1,5 @@
 #![allow(dead_code)]
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 // "guessing" in trait selection can affect `copy_or_move`. Check that this
 // is correctly handled. I am not sure what is the "correct" behaviour,
diff --git a/tests/ui/traits/cycle-cache-err-60010.stderr b/tests/ui/traits/cycle-cache-err-60010.stderr
index 2ff16b4af38..aee41c43aef 100644
--- a/tests/ui/traits/cycle-cache-err-60010.stderr
+++ b/tests/ui/traits/cycle-cache-err-60010.stderr
@@ -1,9 +1,25 @@
-error[E0275]: overflow evaluating the requirement `RootDatabase: RefUnwindSafe`
+error[E0275]: overflow evaluating the requirement `SalsaStorage: RefUnwindSafe`
   --> $DIR/cycle-cache-err-60010.rs:27:13
    |
 LL |     _parse: <ParseQuery as Query<RootDatabase>>::Data,
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+note: required because it appears within the type `PhantomData<SalsaStorage>`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+note: required because it appears within the type `Unique<SalsaStorage>`
+  --> $SRC_DIR/core/src/ptr/unique.rs:LL:COL
+note: required because it appears within the type `Box<SalsaStorage>`
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+note: required because it appears within the type `Runtime<RootDatabase>`
+  --> $DIR/cycle-cache-err-60010.rs:23:8
+   |
+LL | struct Runtime<DB: Database> {
+   |        ^^^^^^^
+note: required because it appears within the type `RootDatabase`
+  --> $DIR/cycle-cache-err-60010.rs:20:8
+   |
+LL | struct RootDatabase {
+   |        ^^^^^^^^^^^^
 note: required for `RootDatabase` to implement `SourceDatabase`
   --> $DIR/cycle-cache-err-60010.rs:44:9
    |
diff --git a/tests/ui/traits/impl-evaluation-order.rs b/tests/ui/traits/impl-evaluation-order.rs
index 256ce992eef..2ce0b6b0df8 100644
--- a/tests/ui/traits/impl-evaluation-order.rs
+++ b/tests/ui/traits/impl-evaluation-order.rs
@@ -6,7 +6,7 @@
 
 // check-pass
 
-#![allow(drop_copy)]
+#![allow(dropping_copy_types)]
 
 trait A {
     type B;
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
index f115e143318..e311a4af2f4 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
@@ -14,7 +14,7 @@ async fn foo() {
     #[cfg(fail)]
     let x = &NotSync;
     bar().await;
-    #[allow(drop_ref)]
+    #[allow(dropping_references)]
     drop(x);
 }
 
diff --git a/tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs b/tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs
new file mode 100644
index 00000000000..d70534feb07
--- /dev/null
+++ b/tests/ui/traits/new-solver/normalize-rcvr-for-inherent.rs
@@ -0,0 +1,25 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+// Verify that we can assemble inherent impl candidates on a possibly
+// unnormalized self type.
+
+trait Foo {
+    type Assoc;
+}
+impl Foo for i32 {
+    type Assoc = Bar;
+}
+
+struct Bar;
+impl Bar {
+    fn method(&self) {}
+}
+
+fn build<T: Foo>(_: T) -> T::Assoc {
+    todo!()
+}
+
+fn main() {
+    build(1i32).method();
+}
diff --git a/tests/ui/traits/new-solver/structural-resolve-field.rs b/tests/ui/traits/new-solver/structural-resolve-field.rs
new file mode 100644
index 00000000000..01899c9ad64
--- /dev/null
+++ b/tests/ui/traits/new-solver/structural-resolve-field.rs
@@ -0,0 +1,13 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+#[derive(Default)]
+struct Foo {
+    x: i32,
+}
+
+fn main() {
+    let mut xs = <[Foo; 1]>::default();
+    xs[0].x = 1;
+    (&mut xs[0]).x = 2;
+}
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
new file mode 100644
index 00000000000..d37943b929a
--- /dev/null
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
@@ -0,0 +1,34 @@
+//~ ERROR overflow
+// A regression test for #111729 checking that we correctly
+// track recursion depth for obligations returned by confirmation.
+use std::panic::RefUnwindSafe;
+
+trait Database {
+    type Storage;
+}
+trait Query<DB> {
+    type Data;
+}
+struct ParseQuery;
+struct RootDatabase {
+    _runtime: Runtime<RootDatabase>,
+}
+
+impl<T: RefUnwindSafe> Database for T {
+    type Storage = SalsaStorage;
+}
+impl Database for RootDatabase {
+    type Storage = SalsaStorage;
+}
+
+struct Runtime<DB: Database> {
+    _storage: Box<DB::Storage>,
+}
+struct SalsaStorage {
+    _parse: <ParseQuery as Query<RootDatabase>>::Data,
+}
+
+impl<DB: Database> Query<DB> for ParseQuery {
+    type Data = RootDatabase;
+}
+fn main() {}
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
new file mode 100644
index 00000000000..8f9ce3ef1e9
--- /dev/null
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
@@ -0,0 +1,24 @@
+error[E0275]: overflow evaluating the requirement `Runtime<RootDatabase>: RefUnwindSafe`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_via_builtin_auto_trait_impl`)
+note: required because it appears within the type `RootDatabase`
+  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:13:8
+   |
+LL | struct RootDatabase {
+   |        ^^^^^^^^^^^^
+note: required for `RootDatabase` to implement `Database`
+  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:17:24
+   |
+LL | impl<T: RefUnwindSafe> Database for T {
+   |         -------------  ^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required because it appears within the type `Runtime<RootDatabase>`
+  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:24:8
+   |
+LL | struct Runtime<DB: Database> {
+   |        ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
index 6ed7667115a..f98c3164d7e 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
@@ -2,7 +2,7 @@
 // Check tautalogically false `Copy` bounds
 
 #![feature(trivial_bounds)]
-#![allow(drop_ref, drop_copy)]
+#![allow(dropping_references, dropping_copy_types)]
 
 fn copy_string(t: String) -> String where String: Copy { //~ WARNING trivial_bounds
     is_copy(&t);
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
new file mode 100644
index 00000000000..e5bfbfdae91
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+
+type Tait<'a> = impl Sized + 'a;
+
+fn foo<'a, 'b>() {
+    if false {
+        if { return } {
+            let y: Tait<'b> = 1i32;
+            //~^ ERROR concrete type differs from previous defining opaque type use
+        }
+    }
+    let x: Tait<'a> = ();
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
new file mode 100644
index 00000000000..f2eb7bc4dc7
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/different_defining_uses_never_type-2.rs:8:31
+   |
+LL |             let y: Tait<'b> = 1i32;
+   |                               ^^^^ expected `()`, got `i32`
+   |
+note: previous use here
+  --> $DIR/different_defining_uses_never_type-2.rs:12:23
+   |
+LL |     let x: Tait<'a> = ();
+   |                       ^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs
new file mode 100644
index 00000000000..2b30a9cd57c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+
+type Tait<T> = impl Sized;
+
+fn foo<T, U>() {
+    if false {
+        if { return } {
+            let y: Tait<U> = 1i32;
+            //~^ ERROR concrete type differs from previous defining opaque type use
+        }
+    }
+    let x: Tait<T> = ();
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
new file mode 100644
index 00000000000..8fc2e22848c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/different_defining_uses_never_type-3.rs:8:30
+   |
+LL |             let y: Tait<U> = 1i32;
+   |                              ^^^^ expected `()`, got `i32`
+   |
+note: previous use here
+  --> $DIR/different_defining_uses_never_type-3.rs:12:22
+   |
+LL |     let x: Tait<T> = ();
+   |                      ^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
index da845e86147..9ae2c34b935 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
@@ -8,6 +8,7 @@ type X<A, B> = impl Into<&'static A>;
 
 fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
     //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied
+    //~| ERROR concrete type differs from previous defining opaque type use
     (a, a)
 }
 
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
index 66a6b0bbf74..0d24d42ba62 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
@@ -10,6 +10,15 @@ help: consider introducing a `where` clause, but there might be an alternative b
 LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
    |                                                                ++++++++++++++++++++++++++
 
-error: aborting due to previous error
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/multiple-def-uses-in-one-fn.rs:9:45
+   |
+LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
+   |                                             ^^^^^^^^^^^^^^^^^^
+   |                                             |
+   |                                             expected `&B`, got `&A`
+   |                                             this expression supplies two conflicting concrete types for the same opaque type
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/issue-67981.rs b/tests/ui/unsized-locals/issue-67981.rs
new file mode 100644
index 00000000000..3eb6498e9dc
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-67981.rs
@@ -0,0 +1,9 @@
+#![feature(unsized_fn_params)]
+
+fn main() {
+    let f: fn([u8]) = |_| {};
+    //~^ERROR the size for values of type `[u8]` cannot be known at compilation time
+    let slice: Box<[u8]> = Box::new([1; 8]);
+
+    f(*slice);
+}
diff --git a/tests/ui/unsized-locals/issue-67981.stderr b/tests/ui/unsized-locals/issue-67981.stderr
new file mode 100644
index 00000000000..a4b179ae2fd
--- /dev/null
+++ b/tests/ui/unsized-locals/issue-67981.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/issue-67981.rs:4:24
+   |
+LL |     let f: fn([u8]) = |_| {};
+   |                        ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL |     let f: fn([u8]) = |&_| {};
+   |                        +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized/box-instead-of-dyn-fn.rs b/tests/ui/unsized/box-instead-of-dyn-fn.rs
index 2fa741bc1c5..321c2ebf5a1 100644
--- a/tests/ui/unsized/box-instead-of-dyn-fn.rs
+++ b/tests/ui/unsized/box-instead-of-dyn-fn.rs
@@ -8,7 +8,6 @@ fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a {
         move || println!("{a}")
     } else {
         Box::new(move || println!("{}", b))
-        //~^ ERROR `if` and `else` have incompatible types
     }
 }
 
diff --git a/tests/ui/unsized/box-instead-of-dyn-fn.stderr b/tests/ui/unsized/box-instead-of-dyn-fn.stderr
index bfb7c3957f4..6087f5c5465 100644
--- a/tests/ui/unsized/box-instead-of-dyn-fn.stderr
+++ b/tests/ui/unsized/box-instead-of-dyn-fn.stderr
@@ -1,42 +1,21 @@
-error[E0308]: `if` and `else` have incompatible types
-  --> $DIR/box-instead-of-dyn-fn.rs:10:9
-   |
-LL | /     if a % 2 == 0 {
-LL | |         move || println!("{a}")
-   | |         -----------------------
-   | |         |
-   | |         the expected closure
-   | |         expected because of this
-LL | |     } else {
-LL | |         Box::new(move || println!("{}", b))
-   | |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found `Box<[closure@box-instead-of-dyn-fn.rs:10:18]>`
-LL | |
-LL | |     }
-   | |_____- `if` and `else` have incompatible types
-   |
-   = note: expected closure `[closure@$DIR/box-instead-of-dyn-fn.rs:8:9: 8:16]`
-               found struct `Box<[closure@$DIR/box-instead-of-dyn-fn.rs:10:18: 10:25]>`
-
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/box-instead-of-dyn-fn.rs:5:56
    |
 LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a {
    |                                                        ^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types>
-   = note: if all the returned values were of the same type you could use `impl Fn() + 'a` as the return type
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-   = note: you can create a new `enum` with a variant for each returned type
-help: return a boxed trait object instead
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
+   |
+LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> impl Fn() + 'a {
+   |                                                        ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> Box<dyn Fn() + 'a> {
-   |                                                        ++++             +
-help: ... and box this value
+LL ~ fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> Box<dyn Fn() + 'a> {
+LL |
+LL |     if a % 2 == 0 {
+LL ~         Box::new(move || println!("{a}"))
    |
-LL |         Box::new(move || println!("{a}"))
-   |         +++++++++                       +
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0308, E0746.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0746`.
diff --git a/tests/ui/unsized/issue-91801.stderr b/tests/ui/unsized/issue-91801.stderr
index 8795aa1687f..da5c4322403 100644
--- a/tests/ui/unsized/issue-91801.stderr
+++ b/tests/ui/unsized/issue-91801.stderr
@@ -4,11 +4,10 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> {
    |                                                                             ^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a` as the return type, as all return paths are of type `Box<[closure@$DIR/issue-91801.rs:10:21: 10:70]>`, which implements `Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a`
+help: box the return type, and wrap all of the returned values in `Box::new`
    |
-LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> impl Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a {
-   |                                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box<Validator<'a>> {
+   |                                                                             ++++             +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/unsized/issue-91803.stderr b/tests/ui/unsized/issue-91803.stderr
index 2dad9e89294..a43b8d0741f 100644
--- a/tests/ui/unsized/issue-91803.stderr
+++ b/tests/ui/unsized/issue-91803.stderr
@@ -4,11 +4,14 @@ error[E0746]: return type cannot have an unboxed trait object
 LL | fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> {
    |                                           ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Foo<'a>` as the return type, as all return paths are of type `Box<_>`, which implements `Foo<'a>`
+help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type
    |
 LL | fn or<'a>(first: &'static dyn Foo<'a>) -> impl Foo<'a> {
-   |                                           ~~~~~~~~~~~~
+   |                                           ~~~~
+help: box the return type, and wrap all of the returned values in `Box::new`
+   |
+LL | fn or<'a>(first: &'static dyn Foo<'a>) -> Box<dyn Foo<'a>> {
+   |                                           ++++           +
 
 error: aborting due to previous error
 
diff --git a/triagebot.toml b/triagebot.toml
index 046d732bd42..d7cd3ea1275 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -482,7 +482,6 @@ compiler-team = [
     "@petrochenkov",
     "@davidtwco",
     "@oli-obk",
-    "@lcnr",
     "@wesleywiser",
 ]
 compiler-team-contributors = [
@@ -593,6 +592,7 @@ style-team = [
 "/compiler/rustc_llvm" =                     ["@cuviper"]
 "/compiler/rustc_middle/src/mir" =           ["compiler", "mir"]
 "/compiler/rustc_middle/src/traits" =        ["compiler", "types"]
+"/compiler/rustc_middle/src/ty" =            ["compiler", "types"]
 "/compiler/rustc_const_eval/src/interpret" = ["compiler", "mir"]
 "/compiler/rustc_const_eval/src/transform" = ["compiler", "mir-opt"]
 "/compiler/rustc_mir_build/src/build" =      ["compiler", "mir"]