about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock50
-rw-r--r--RELEASES.md14
-rw-r--r--compiler/rustc_abi/src/lib.rs2
-rw-r--r--compiler/rustc_arena/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/ast.rs4
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs3
-rw-r--r--compiler/rustc_ast/src/token.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs12
-rw-r--r--compiler/rustc_ast_passes/messages.ftl12
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs85
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs27
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs8
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs6
-rw-r--r--compiler/rustc_attr/src/builtin.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs179
-rw-r--r--compiler/rustc_borrowck/src/invalidation.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs35
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs76
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs149
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs25
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs19
-rw-r--r--compiler/rustc_const_eval/src/util/alignment.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs2
-rw-r--r--compiler/rustc_data_structures/src/lib.rs2
-rw-r--r--compiler/rustc_data_structures/src/memmap.rs7
-rw-r--r--compiler/rustc_data_structures/src/sharded.rs88
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs6
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs49
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0191.md6
-rw-r--r--compiler/rustc_error_messages/src/lib.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs20
-rw-r--r--compiler/rustc_expand/src/lib.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs14
-rw-r--r--compiler/rustc_hir/src/lang_items.rs1
-rw-r--r--compiler/rustc_hir/src/lib.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs53
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs84
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs6
-rw-r--r--compiler/rustc_index/src/lib.rs14
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl13
-rw-r--r--compiler/rustc_lint/src/context.rs50
-rw-r--r--compiler/rustc_lint/src/errors.rs42
-rw-r--r--compiler/rustc_lint/src/levels.rs54
-rw-r--r--compiler/rustc_lint/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/lints.rs20
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs64
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs42
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs7
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp5
-rw-r--r--compiler/rustc_macros/src/lib.rs2
-rw-r--r--compiler/rustc_middle/src/lib.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs19
-rw-r--r--compiler/rustc_middle/src/mir/patch.rs25
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs17
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs97
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs4
-rw-r--r--compiler/rustc_mir_build/src/lints.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs45
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs2
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs2
-rw-r--r--compiler/rustc_mir_transform/src/add_call_guards.rs6
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs2
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dead_store_elimination.rs6
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs12
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs6
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs8
-rw-r--r--compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs2
-rw-r--r--compiler/rustc_mir_transform/src/separate_const_switch.rs4
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs14
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs32
-rw-r--r--compiler/rustc_parse/src/lib.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs8
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs46
-rw-r--r--compiler/rustc_passes/messages.ftl2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs1
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs10
-rw-r--r--compiler/rustc_query_impl/src/lib.rs2
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs2
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs17
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/ident.rs66
-rw-r--r--compiler/rustc_resolve/src/late.rs79
-rw-r--r--compiler/rustc_resolve/src/lib.rs110
-rw-r--r--compiler/rustc_resolve/src/macros.rs19
-rw-r--r--compiler/rustc_session/messages.ftl3
-rw-r--r--compiler/rustc_session/src/errors.rs6
-rw-r--r--compiler/rustc_session/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/parse.rs17
-rw-r--r--compiler/rustc_session/src/utils.rs47
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs8
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs371
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs56
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs22
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs136
-rw-r--r--compiler/rustc_span/src/hygiene.rs126
-rw-r--r--compiler/rustc_span/src/lib.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs13
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs17
-rw-r--r--compiler/rustc_target/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs1
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--library/alloc/src/lib.rs5
-rw-r--r--library/alloc/src/rc.rs2
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/sync.rs2
-rw-r--r--library/alloc/tests/vec.rs1
m---------library/backtrace0
-rw-r--r--library/core/src/cell.rs3
-rw-r--r--library/core/src/convert/num.rs4
-rw-r--r--library/core/src/intrinsics.rs16
-rw-r--r--library/core/src/intrinsics/mir.rs6
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/core/src/mem/mod.rs4
-rw-r--r--library/core/src/num/uint_macros.rs12
-rw-r--r--library/core/src/panicking.rs19
-rw-r--r--library/core/src/ptr/mod.rs3
-rw-r--r--library/core/src/ptr/non_null.rs2
-rw-r--r--library/core/src/str/mod.rs2
-rw-r--r--library/core/src/str/traits.rs2
-rw-r--r--library/panic_abort/src/lib.rs2
-rw-r--r--library/panic_unwind/src/lib.rs3
-rw-r--r--library/proc_macro/src/lib.rs2
-rw-r--r--library/profiler_builtins/src/lib.rs2
-rw-r--r--library/std/src/f32.rs5
-rw-r--r--library/std/src/f64.rs5
-rw-r--r--library/std/src/ffi/mod.rs2
-rw-r--r--library/std/src/fs.rs9
-rw-r--r--library/std/src/io/error.rs10
-rw-r--r--library/std/src/io/mod.rs14
-rw-r--r--library/std/src/io/util.rs4
-rw-r--r--library/std/src/keyword_docs.rs10
-rw-r--r--library/std/src/lib.rs4
-rw-r--r--library/std/src/os/unix/fs.rs6
-rw-r--r--library/std/src/process.rs2
-rw-r--r--library/std/src/sys/itron/error.rs5
-rw-r--r--library/std/src/sys/sgx/mod.rs6
-rw-r--r--library/std/src/sys/solid/error.rs5
-rw-r--r--library/std/src/sys/solid/mod.rs5
-rw-r--r--library/std/src/sys/solid/net.rs6
-rw-r--r--library/std/src/sys/solid/os.rs2
-rw-r--r--library/std/src/sys/unix/mod.rs5
-rw-r--r--library/std/src/sys/unsupported/common.rs4
-rw-r--r--library/std/src/sys/wasi/mod.rs5
-rw-r--r--library/std/src/sys/wasi/thread.rs8
-rw-r--r--library/std/src/sys/windows/mod.rs5
-rw-r--r--library/std/src/thread/local.rs18
-rw-r--r--library/test/src/lib.rs2
-rw-r--r--library/unwind/src/lib.rs2
-rw-r--r--src/bootstrap/bootstrap.py26
-rw-r--r--src/bootstrap/config.rs7
-rw-r--r--src/bootstrap/download.rs15
-rw-r--r--src/bootstrap/test.rs12
-rw-r--r--src/bootstrap/tool.rs2
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile1
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh2
-rwxr-xr-xsrc/ci/docker/scripts/freebsd-toolchain.sh2
-rw-r--r--src/ci/docker/scripts/illumos-toolchain.sh4
-rw-r--r--src/doc/rustc/src/platform-support.md8
-rw-r--r--src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md1
-rw-r--r--src/doc/rustdoc/src/how-to-write-documentation.md13
-rw-r--r--src/librustdoc/clean/inline.rs8
-rw-r--r--src/librustdoc/clean/mod.rs14
-rw-r--r--src/librustdoc/clean/types.rs14
-rw-r--r--src/librustdoc/config.rs4
-rw-r--r--src/librustdoc/fold.rs2
-rw-r--r--src/librustdoc/formats/cache.rs2
-rw-r--r--src/librustdoc/formats/item_type.rs8
-rw-r--r--src/librustdoc/html/render/context.rs3
-rw-r--r--src/librustdoc/html/render/mod.rs24
-rw-r--r--src/librustdoc/html/render/print_item.rs10
-rw-r--r--src/librustdoc/html/render/sidebar.rs8
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css26
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css1
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css1
-rw-r--r--src/librustdoc/html/static/css/themes/light.css1
-rw-r--r--src/librustdoc/html/static/js/main.js2
-rw-r--r--src/librustdoc/json/conversions.rs12
-rw-r--r--src/librustdoc/json/mod.rs2
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs11
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs7
-rw-r--r--src/librustdoc/passes/stripper.rs2
-rw-r--r--src/librustdoc/visit.rs2
m---------src/llvm-project0
-rw-r--r--src/rustdoc-json-types/lib.rs8
-rw-r--r--src/stage0.json738
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.stderr21
-rw-r--r--src/tools/compiletest/src/runtest.rs40
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs12
-rw-r--r--src/tools/jsondoclint/src/validator.rs10
-rw-r--r--src/tools/miri/src/machine.rs22
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.rs13
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr26
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr7
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr7
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr12
-rw-r--r--src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_1.stderr7
-rw-r--r--src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_3.stderr7
-rw-r--r--src/tools/miri/tests/fail/panic/double_panic.stderr4
-rw-r--r--src/tools/rust-analyzer/Cargo.lock12
-rw-r--r--src/tools/rust-analyzer/Cargo.toml5
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/fixture.rs4
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs20
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/db.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/find_path.rs81
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/generics.rs85
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs11
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/import_map.rs42
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs477
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs51
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs27
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs44
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs65
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres.rs72
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs434
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs85
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs80
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs52
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs32
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs82
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs189
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/src.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/builder.rs13
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs53
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs42
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs21
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs48
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs121
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs31
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs102
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs42
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs52
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/attrs.rs183
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs68
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs68
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs91
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/symbols.rs40
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs105
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs190
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs123
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs37
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs71
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs87
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs53
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs145
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs54
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs294
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/defs.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/helpers.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs44
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt203
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs56
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/expand_macro.rs47
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/extend_selection.rs29
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs54
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/highlight_related.rs17
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs107
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/navigation_target.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/signature_help.rs32
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs4
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs1
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/shortcuts.rs13
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast6
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast15
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast17
-rw-r--r--src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast9
-rw-r--r--src/tools/rust-analyzer/crates/profile/src/stop_watch.rs20
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs13
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs7
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs7
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs8
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/lib.rs12
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/fixture.rs2
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc15
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json18
-rw-r--r--src/tools/rust-analyzer/editors/code/src/bootstrap.ts2
-rw-r--r--src/tools/rust-analyzer/editors/code/src/commands.ts7
-rw-r--r--src/tools/rust-analyzer/editors/code/src/config.ts33
-rw-r--r--src/tools/rust-analyzer/editors/code/src/ctx.ts18
-rw-r--r--src/tools/rust-analyzer/editors/code/src/main.ts1
-rw-r--r--src/tools/rust-analyzer/editors/code/src/util.ts9
-rw-r--r--src/tools/rust-analyzer/lib/lsp-server/Cargo.toml5
-rw-r--r--src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs5
-rw-r--r--src/tools/rust-analyzer/xtask/src/metrics.rs4
-rw-r--r--src/tools/rustfmt/src/types.rs2
-rw-r--r--src/tools/rustfmt/tests/target/anonymous-types.rs19
-rw-r--r--src/tools/tidy/src/ui_tests.rs4
-rw-r--r--tests/codegen/asm-maybe-uninit.rs27
-rw-r--r--tests/codegen/box-uninit-bytes.rs (renamed from tests/codegen/box-maybe-uninit.rs)14
-rw-r--r--tests/codegen/debuginfo-inline-callsite-location.rs26
-rw-r--r--tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs12
-rw-r--r--tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir2
-rw-r--r--tests/mir-opt/basic_assignment.main.ElaborateDrops.diff6
-rw-r--r--tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir6
-rw-r--r--tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir6
-rw-r--r--tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir6
-rw-r--r--tests/mir-opt/building/enum_cast.droppy.built.after.mir2
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir6
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir6
-rw-r--r--tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff2
-rw-r--r--tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-abort.diff15
-rw-r--r--tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-unwind.diff15
-rw-r--r--tests/mir-opt/dead-store-elimination/call_arg_copy.rs26
-rw-r--r--tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff2
-rw-r--r--tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff2
-rw-r--r--tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir4
-rw-r--r--tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/cycle.f.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff4
-rw-r--r--tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/unsized_argument.caller.Inline.diff2
-rw-r--r--tests/mir-opt/issue_41110.main.ElaborateDrops.panic-abort.diff8
-rw-r--r--tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff8
-rw-r--r--tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff10
-rw-r--r--tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff10
-rw-r--r--tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff6
-rw-r--r--tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff6
-rw-r--r--tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir4
-rw-r--r--tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir4
-rw-r--r--tests/mir-opt/issue_91633.bar.built.after.mir2
-rw-r--r--tests/mir-opt/issue_91633.foo.built.after.mir2
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff2
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff2
-rw-r--r--tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir2
-rw-r--r--tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir2
-rw-r--r--tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/chained_comparison.rs1
-rw-r--r--tests/mir-opt/pre-codegen/checked_ops.rs1
-rw-r--r--tests/mir-opt/pre-codegen/intrinsics.rs1
-rw-r--r--tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir2
-rw-r--r--tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir2
-rw-r--r--tests/mir-opt/pre-codegen/loops.rs1
-rw-r--r--tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir2
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.rs2
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.rs1
-rw-r--r--tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir4
-rw-r--r--tests/mir-opt/pre-codegen/simple_option_map.rs1
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.rs2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.rs2
-rw-r--r--tests/mir-opt/pre-codegen/try_identity.rs1
-rw-r--r--tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir2
-rw-r--r--tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir2
-rw-r--r--tests/run-coverage-rustdoc/doctest.coverage4
-rw-r--r--tests/run-coverage-rustdoc/doctest.rs4
-rw-r--r--tests/run-coverage/assert.coverage2
-rw-r--r--tests/run-coverage/assert.rs2
-rw-r--r--tests/run-coverage/async2.coverage12
-rw-r--r--tests/run-coverage/async2.rs12
-rw-r--r--tests/run-coverage/auxiliary/inline_always_with_dead_code.rs4
-rw-r--r--tests/run-coverage/auxiliary/unused_mod_helper.rs1
-rw-r--r--tests/run-coverage/auxiliary/used_crate.rs5
-rw-r--r--tests/run-coverage/auxiliary/used_inline_crate.rs11
-rw-r--r--tests/run-coverage/closure.coverage9
-rw-r--r--tests/run-coverage/closure.rs9
-rw-r--r--tests/run-coverage/closure_macro_async.coverage6
-rw-r--r--tests/run-coverage/closure_macro_async.rs6
-rw-r--r--tests/run-coverage/conditions.coverage1
-rw-r--r--tests/run-coverage/conditions.rs1
-rw-r--r--tests/run-coverage/dead_code.coverage2
-rw-r--r--tests/run-coverage/dead_code.rs2
-rw-r--r--tests/run-coverage/drop_trait.coverage2
-rw-r--r--tests/run-coverage/drop_trait.rs2
-rw-r--r--tests/run-coverage/generics.coverage6
-rw-r--r--tests/run-coverage/generics.rs6
-rw-r--r--tests/run-coverage/issue-85461.coverage5
-rw-r--r--tests/run-coverage/issue-85461.rs1
-rw-r--r--tests/run-coverage/issue-93054.coverage14
-rw-r--r--tests/run-coverage/issue-93054.rs14
-rw-r--r--tests/run-coverage/loops_branches.coverage3
-rw-r--r--tests/run-coverage/loops_branches.rs3
-rw-r--r--tests/run-coverage/match_or_pattern.coverage2
-rw-r--r--tests/run-coverage/match_or_pattern.rs2
-rw-r--r--tests/run-coverage/no_cov_crate.coverage2
-rw-r--r--tests/run-coverage/no_cov_crate.rs2
-rw-r--r--tests/run-coverage/overflow.coverage2
-rw-r--r--tests/run-coverage/overflow.rs2
-rw-r--r--tests/run-coverage/try_error_result.coverage14
-rw-r--r--tests/run-coverage/try_error_result.rs14
-rw-r--r--tests/run-coverage/unused.coverage2
-rw-r--r--tests/run-coverage/unused.rs2
-rw-r--r--tests/run-coverage/unused_mod.coverage1
-rw-r--r--tests/run-coverage/uses_crate.coverage5
-rw-r--r--tests/run-coverage/uses_inline_crate.coverage11
-rw-r--r--tests/run-coverage/while_early_ret.coverage2
-rw-r--r--tests/run-coverage/while_early_ret.rs2
-rw-r--r--tests/run-coverage/yield.coverage4
-rw-r--r--tests/run-coverage/yield.rs4
-rw-r--r--tests/run-make/issue-88756-default-output/output-default.stdout2
-rw-r--r--tests/rustdoc-gui/sidebar.goml4
-rw-r--r--tests/rustdoc-gui/src/test_docs/lib.rs12
-rw-r--r--tests/rustdoc-gui/warning-block.goml45
-rw-r--r--tests/rustdoc-json/fn_pointer/abi.rs14
-rw-r--r--tests/rustdoc-json/fn_pointer/generics.rs14
-rw-r--r--tests/rustdoc-json/fn_pointer/qualifiers.rs12
-rw-r--r--tests/rustdoc-json/primitives/primitive_type.rs10
-rw-r--r--tests/rustdoc-json/type/dyn.rs64
-rw-r--r--tests/rustdoc-json/type/fn_lifetime.rs38
-rw-r--r--tests/rustdoc-json/type/generic_default.rs42
-rw-r--r--tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs18
-rw-r--r--tests/rustdoc/html-no-source.rs30
-rw-r--r--tests/rustdoc/issue-105735-overlapping-reexport-2.rs2
-rw-r--r--tests/rustdoc/issue-109449-doc-hidden-reexports.rs6
-rw-r--r--tests/rustdoc/sidebar-all-page.rs5
-rw-r--r--tests/rustdoc/titles.rs2
-rw-r--r--tests/ui/abi/explicit_repr_rust.rs12
-rw-r--r--tests/ui/associated-consts/associated-const-array-len.stderr4
-rw-r--r--tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs2
-rw-r--r--tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr16
-rw-r--r--tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs12
-rw-r--r--tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr24
-rw-r--r--tests/ui/associated-types/issue-44153.stderr4
-rw-r--r--tests/ui/associated-types/substs-ppaux.normal.stderr4
-rw-r--r--tests/ui/associated-types/substs-ppaux.verbose.stderr4
-rw-r--r--tests/ui/backtrace.rs13
-rw-r--r--tests/ui/borrowck/suggest-mut-iterator.fixed30
-rw-r--r--tests/ui/borrowck/suggest-mut-iterator.rs30
-rw-r--r--tests/ui/borrowck/suggest-mut-iterator.stderr16
-rw-r--r--tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr4
-rw-r--r--tests/ui/const-generics/exhaustive-value.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-100313.stderr1
-rw-r--r--tests/ui/consts/assoc-const-elided-lifetime.rs19
-rw-r--r--tests/ui/consts/assoc-const-elided-lifetime.stderr33
-rw-r--r--tests/ui/consts/const-eval/ub-int-array.64bit.stderr36
-rw-r--r--tests/ui/consts/const-eval/ub-int-array.rs8
-rw-r--r--tests/ui/consts/const-eval/ub-int-array.stderr (renamed from tests/ui/consts/const-eval/ub-int-array.32bit.stderr)8
-rw-r--r--tests/ui/consts/missing-larger-array-impl.stderr4
-rw-r--r--tests/ui/consts/std/alloc.32bit.stderr4
-rw-r--r--tests/ui/consts/std/alloc.64bit.stderr4
-rw-r--r--tests/ui/consts/std/alloc.rs1
-rw-r--r--tests/ui/cross-crate/auxiliary/static_init_aux.rs4
-rw-r--r--tests/ui/cross-crate/static-init.rs3
-rw-r--r--tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed2
-rw-r--r--tests/ui/deprecation/issue-84637-deprecated-associated-function.rs2
-rw-r--r--tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-unnamed_fields.rs26
-rw-r--r--tests/ui/feature-gates/feature-gate-unnamed_fields.stderr84
-rw-r--r--tests/ui/generic-const-items/unsatisfied-bounds.stderr4
-rw-r--r--tests/ui/implied-bounds/implied_bounds_entailment_alias_var.rs32
-rw-r--r--tests/ui/issues/issue-39970.stderr4
-rw-r--r--tests/ui/issues/issue-43988.stderr4
-rw-r--r--tests/ui/lint/reference_casting.rs11
-rw-r--r--tests/ui/lint/reference_casting.stderr104
-rw-r--r--tests/ui/macros/issue-2804.rs (renamed from tests/ui/issue-2804.rs)0
-rw-r--r--tests/ui/panics/panic-in-cleanup.rs22
-rw-r--r--tests/ui/panics/panic-in-cleanup.run.stderr10
-rw-r--r--tests/ui/panics/panic-in-ffi.rs17
-rw-r--r--tests/ui/panics/panic-in-ffi.run.stderr7
-rw-r--r--tests/ui/parser/keyword-union-as-identifier.rs72
-rw-r--r--tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr4
-rw-r--r--tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.rs67
-rw-r--r--tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr170
-rw-r--r--tests/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr2
-rw-r--r--tests/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr2
-rw-r--r--tests/ui/repr/invalid_repr_list_help.stderr10
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs18
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr35
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs15
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs16
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs14
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs14
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs16
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs27
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr52
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs18
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs23
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr2
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-6.rs (renamed from tests/ui/issues/issue-17431-6.rs)0
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-6.stderr (renamed from tests/ui/issues/issue-17431-6.stderr)0
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-7.rs (renamed from tests/ui/issues/issue-17431-7.rs)0
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-7.stderr (renamed from tests/ui/issues/issue-17431-7.stderr)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-1.rs (renamed from tests/ui/issues/issue-17431-1.rs)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-1.stderr (renamed from tests/ui/issues/issue-17431-1.stderr)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-2.rs (renamed from tests/ui/issues/issue-17431-2.rs)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-2.stderr (renamed from tests/ui/issues/issue-17431-2.stderr)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-3.rs (renamed from tests/ui/issues/issue-17431-3.rs)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-3.stderr (renamed from tests/ui/issues/issue-17431-3.stderr)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-4.rs (renamed from tests/ui/issues/issue-17431-4.rs)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-4.stderr (renamed from tests/ui/issues/issue-17431-4.stderr)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-5.rs (renamed from tests/ui/issues/issue-17431-5.rs)0
-rw-r--r--tests/ui/structs-enums/struct-rec/issue-17431-5.stderr (renamed from tests/ui/issues/issue-17431-5.stderr)0
-rw-r--r--tests/ui/track-diagnostics/track.rs5
-rw-r--r--tests/ui/track-diagnostics/track.stderr2
-rw-r--r--tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs6
-rw-r--r--tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr13
-rw-r--r--tests/ui/traits/issue-66768.rs (renamed from tests/ui/issues/issue-66768.rs)0
-rw-r--r--tests/ui/traits/suggest-where-clause.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/drop-shim-relates-opaque-issue-114375.rs10
-rw-r--r--tests/ui/typeck/auxiliary/issue-29181.rs (renamed from tests/ui/issues/auxiliary/issue-29181.rs)0
-rw-r--r--tests/ui/typeck/issue-29181.rs (renamed from tests/ui/issues/issue-29181.rs)0
-rw-r--r--tests/ui/typeck/issue-29181.stderr (renamed from tests/ui/issues/issue-29181.stderr)0
-rw-r--r--tests/ui/unevaluated_fixed_size_array_len.stderr4
-rw-r--r--tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs37
-rw-r--r--tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr78
-rw-r--r--tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs37
-rw-r--r--tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr78
-rw-r--r--tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr6
-rw-r--r--tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr6
-rw-r--r--triagebot.toml97
610 files changed, 8935 insertions, 3430 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4ebbb16442e..7337901bc3a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,21 +4,12 @@ version = 3
 
 [[package]]
 name = "addr2line"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
-dependencies = [
- "gimli 0.27.3",
-]
-
-[[package]]
-name = "addr2line"
 version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
 dependencies = [
  "compiler_builtins",
- "gimli 0.28.0",
+ "gimli",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
 ]
@@ -180,7 +171,7 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9792d37ca5173d7e7f4fe453739a0671d0557915a030a383d6b866476bbc3e71"
 dependencies = [
- "object 0.32.0",
+ "object",
 ]
 
 [[package]]
@@ -246,16 +237,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
 name = "backtrace"
-version = "0.3.68"
+version = "0.3.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
+checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
 dependencies = [
- "addr2line 0.20.0",
+ "addr2line",
  "cc",
  "cfg-if",
  "libc",
  "miniz_oxide",
- "object 0.31.1",
+ "object",
  "rustc-demangle",
 ]
 
@@ -1437,12 +1428,6 @@ dependencies = [
 
 [[package]]
 name = "gimli"
-version = "0.27.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
-
-[[package]]
-name = "gimli"
 version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
@@ -2432,15 +2417,6 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.31.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "object"
 version = "0.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe"
@@ -3357,7 +3333,7 @@ dependencies = [
  "cstr",
  "libc",
  "measureme",
- "object 0.32.0",
+ "object",
  "rustc-demangle",
  "rustc_ast",
  "rustc_attr",
@@ -3393,7 +3369,7 @@ dependencies = [
  "itertools",
  "jobserver",
  "libc",
- "object 0.32.0",
+ "object",
  "pathdiff",
  "regex",
  "rustc_arena",
@@ -4327,7 +4303,7 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.3.2",
- "object 0.32.0",
+ "object",
  "rustc_abi",
  "rustc_data_structures",
  "rustc_feature",
@@ -4856,7 +4832,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 name = "std"
 version = "0.0.0"
 dependencies = [
- "addr2line 0.21.0",
+ "addr2line",
  "alloc",
  "cfg-if",
  "compiler_builtins",
@@ -4867,7 +4843,7 @@ dependencies = [
  "hermit-abi 0.3.2",
  "libc",
  "miniz_oxide",
- "object 0.32.0",
+ "object",
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
@@ -5171,9 +5147,9 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4db52ee8fec06e119b692ef3dd2c4cf621a99204c1b8c47407870ed050305b9b"
 dependencies = [
- "gimli 0.28.0",
+ "gimli",
  "hashbrown 0.14.0",
- "object 0.32.0",
+ "object",
  "tracing",
 ]
 
diff --git a/RELEASES.md b/RELEASES.md
index 722f7e5dd08..242b1c2eefd 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -65,16 +65,16 @@ Rustdoc
 Stabilized APIs
 ---------------
 
-- [`impl<T: Send> Sync for mpsc::Sender<T>`](https://doc.rust-lang.org/nightly/std/sync/mpsc/struct.Sender.html#impl-Sync-for-Sender%3CT%3E)
-- [`impl TryFrom<&OsStr> for &str`](https://doc.rust-lang.org/nightly/std/primitive.str.html#impl-TryFrom%3C%26'a+OsStr%3E-for-%26'a+str)
-- [`String::leak`](https://doc.rust-lang.org/nightly/alloc/string/struct.String.html#method.leak)
+- [`impl<T: Send> Sync for mpsc::Sender<T>`](https://doc.rust-lang.org/stable/std/sync/mpsc/struct.Sender.html#impl-Sync-for-Sender%3CT%3E)
+- [`impl TryFrom<&OsStr> for &str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-TryFrom%3C%26'a+OsStr%3E-for-%26'a+str)
+- [`String::leak`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.leak)
 
 These APIs are now stable in const contexts:
 
-- [`CStr::from_bytes_with_nul`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul)
-- [`CStr::to_bytes`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul)
-- [`CStr::to_bytes_with_nul`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul)
-- [`CStr::to_str`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul)
+- [`CStr::from_bytes_with_nul`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.from_bytes_with_nul)
+- [`CStr::to_bytes`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.to_bytes)
+- [`CStr::to_bytes_with_nul`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.to_bytes_with_nul)
+- [`CStr::to_str`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.to_str)
 
 <a id="1.72.0-Cargo"></a>
 
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 12dd1542d79..7f2cab3eb11 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1,5 +1,5 @@
 #![cfg_attr(feature = "nightly", feature(step_trait, rustc_attrs, min_specialization))]
-#![cfg_attr(all(not(bootstrap), feature = "nightly"), allow(internal_features))]
+#![cfg_attr(feature = "nightly", allow(internal_features))]
 
 use std::fmt;
 #[cfg(feature = "nightly")]
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index e45b7c154fa..f14463fe940 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -24,7 +24,7 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 #![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine.
 
 use smallvec::SmallVec;
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 58725a08c7c..395540764ea 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2092,6 +2092,10 @@ pub enum TyKind {
     Never,
     /// A tuple (`(A, B, C, D,...)`).
     Tup(ThinVec<P<Ty>>),
+    /// An anonymous struct type i.e. `struct { foo: Type }`
+    AnonStruct(ThinVec<FieldDef>),
+    /// An anonymous union type i.e. `union { bar: Type }`
+    AnonUnion(ThinVec<FieldDef>),
     /// A path (`module::module::...::Type`), optionally
     /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
     ///
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 48e9b180b74..e3504a5638e 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -510,6 +510,9 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
             visit_vec(bounds, |bound| vis.visit_param_bound(bound));
         }
         TyKind::MacCall(mac) => vis.visit_mac_call(mac),
+        TyKind::AnonStruct(fields) | TyKind::AnonUnion(fields) => {
+            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
+        }
     }
     vis.visit_span(span);
     visit_lazy_tts(tokens, vis);
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index f4ad0efa423..300b1486f9b 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -486,6 +486,8 @@ impl Token {
             Lt | BinOp(Shl)             | // associated path
             ModSep                      => true, // global path
             Interpolated(ref nt) => matches!(**nt, NtTy(..) | NtPath(..)),
+            // For anonymous structs or unions, which only appear in specific positions
+            // (type of struct fields or union fields), we don't consider them as regular types
             _ => false,
         }
     }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 6d474de2d15..ddbbf5a10bc 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -438,6 +438,9 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
         TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
         TyKind::MacCall(mac) => visitor.visit_mac_call(mac),
         TyKind::Never | TyKind::CVarArgs => {}
+        TyKind::AnonStruct(ref fields, ..) | TyKind::AnonUnion(ref fields, ..) => {
+            walk_list!(visitor, visit_field_def, fields)
+        }
     }
 }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 4a47de1280c..1827e42368f 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1293,6 +1293,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             TyKind::Err => {
                 hir::TyKind::Err(self.tcx.sess.delay_span_bug(t.span, "TyKind::Err lowered"))
             }
+            // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS
+            #[allow(rustc::untranslatable_diagnostic)]
+            #[allow(rustc::diagnostic_outside_of_impl)]
+            TyKind::AnonStruct(ref _fields) => hir::TyKind::Err(
+                self.tcx.sess.span_err(t.span, "anonymous structs are unimplemented"),
+            ),
+            // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS
+            #[allow(rustc::untranslatable_diagnostic)]
+            #[allow(rustc::diagnostic_outside_of_impl)]
+            TyKind::AnonUnion(ref _fields) => hir::TyKind::Err(
+                self.tcx.sess.span_err(t.span, "anonymous unions are unimplemented"),
+            ),
             TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
             TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
             TyKind::Ref(region, mt) => {
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index f323bb4c254..ee5007027de 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -1,3 +1,7 @@
+ast_passes_anon_struct_or_union_not_allowed =
+    anonymous {$struct_or_union}s are not allowed outside of unnamed struct or union fields
+    .label = anonymous {$struct_or_union} declared here
+
 ast_passes_assoc_const_without_body =
     associated constant in `impl` without body
     .suggestion = provide a definition for the constant
@@ -162,6 +166,14 @@ ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
 ast_passes_invalid_label =
     invalid label name `{$name}`
 
+ast_passes_invalid_unnamed_field =
+    unnamed fields are not allowed outside of structs or unions
+    .label = unnamed field declared here
+
+ast_passes_invalid_unnamed_field_ty =
+    unnamed fields can only have struct or union types
+    .label = not a struct or union
+
 ast_passes_item_underscore = `{$kind}` items in this context need a name
     .label = `_` is not a valid name for this `{$kind}` item
 
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index bd3e676daa4..ad367d05f04 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -223,10 +223,27 @@ impl<'a> AstValidator<'a> {
                     }
                 }
             }
+            TyKind::AnonStruct(ref fields, ..) | TyKind::AnonUnion(ref fields, ..) => {
+                walk_list!(self, visit_field_def, fields)
+            }
             _ => visit::walk_ty(self, t),
         }
     }
 
+    fn visit_struct_field_def(&mut self, field: &'a FieldDef) {
+        if let Some(ident) = field.ident &&
+            ident.name == kw::Underscore {
+                self.check_unnamed_field_ty(&field.ty, ident.span);
+                self.visit_vis(&field.vis);
+                self.visit_ident(ident);
+                self.visit_ty_common(&field.ty);
+                self.walk_ty(&field.ty);
+                walk_list!(self, visit_attribute, &field.attrs);
+        } else {
+            self.visit_field_def(field);
+        }
+    }
+
     fn err_handler(&self) -> &rustc_errors::Handler {
         &self.session.diagnostic()
     }
@@ -264,6 +281,42 @@ impl<'a> AstValidator<'a> {
         }
     }
 
+    fn check_unnamed_field_ty(&self, ty: &Ty, span: Span) {
+        if matches!(
+            &ty.kind,
+            // We already checked for `kw::Underscore` before calling this function,
+            // so skip the check
+            TyKind::AnonStruct(..) | TyKind::AnonUnion(..)
+            // If the anonymous field contains a Path as type, we can't determine
+            // if the path is a valid struct or union, so skip the check
+            | TyKind::Path(..)
+        ) {
+            return;
+        }
+        self.err_handler().emit_err(errors::InvalidUnnamedFieldTy { span, ty_span: ty.span });
+    }
+
+    fn deny_anon_struct_or_union(&self, ty: &Ty) {
+        let struct_or_union = match &ty.kind {
+            TyKind::AnonStruct(..) => "struct",
+            TyKind::AnonUnion(..) => "union",
+            _ => return,
+        };
+        self.err_handler()
+            .emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
+    }
+
+    fn deny_unnamed_field(&self, field: &FieldDef) {
+        if let Some(ident) = field.ident &&
+            ident.name == kw::Underscore {
+                self.err_handler()
+                    .emit_err(errors::InvalidUnnamedField {
+                        span: field.span,
+                        ident_span: ident.span
+                    });
+        }
+    }
+
     fn check_trait_fn_not_const(&self, constness: Const) {
         if let Const::Yes(span) = constness {
             self.session.emit_err(errors::TraitFnConst { span });
@@ -789,6 +842,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
     fn visit_ty(&mut self, ty: &'a Ty) {
         self.visit_ty_common(ty);
+        self.deny_anon_struct_or_union(ty);
         self.walk_ty(ty)
     }
 
@@ -803,6 +857,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     }
 
     fn visit_field_def(&mut self, field: &'a FieldDef) {
+        self.deny_unnamed_field(field);
         visit::walk_field_def(self, field)
     }
 
@@ -995,10 +1050,38 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     self.check_mod_file_item_asciionly(item.ident);
                 }
             }
-            ItemKind::Union(vdata, ..) => {
+            ItemKind::Struct(vdata, generics) => match vdata {
+                // Duplicating the `Visitor` logic allows catching all cases
+                // of `Anonymous(Struct, Union)` outside of a field struct or union.
+                //
+                // Inside `visit_ty` the validator catches every `Anonymous(Struct, Union)` it
+                // encounters, and only on `ItemKind::Struct` and `ItemKind::Union`
+                // it uses `visit_ty_common`, which doesn't contain that specific check.
+                VariantData::Struct(fields, ..) => {
+                    self.visit_vis(&item.vis);
+                    self.visit_ident(item.ident);
+                    self.visit_generics(generics);
+                    walk_list!(self, visit_struct_field_def, fields);
+                    walk_list!(self, visit_attribute, &item.attrs);
+                    return;
+                }
+                _ => {}
+            },
+            ItemKind::Union(vdata, generics) => {
                 if vdata.fields().is_empty() {
                     self.err_handler().emit_err(errors::FieldlessUnion { span: item.span });
                 }
+                match vdata {
+                    VariantData::Struct(fields, ..) => {
+                        self.visit_vis(&item.vis);
+                        self.visit_ident(item.ident);
+                        self.visit_generics(generics);
+                        walk_list!(self, visit_struct_field_def, fields);
+                        walk_list!(self, visit_attribute, &item.attrs);
+                        return;
+                    }
+                    _ => {}
+                }
             }
             ItemKind::Const(box ConstItem { defaultness, expr: None, .. }) => {
                 self.check_defaultness(item.span, *defaultness);
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index a6f217d4780..74ab48c06ff 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -727,3 +727,30 @@ pub struct ConstraintOnNegativeBound {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_invalid_unnamed_field_ty)]
+pub struct InvalidUnnamedFieldTy {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub ty_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_invalid_unnamed_field)]
+pub struct InvalidUnnamedField {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub ident_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_anon_struct_or_union_not_allowed)]
+pub struct AnonStructOrUnionNotAllowed {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub struct_or_union: &'static str,
+}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 10c9c3ef111..8405ae6ff8e 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -570,6 +570,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
     gate_all!(explicit_tail_calls, "`become` expression is experimental");
     gate_all!(generic_const_items, "generic const items are experimental");
+    gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
 
     if !visitor.features.negative_bounds {
         for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 58ce73047bc..8b7e91882fc 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1064,6 +1064,14 @@ impl<'a> State<'a> {
                 }
                 self.pclose();
             }
+            ast::TyKind::AnonStruct(fields) => {
+                self.head("struct");
+                self.print_record_struct_body(&fields, ty.span);
+            }
+            ast::TyKind::AnonUnion(fields) => {
+                self.head("union");
+                self.print_record_struct_body(&fields, ty.span);
+            }
             ast::TyKind::Paren(typ) => {
                 self.popen();
                 self.print_type(typ);
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index d27a44f1206..3393f034bc3 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -443,7 +443,11 @@ impl<'a> State<'a> {
         }
     }
 
-    fn print_record_struct_body(&mut self, fields: &[ast::FieldDef], span: rustc_span::Span) {
+    pub(crate) fn print_record_struct_body(
+        &mut self,
+        fields: &[ast::FieldDef],
+        span: rustc_span::Span,
+    ) {
         self.nbsp();
         self.bopen();
 
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 3592287b95c..ca4b3662a08 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -937,6 +937,7 @@ pub fn find_deprecation(
 #[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone)]
 pub enum ReprAttr {
     ReprInt(IntType),
+    ReprRust,
     ReprC,
     ReprPacked(u32),
     ReprSimd,
@@ -985,6 +986,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
             let mut recognised = false;
             if item.is_word() {
                 let hint = match item.name_or_empty() {
+                    sym::Rust => Some(ReprRust),
                     sym::C => Some(ReprC),
                     sym::packed => Some(ReprPacked(1)),
                     sym::simd => Some(ReprSimd),
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index d62541daf07..31e863b8a4e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -225,17 +225,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 }
                 if suggest {
                     borrow_spans.var_subdiag(
-                    None,
-                    &mut err,
-                    Some(mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }),
-                    |_kind, var_span| {
-                        let place = self.describe_any_place(access_place.as_ref());
-                        crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure {
-                            place,
-                            var_span,
-                        }
-                    },
-                );
+                        None,
+                        &mut err,
+                        Some(mir::BorrowKind::Mut { kind: mir::MutBorrowKind::Default }),
+                        |_kind, var_span| {
+                            let place = self.describe_any_place(access_place.as_ref());
+                            crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure {
+                                place,
+                                var_span,
+                            }
+                        },
+                    );
                 }
                 borrow_span
             }
@@ -262,11 +262,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             } => {
                 err.span_label(span, format!("cannot {act}"));
 
-                if let Some(span) = get_mut_span_in_struct_field(
-                    self.infcx.tcx,
-                    Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty,
-                    *field,
-                ) {
+                let place = Place::ty_from(local, proj_base, self.body, self.infcx.tcx);
+                if let Some(span) = get_mut_span_in_struct_field(self.infcx.tcx, place.ty, *field) {
                     err.span_suggestion_verbose(
                         span,
                         "consider changing this to be mutable",
@@ -781,83 +778,88 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
     // Attempt to search similar mutable associated items for suggestion.
     // In the future, attempt in all path but initially for RHS of for_loop
-    fn suggest_similar_mut_method_for_for_loop(&self, err: &mut Diagnostic) {
+    fn suggest_similar_mut_method_for_for_loop(&self, err: &mut Diagnostic, span: Span) {
         use hir::{
-            Expr,
-            ExprKind::{Block, Call, DropTemps, Match, MethodCall},
+            BorrowKind, Expr,
+            ExprKind::{AddrOf, Block, Call, MethodCall},
         };
 
         let hir_map = self.infcx.tcx.hir();
-        if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id()) {
-            if let Block(
-                hir::Block {
-                    expr:
-                        Some(Expr {
-                            kind:
-                                DropTemps(Expr {
-                                    kind:
-                                        Match(
-                                            Expr {
-                                                kind:
-                                                    Call(
-                                                        _,
-                                                        [
-                                                            Expr {
-                                                                kind:
-                                                                    MethodCall(path_segment, _, _, span),
-                                                                hir_id,
-                                                                ..
-                                                            },
-                                                            ..,
-                                                        ],
-                                                    ),
-                                                ..
-                                            },
-                                            ..,
-                                        ),
-                                    ..
-                                }),
-                            ..
-                        }),
-                    ..
-                },
-                _,
-            ) = hir_map.body(body_id).value.kind
-            {
-                let opt_suggestions = self
-                    .infcx
-                    .tcx
-                    .typeck(path_segment.hir_id.owner.def_id)
-                    .type_dependent_def_id(*hir_id)
-                    .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id))
-                    .map(|def_id| self.infcx.tcx.associated_items(def_id))
-                    .map(|assoc_items| {
-                        assoc_items
-                            .in_definition_order()
-                            .map(|assoc_item_def| assoc_item_def.ident(self.infcx.tcx))
-                            .filter(|&ident| {
-                                let original_method_ident = path_segment.ident;
-                                original_method_ident != ident
-                                    && ident
-                                        .as_str()
-                                        .starts_with(&original_method_ident.name.to_string())
-                            })
-                            .map(|ident| format!("{ident}()"))
-                            .peekable()
-                    });
+        struct Finder<'tcx> {
+            span: Span,
+            expr: Option<&'tcx Expr<'tcx>>,
+        }
 
-                if let Some(mut suggestions) = opt_suggestions
-                    && suggestions.peek().is_some()
-                {
-                    err.span_suggestions(
-                        *span,
-                        "use mutable method",
-                        suggestions,
-                        Applicability::MaybeIncorrect,
-                    );
+        impl<'tcx> Visitor<'tcx> for Finder<'tcx> {
+            fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
+                if e.span == self.span && self.expr.is_none() {
+                    self.expr = Some(e);
                 }
+                hir::intravisit::walk_expr(self, e);
             }
-        };
+        }
+        if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id())
+            && let Block(block, _) = hir_map.body(body_id).value.kind
+        {
+            // `span` corresponds to the expression being iterated, find the `for`-loop desugared
+            // expression with that span in order to identify potential fixes when encountering a
+            // read-only iterator that should be mutable.
+            let mut v = Finder {
+                span,
+                expr: None,
+            };
+            v.visit_block(block);
+            if let Some(expr) = v.expr && let Call(_, [expr]) = expr.kind {
+                match expr.kind {
+                    MethodCall(path_segment, _, _, span) => {
+                        // We have `for _ in iter.read_only_iter()`, try to
+                        // suggest `for _ in iter.mutable_iter()` instead.
+                        let opt_suggestions = self
+                            .infcx
+                            .tcx
+                            .typeck(path_segment.hir_id.owner.def_id)
+                            .type_dependent_def_id(expr.hir_id)
+                            .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id))
+                            .map(|def_id| self.infcx.tcx.associated_items(def_id))
+                            .map(|assoc_items| {
+                                assoc_items
+                                    .in_definition_order()
+                                    .map(|assoc_item_def| assoc_item_def.ident(self.infcx.tcx))
+                                    .filter(|&ident| {
+                                        let original_method_ident = path_segment.ident;
+                                        original_method_ident != ident
+                                            && ident.as_str().starts_with(
+                                                &original_method_ident.name.to_string(),
+                                            )
+                                    })
+                                    .map(|ident| format!("{ident}()"))
+                                    .peekable()
+                            });
+
+                        if let Some(mut suggestions) = opt_suggestions
+                            && suggestions.peek().is_some()
+                        {
+                            err.span_suggestions(
+                                span,
+                                "use mutable method",
+                                suggestions,
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
+                    }
+                    AddrOf(BorrowKind::Ref, Mutability::Not, expr) => {
+                        // We have `for _ in &i`, suggest `for _ in &mut i`.
+                        err.span_suggestion_verbose(
+                            expr.span.shrink_to_lo(),
+                            "use a mutable iterator instead",
+                            "mut ".to_string(),
+                            Applicability::MachineApplicable,
+                        );
+                    }
+                    _ => {}
+                }
+            }
+        }
     }
 
     /// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected.
@@ -1003,9 +1005,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) {
                     // on for loops, RHS points to the iterator part
                     Some(DesugaringKind::ForLoop) => {
-                        self.suggest_similar_mut_method_for_for_loop(err);
+                        let span = opt_assignment_rhs_span.unwrap();
+                        self.suggest_similar_mut_method_for_for_loop(err, span);
                         err.span_label(
-                            opt_assignment_rhs_span.unwrap(),
+                            span,
                             format!("this iterator yields `{pointer_sigil}` {pointer_desc}s",),
                         );
                         None
diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs
index d4c42a75874..84be50a6416 100644
--- a/compiler/rustc_borrowck/src/invalidation.rs
+++ b/compiler/rustc_borrowck/src/invalidation.rs
@@ -202,7 +202,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
                 }
             }
             TerminatorKind::Goto { target: _ }
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Unreachable
             | TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
             | TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index ef2788efbcf..770c180ff2c 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -11,7 +11,7 @@
 #![feature(trusted_step)]
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_middle;
@@ -770,7 +770,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
             }
 
             TerminatorKind::Goto { target: _ }
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Unreachable
             | TerminatorKind::UnwindResume
             | TerminatorKind::Return
@@ -817,7 +817,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
                 }
             }
 
-            TerminatorKind::UnwindTerminate
+            TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Assert { .. }
             | TerminatorKind::Call { .. }
             | TerminatorKind::Drop { .. }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index d91a3d94045..3004291c3e7 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1334,7 +1334,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         match &term.kind {
             TerminatorKind::Goto { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::GeneratorDrop
             | TerminatorKind::Unreachable
@@ -1613,7 +1613,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     span_mirbug!(self, block_data, "resume on non-cleanup block!")
                 }
             }
-            TerminatorKind::UnwindTerminate => {
+            TerminatorKind::UnwindTerminate(_) => {
                 if !is_cleanup {
                     span_mirbug!(self, block_data, "abort on non-cleanup block!")
                 }
@@ -1697,7 +1697,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     span_mirbug!(self, ctxt, "unwind on cleanup block")
                 }
             }
-            UnwindAction::Unreachable | UnwindAction::Terminate => (),
+            UnwindAction::Unreachable | UnwindAction::Terminate(_) => (),
         }
     }
 
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index ed371a04c53..9159bc36987 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -474,8 +474,8 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                     *destination,
                 );
             }
-            TerminatorKind::UnwindTerminate => {
-                codegen_panic_cannot_unwind(fx, source_info);
+            TerminatorKind::UnwindTerminate(reason) => {
+                codegen_unwind_terminate(fx, source_info, *reason);
             }
             TerminatorKind::UnwindResume => {
                 // FIXME implement unwinding
@@ -971,13 +971,14 @@ pub(crate) fn codegen_panic_nounwind<'tcx>(
     codegen_panic_inner(fx, rustc_hir::LangItem::PanicNounwind, &args, source_info.span);
 }
 
-pub(crate) fn codegen_panic_cannot_unwind<'tcx>(
+pub(crate) fn codegen_unwind_terminate<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     source_info: mir::SourceInfo,
+    reason: UnwindTerminateReason,
 ) {
     let args = [];
 
-    codegen_panic_inner(fx, rustc_hir::LangItem::PanicCannotUnwind, &args, source_info.span);
+    codegen_panic_inner(fx, reason.lang_item(), &args, source_info.span);
 }
 
 fn codegen_panic_inner<'tcx>(
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index 7db5f79eead..a934b0767f1 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -551,7 +551,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
                     TerminatorKind::Goto { .. }
                     | TerminatorKind::SwitchInt { .. }
                     | TerminatorKind::UnwindResume
-                    | TerminatorKind::UnwindTerminate
+                    | TerminatorKind::UnwindTerminate(_)
                     | TerminatorKind::Return
                     | TerminatorKind::Unreachable
                     | TerminatorKind::Drop { .. }
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index a81585d4128..d1bfd833cd8 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -55,7 +55,7 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         _fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
         _llfn: RValue<'gcc>,
         _mir: &mir::Body<'tcx>,
-    ) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>> {
+    ) -> Option<FunctionDebugContext<'tcx, Self::DIScope, Self::DILocation>> {
         // TODO(antoyo)
         None
     }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index d174a3593b9..7a68c291aa5 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -20,7 +20,7 @@ pub fn compute_mir_scopes<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     instance: Instance<'tcx>,
     mir: &Body<'tcx>,
-    debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
+    debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>,
 ) {
     // Find all scopes with variables defined in them.
     let variables = if cx.sess().opts.debuginfo == DebugInfo::Full {
@@ -51,7 +51,7 @@ fn make_mir_scope<'ll, 'tcx>(
     instance: Instance<'tcx>,
     mir: &Body<'tcx>,
     variables: &Option<BitSet<SourceScope>>,
-    debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
+    debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>,
     instantiated: &mut BitSet<SourceScope>,
     scope: SourceScope,
 ) {
@@ -84,7 +84,6 @@ fn make_mir_scope<'ll, 'tcx>(
     }
 
     let loc = cx.lookup_debug_loc(scope_data.span.lo());
-    let file_metadata = file_metadata(cx, &loc.file);
 
     let dbg_scope = match scope_data.inlined {
         Some((callee, _)) => {
@@ -95,18 +94,26 @@ fn make_mir_scope<'ll, 'tcx>(
                 ty::ParamEnv::reveal_all(),
                 ty::EarlyBinder::bind(callee),
             );
-            let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
-            cx.dbg_scope_fn(callee, callee_fn_abi, None)
+            debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| {
+                let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
+                cx.dbg_scope_fn(callee, callee_fn_abi, None)
+            })
+        }
+        None => {
+            let file_metadata = file_metadata(cx, &loc.file);
+            debug_context
+                .lexical_blocks
+                .entry((parent_scope.dbg_scope, loc.line, loc.col, file_metadata))
+                .or_insert_with(|| unsafe {
+                    llvm::LLVMRustDIBuilderCreateLexicalBlock(
+                        DIB(cx),
+                        parent_scope.dbg_scope,
+                        file_metadata,
+                        loc.line,
+                        loc.col,
+                    )
+                })
         }
-        None => unsafe {
-            llvm::LLVMRustDIBuilderCreateLexicalBlock(
-                DIB(cx),
-                parent_scope.dbg_scope,
-                file_metadata,
-                loc.line,
-                loc.col,
-            )
-        },
     };
 
     let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 40714a0afe9..9cdeae2841b 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -5,7 +5,7 @@ use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
 use self::metadata::{file_metadata, type_di_node};
 use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
 use self::namespace::mangled_name_of_instance;
-use self::utils::{create_DIArray, is_node_local_to_unit, DIB};
+use self::utils::{create_DIArray, debug_context, is_node_local_to_unit, DIB};
 
 use crate::abi::FnAbi;
 use crate::builder::Builder;
@@ -67,6 +67,8 @@ pub struct CodegenUnitDebugContext<'ll, 'tcx> {
     type_map: metadata::TypeMap<'ll, 'tcx>,
     namespace_map: RefCell<DefIdMap<&'ll DIScope>>,
     recursion_marker_type: OnceCell<&'ll DIType>,
+    /// Maps a variable (name, scope, kind (argument or local), span) to its debug information.
+    variables: RefCell<FxHashMap<(Symbol, &'ll DIScope, VariableKind, Span), &'ll DIVariable>>,
 }
 
 impl Drop for CodegenUnitDebugContext<'_, '_> {
@@ -91,6 +93,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
             type_map: Default::default(),
             namespace_map: RefCell::new(Default::default()),
             recursion_marker_type: OnceCell::new(),
+            variables: RefCell::new(Default::default()),
         }
     }
 
@@ -292,7 +295,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
         llfn: &'ll Value,
         mir: &mir::Body<'tcx>,
-    ) -> Option<FunctionDebugContext<&'ll DIScope, &'ll DILocation>> {
+    ) -> Option<FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>> {
         if self.sess().opts.debuginfo == DebugInfo::None {
             return None;
         }
@@ -304,8 +307,11 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             file_start_pos: BytePos(0),
             file_end_pos: BytePos(0),
         };
-        let mut fn_debug_context =
-            FunctionDebugContext { scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes) };
+        let mut fn_debug_context = FunctionDebugContext {
+            scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes),
+            inlined_function_scopes: Default::default(),
+            lexical_blocks: Default::default(),
+        };
 
         // Fill in all the scopes, with the information from the MIR body.
         compute_mir_scopes(self, instance, mir, &mut fn_debug_context);
@@ -606,33 +612,39 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         variable_kind: VariableKind,
         span: Span,
     ) -> &'ll DIVariable {
-        let loc = self.lookup_debug_loc(span.lo());
-        let file_metadata = file_metadata(self, &loc.file);
-
-        let type_metadata = type_di_node(self, variable_type);
-
-        let (argument_index, dwarf_tag) = match variable_kind {
-            ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
-            LocalVariable => (0, DW_TAG_auto_variable),
-        };
-        let align = self.align_of(variable_type);
-
-        let name = variable_name.as_str();
-        unsafe {
-            llvm::LLVMRustDIBuilderCreateVariable(
-                DIB(self),
-                dwarf_tag,
-                scope_metadata,
-                name.as_ptr().cast(),
-                name.len(),
-                file_metadata,
-                loc.line,
-                type_metadata,
-                true,
-                DIFlags::FlagZero,
-                argument_index,
-                align.bytes() as u32,
-            )
-        }
+        debug_context(self)
+            .variables
+            .borrow_mut()
+            .entry((variable_name, scope_metadata, variable_kind, span))
+            .or_insert_with(|| {
+                let loc = self.lookup_debug_loc(span.lo());
+                let file_metadata = file_metadata(self, &loc.file);
+
+                let type_metadata = type_di_node(self, variable_type);
+
+                let (argument_index, dwarf_tag) = match variable_kind {
+                    ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
+                    LocalVariable => (0, DW_TAG_auto_variable),
+                };
+                let align = self.align_of(variable_type);
+
+                let name = variable_name.as_str();
+                unsafe {
+                    llvm::LLVMRustDIBuilderCreateVariable(
+                        DIB(self),
+                        dwarf_tag,
+                        scope_metadata,
+                        name.as_ptr().cast(),
+                        name.len(),
+                        file_metadata,
+                        loc.line,
+                        type_metadata,
+                        true,
+                        DIFlags::FlagZero,
+                        argument_index,
+                        align.bytes() as u32,
+                    )
+                }
+            })
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 3f5b46333d9..7fda2d5fadf 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -285,7 +285,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
             match data.terminator().kind {
                 TerminatorKind::Goto { .. }
                 | TerminatorKind::UnwindResume
-                | TerminatorKind::UnwindTerminate
+                | TerminatorKind::UnwindTerminate(_)
                 | TerminatorKind::Return
                 | TerminatorKind::GeneratorDrop
                 | TerminatorKind::Unreachable
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 19228183462..6aef1664394 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -12,7 +12,7 @@ use crate::MemFlags;
 use rustc_ast as ast;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir::lang_items::LangItem;
-use rustc_middle::mir::{self, AssertKind, SwitchTargets};
+use rustc_middle::mir::{self, AssertKind, SwitchTargets, UnwindTerminateReason};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Instance, Ty};
@@ -178,7 +178,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
             mir::UnwindAction::Cleanup(cleanup) => Some(self.llbb_with_cleanup(fx, cleanup)),
             mir::UnwindAction::Continue => None,
             mir::UnwindAction::Unreachable => None,
-            mir::UnwindAction::Terminate => {
+            mir::UnwindAction::Terminate(reason) => {
                 if fx.mir[self.bb].is_cleanup && base::wants_new_eh_instructions(fx.cx.tcx().sess) {
                     // MSVC SEH will abort automatically if an exception tries to
                     // propagate out from cleanup.
@@ -191,7 +191,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
 
                     None
                 } else {
-                    Some(fx.terminate_block())
+                    Some(fx.terminate_block(reason))
                 }
             }
         };
@@ -264,7 +264,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
     ) -> MergingSucc {
         let unwind_target = match unwind {
             mir::UnwindAction::Cleanup(cleanup) => Some(self.llbb_with_cleanup(fx, cleanup)),
-            mir::UnwindAction::Terminate => Some(fx.terminate_block()),
+            mir::UnwindAction::Terminate(reason) => Some(fx.terminate_block(reason)),
             mir::UnwindAction::Continue => None,
             mir::UnwindAction::Unreachable => None,
         };
@@ -649,12 +649,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         helper: TerminatorCodegenHelper<'tcx>,
         bx: &mut Bx,
         terminator: &mir::Terminator<'tcx>,
+        reason: UnwindTerminateReason,
     ) {
         let span = terminator.source_info.span;
         self.set_debug_loc(bx, terminator.source_info);
 
         // Obtain the panic entry point.
-        let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicCannotUnwind);
+        let (fn_abi, llfn) = common::build_langcall(bx, Some(span), reason.lang_item());
 
         // Codegen the actual panic invoke/call.
         let merging_succ = helper.do_call(
@@ -1229,8 +1230,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 MergingSucc::False
             }
 
-            mir::TerminatorKind::UnwindTerminate => {
-                self.codegen_terminate_terminator(helper, bx, terminator);
+            mir::TerminatorKind::UnwindTerminate(reason) => {
+                self.codegen_terminate_terminator(helper, bx, terminator, reason);
                 MergingSucc::False
             }
 
@@ -1579,79 +1580,81 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         })
     }
 
-    fn terminate_block(&mut self) -> Bx::BasicBlock {
-        self.terminate_block.unwrap_or_else(|| {
-            let funclet;
-            let llbb;
-            let mut bx;
-            if base::wants_msvc_seh(self.cx.sess()) {
-                // This is a basic block that we're aborting the program for,
-                // notably in an `extern` function. These basic blocks are inserted
-                // so that we assert that `extern` functions do indeed not panic,
-                // and if they do we abort the process.
-                //
-                // On MSVC these are tricky though (where we're doing funclets). If
-                // we were to do a cleanuppad (like below) the normal functions like
-                // `longjmp` would trigger the abort logic, terminating the
-                // program. Instead we insert the equivalent of `catch(...)` for C++
-                // which magically doesn't trigger when `longjmp` files over this
-                // frame.
-                //
-                // Lots more discussion can be found on #48251 but this codegen is
-                // modeled after clang's for:
-                //
-                //      try {
-                //          foo();
-                //      } catch (...) {
-                //          bar();
-                //      }
-                //
-                // which creates an IR snippet like
-                //
-                //      cs_terminate:
-                //         %cs = catchswitch within none [%cp_terminate] unwind to caller
-                //      cp_terminate:
-                //         %cp = catchpad within %cs [null, i32 64, null]
-                //         ...
-
-                llbb = Bx::append_block(self.cx, self.llfn, "cs_terminate");
-                let cp_llbb = Bx::append_block(self.cx, self.llfn, "cp_terminate");
-
-                let mut cs_bx = Bx::build(self.cx, llbb);
-                let cs = cs_bx.catch_switch(None, None, &[cp_llbb]);
-
-                // The "null" here is actually a RTTI type descriptor for the
-                // C++ personality function, but `catch (...)` has no type so
-                // it's null. The 64 here is actually a bitfield which
-                // represents that this is a catch-all block.
-                bx = Bx::build(self.cx, cp_llbb);
-                let null =
-                    bx.const_null(bx.type_ptr_ext(bx.cx().data_layout().instruction_address_space));
-                let sixty_four = bx.const_i32(64);
-                funclet = Some(bx.catch_pad(cs, &[null, sixty_four, null]));
-            } else {
-                llbb = Bx::append_block(self.cx, self.llfn, "terminate");
-                bx = Bx::build(self.cx, llbb);
+    fn terminate_block(&mut self, reason: UnwindTerminateReason) -> Bx::BasicBlock {
+        if let Some((cached_bb, cached_reason)) = self.terminate_block && reason == cached_reason {
+            return cached_bb;
+        }
 
-                let llpersonality = self.cx.eh_personality();
-                bx.filter_landing_pad(llpersonality);
+        let funclet;
+        let llbb;
+        let mut bx;
+        if base::wants_msvc_seh(self.cx.sess()) {
+            // This is a basic block that we're aborting the program for,
+            // notably in an `extern` function. These basic blocks are inserted
+            // so that we assert that `extern` functions do indeed not panic,
+            // and if they do we abort the process.
+            //
+            // On MSVC these are tricky though (where we're doing funclets). If
+            // we were to do a cleanuppad (like below) the normal functions like
+            // `longjmp` would trigger the abort logic, terminating the
+            // program. Instead we insert the equivalent of `catch(...)` for C++
+            // which magically doesn't trigger when `longjmp` files over this
+            // frame.
+            //
+            // Lots more discussion can be found on #48251 but this codegen is
+            // modeled after clang's for:
+            //
+            //      try {
+            //          foo();
+            //      } catch (...) {
+            //          bar();
+            //      }
+            //
+            // which creates an IR snippet like
+            //
+            //      cs_terminate:
+            //         %cs = catchswitch within none [%cp_terminate] unwind to caller
+            //      cp_terminate:
+            //         %cp = catchpad within %cs [null, i32 64, null]
+            //         ...
+
+            llbb = Bx::append_block(self.cx, self.llfn, "cs_terminate");
+            let cp_llbb = Bx::append_block(self.cx, self.llfn, "cp_terminate");
+
+            let mut cs_bx = Bx::build(self.cx, llbb);
+            let cs = cs_bx.catch_switch(None, None, &[cp_llbb]);
+
+            // The "null" here is actually a RTTI type descriptor for the
+            // C++ personality function, but `catch (...)` has no type so
+            // it's null. The 64 here is actually a bitfield which
+            // represents that this is a catch-all block.
+            bx = Bx::build(self.cx, cp_llbb);
+            let null =
+                bx.const_null(bx.type_ptr_ext(bx.cx().data_layout().instruction_address_space));
+            let sixty_four = bx.const_i32(64);
+            funclet = Some(bx.catch_pad(cs, &[null, sixty_four, null]));
+        } else {
+            llbb = Bx::append_block(self.cx, self.llfn, "terminate");
+            bx = Bx::build(self.cx, llbb);
 
-                funclet = None;
-            }
+            let llpersonality = self.cx.eh_personality();
+            bx.filter_landing_pad(llpersonality);
+
+            funclet = None;
+        }
 
-            self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
+        self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
 
-            let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicCannotUnwind);
-            let fn_ty = bx.fn_decl_backend_type(&fn_abi);
+        let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, reason.lang_item());
+        let fn_ty = bx.fn_decl_backend_type(&fn_abi);
 
-            let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref());
-            bx.do_not_inline(llret);
+        let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref());
+        bx.do_not_inline(llret);
 
-            bx.unreachable();
+        bx.unreachable();
 
-            self.terminate_block = Some(llbb);
-            llbb
-        })
+        self.terminate_block = Some((llbb, reason));
+        llbb
     }
 
     /// Get the backend `BasicBlock` for a MIR `BasicBlock`, either already
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 564b5da32cc..7df830692d3 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -1,10 +1,12 @@
 use crate::traits::*;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_index::IndexVec;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
 use rustc_middle::ty;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
+use rustc_middle::ty::Instance;
 use rustc_middle::ty::Ty;
 use rustc_session::config::DebugInfo;
 use rustc_span::symbol::{kw, Symbol};
@@ -17,11 +19,19 @@ use super::{FunctionCx, LocalRef};
 
 use std::ops::Range;
 
-pub struct FunctionDebugContext<S, L> {
+pub struct FunctionDebugContext<'tcx, S, L> {
+    /// Maps from source code to the corresponding debug info scope.
     pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
+
+    /// Maps from a given inlined function to its debug info declaration.
+    pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
+
+    /// Maps from a lexical block (parent scope, line, column, file) to its debug info declaration.
+    /// This is particularily useful if the parent scope is an inlined function.
+    pub lexical_blocks: FxHashMap<(S, u32, u32, S), S>,
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Eq, PartialEq, Hash)]
 pub enum VariableKind {
     ArgumentVariable(usize /*index*/),
     LocalVariable,
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 3464f910829..37a209cec5e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -5,6 +5,7 @@ use rustc_index::IndexVec;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::traversal;
+use rustc_middle::mir::UnwindTerminateReason;
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_target::abi::call::{FnAbi, PassMode};
@@ -45,7 +46,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
 
     mir: &'tcx mir::Body<'tcx>,
 
-    debug_context: Option<FunctionDebugContext<Bx::DIScope, Bx::DILocation>>,
+    debug_context: Option<FunctionDebugContext<'tcx, Bx::DIScope, Bx::DILocation>>,
 
     llfn: Bx::Function,
 
@@ -83,8 +84,8 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
     /// Cached unreachable block
     unreachable_block: Option<Bx::BasicBlock>,
 
-    /// Cached terminate upon unwinding block
-    terminate_block: Option<Bx::BasicBlock>,
+    /// Cached terminate upon unwinding block and its reason
+    terminate_block: Option<(Bx::BasicBlock, UnwindTerminateReason)>,
 
     /// The location where each MIR arg/var/tmp/ret is stored. This is
     /// usually an `PlaceRef` representing an alloca, but not always:
@@ -174,7 +175,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     let mut start_bx = Bx::build(cx, start_llbb);
 
     if mir.basic_blocks.iter().any(|bb| {
-        bb.is_cleanup || matches!(bb.terminator().unwind(), Some(mir::UnwindAction::Terminate))
+        bb.is_cleanup || matches!(bb.terminator().unwind(), Some(mir::UnwindAction::Terminate(_)))
     }) {
         start_bx.set_personality_fn(cx.eh_personality());
     }
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 63fecaf34fd..4acc0ea076c 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -26,7 +26,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
         fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
         llfn: Self::Function,
         mir: &mir::Body<'tcx>,
-    ) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>>;
+    ) -> Option<FunctionDebugContext<'tcx, Self::DIScope, Self::DILocation>>;
 
     // FIXME(eddyb) find a common convention for all of the debuginfo-related
     // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 61d3de5c405..90848dbfbc7 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -756,6 +756,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ///
     /// If `target` is `UnwindAction::Unreachable`, that indicates the function does not allow
     /// unwinding, and doing so is UB.
+    #[cold] // usually we have normal returns, not unwinding
     pub fn unwind_to_block(&mut self, target: mir::UnwindAction) -> InterpResult<'tcx> {
         self.frame_mut().loc = match target {
             mir::UnwindAction::Cleanup(block) => Left(mir::Location { block, statement_index: 0 }),
@@ -763,9 +764,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             mir::UnwindAction::Unreachable => {
                 throw_ub_custom!(fluent::const_eval_unreachable_unwind);
             }
-            mir::UnwindAction::Terminate => {
+            mir::UnwindAction::Terminate(reason) => {
                 self.frame_mut().loc = Right(self.frame_mut().body.span);
-                M::unwind_terminate(self)?;
+                M::unwind_terminate(self, reason)?;
                 // This might have pushed a new stack frame, or it terminated execution.
                 // Either way, `loc` will not be updated.
                 return Ok(());
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index d3c73b896c0..91c07d73fce 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -18,7 +18,7 @@ use crate::const_eval::CheckAlignment;
 
 use super::{
     AllocBytes, AllocId, AllocRange, Allocation, ConstAllocation, FnArg, Frame, ImmTy, InterpCx,
-    InterpResult, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Provenance, Scalar,
+    InterpResult, MPlaceTy, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Provenance, Scalar,
 };
 
 /// Data returned by Machine::stack_pop,
@@ -222,7 +222,10 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
     fn panic_nounwind(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx>;
 
     /// Called when unwinding reached a state where execution should be terminated.
-    fn unwind_terminate(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>;
+    fn unwind_terminate(
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        reason: mir::UnwindTerminateReason,
+    ) -> InterpResult<'tcx>;
 
     /// Called for all binary operations where the LHS has pointer type.
     ///
@@ -462,6 +465,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
 
     /// Called immediately after a stack frame got popped, but before jumping back to the caller.
     /// The `locals` have already been destroyed!
+    #[inline(always)]
     fn after_stack_pop(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
         _frame: Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>,
@@ -471,6 +475,18 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
         assert!(!unwinding);
         Ok(StackPopJump::Normal)
     }
+
+    /// Called immediately after actual memory was allocated for a local
+    /// but before the local's stack frame is updated to point to that memory.
+    #[inline(always)]
+    fn after_local_allocated(
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        _frame: usize,
+        _local: mir::Local,
+        _mplace: &MPlaceTy<'tcx, Self::Provenance>,
+    ) -> InterpResult<'tcx> {
+        Ok(())
+    }
 }
 
 /// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
@@ -501,7 +517,10 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
     }
 
     #[inline(always)]
-    fn unwind_terminate(_ecx: &mut InterpCx<$mir, $tcx, Self>) -> InterpResult<$tcx> {
+    fn unwind_terminate(
+        _ecx: &mut InterpCx<$mir, $tcx, Self>,
+        _reason: mir::UnwindTerminateReason,
+    ) -> InterpResult<$tcx> {
         unreachable!("unwinding cannot happen during compile-time evaluation")
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index daadb758964..40a7a0f4e56 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -899,7 +899,7 @@ where
                         if local_layout.is_unsized() {
                             throw_unsup_format!("unsized locals are not supported");
                         }
-                        let mplace = *self.allocate(local_layout, MemoryKind::Stack)?;
+                        let mplace = self.allocate(local_layout, MemoryKind::Stack)?;
                         // Preserve old value. (As an optimization, we can skip this if it was uninit.)
                         if !matches!(local_val, Immediate::Uninit) {
                             // We don't have to validate as we can assume the local was already
@@ -909,15 +909,16 @@ where
                                 local_val,
                                 local_layout,
                                 local_layout.align.abi,
-                                mplace,
+                                *mplace,
                             )?;
                         }
+                        M::after_local_allocated(self, frame, local, &mplace)?;
                         // Now we can call `access_mut` again, asserting it goes well, and actually
                         // overwrite things. This points to the entire allocation, not just the part
                         // the place refers to, i.e. we do this before we apply `offset`.
                         *M::access_local_mut(self, frame, local).unwrap() =
-                            Operand::Indirect(mplace);
-                        mplace
+                            Operand::Indirect(*mplace);
+                        *mplace
                     }
                     &mut Operand::Indirect(mplace) => mplace, // this already was an indirect local
                 };
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index b2ebcceceb3..ca7c484ea31 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -196,8 +196,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
 
-            UnwindTerminate => {
-                M::unwind_terminate(self)?;
+            UnwindTerminate(reason) => {
+                M::unwind_terminate(self, reason)?;
             }
 
             // When we encounter Resume, we've finished unwinding
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index e67098a3ac3..f288ddc25d3 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -1037,7 +1037,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 self.check_op(ops::Generator(hir::GeneratorKind::Gen))
             }
 
-            TerminatorKind::UnwindTerminate => {
+            TerminatorKind::UnwindTerminate(_) => {
                 // Cleanup blocks are skipped for const checking (see `visit_basic_block_data`).
                 span_bug!(self.span, "`Terminate` terminator outside of cleanup block")
             }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
index a8c61d2c8fd..fd6bc2ee9af 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
@@ -106,7 +106,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
                 }
             }
 
-            mir::TerminatorKind::UnwindTerminate
+            mir::TerminatorKind::UnwindTerminate(_)
             | mir::TerminatorKind::Call { .. }
             | mir::TerminatorKind::Assert { .. }
             | mir::TerminatorKind::FalseEdge { .. }
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 0dfbbf73dce..b829f24ab7a 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -10,8 +10,8 @@ use rustc_middle::mir::{
     traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location,
     MirPass, MirPhase, NonDivergingIntrinsic, NullOp, Operand, Place, PlaceElem, PlaceRef,
     ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind,
-    Terminator, TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents,
-    START_BLOCK,
+    Terminator, TerminatorKind, UnOp, UnwindAction, UnwindTerminateReason, VarDebugInfo,
+    VarDebugInfoContents, START_BLOCK,
 };
 use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
@@ -274,7 +274,16 @@ impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
                     self.fail(location, "`UnwindAction::Continue` in no-unwind function");
                 }
             }
-            UnwindAction::Unreachable | UnwindAction::Terminate => (),
+            UnwindAction::Terminate(UnwindTerminateReason::InCleanup) => {
+                if !is_cleanup {
+                    self.fail(
+                        location,
+                        "`UnwindAction::Terminate(InCleanup)` in a non-cleanup block",
+                    );
+                }
+            }
+            // These are allowed everywhere.
+            UnwindAction::Unreachable | UnwindAction::Terminate(UnwindTerminateReason::Abi) => (),
         }
     }
 }
@@ -501,7 +510,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
                     self.fail(location, "Cannot `UnwindResume` in a function that cannot unwind")
                 }
             }
-            TerminatorKind::UnwindTerminate => {
+            TerminatorKind::UnwindTerminate(_) => {
                 let bb = location.block;
                 if !self.body.basic_blocks[bb].is_cleanup {
                     self.fail(location, "Cannot `UnwindTerminate` from non-cleanup basic block")
@@ -1233,7 +1242,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             | TerminatorKind::InlineAsm { .. }
             | TerminatorKind::GeneratorDrop
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable => {}
         }
diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs
index 4f39dad205a..c1f0ff260d2 100644
--- a/compiler/rustc_const_eval/src/util/alignment.rs
+++ b/compiler/rustc_const_eval/src/util/alignment.rs
@@ -40,7 +40,7 @@ where
     }
 }
 
-fn is_within_packed<'tcx, L>(
+pub fn is_within_packed<'tcx, L>(
     tcx: TyCtxt<'tcx>,
     local_decls: &L,
     place: Place<'tcx>,
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index 289e3422595..0aef7fa469e 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -5,7 +5,7 @@ mod check_validity_requirement;
 mod compare_types;
 mod type_name;
 
-pub use self::alignment::is_disaligned;
+pub use self::alignment::{is_disaligned, is_within_packed};
 pub use self::check_validity_requirement::check_validity_requirement;
 pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype};
 pub use self::type_name::type_name;
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 33772089744..bee5a89c4c7 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -37,7 +37,7 @@
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 #[macro_use]
diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs
index ca908671ae5..30403a61442 100644
--- a/compiler/rustc_data_structures/src/memmap.rs
+++ b/compiler/rustc_data_structures/src/memmap.rs
@@ -11,9 +11,14 @@ pub struct Mmap(Vec<u8>);
 
 #[cfg(not(target_arch = "wasm32"))]
 impl Mmap {
+    /// # Safety
+    ///
+    /// The given file must not be mutated (i.e., not written, not truncated, ...) until the mapping is closed.
+    ///
+    /// However in practice most callers do not ensure this, so uses of this function are likely unsound.
     #[inline]
     pub unsafe fn map(file: File) -> io::Result<Self> {
-        // Safety: this is in fact not safe.
+        // Safety: the caller must ensure that this is safe.
         unsafe { memmap2::Mmap::map(&file).map(Mmap) }
     }
 }
diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs
index 40cbf14958e..52ab5a7fb14 100644
--- a/compiler/rustc_data_structures/src/sharded.rs
+++ b/compiler/rustc_data_structures/src/sharded.rs
@@ -1,31 +1,26 @@
 use crate::fx::{FxHashMap, FxHasher};
 #[cfg(parallel_compiler)]
-use crate::sync::is_dyn_thread_safe;
-use crate::sync::{CacheAligned, Lock, LockGuard};
+use crate::sync::{is_dyn_thread_safe, CacheAligned};
+use crate::sync::{Lock, LockGuard};
 use std::borrow::Borrow;
 use std::collections::hash_map::RawEntryMut;
 use std::hash::{Hash, Hasher};
 use std::mem;
 
-#[cfg(parallel_compiler)]
 // 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700,
 // but this should be tested on higher core count CPUs. How the `Sharded` type gets used
 // may also affect the ideal number of shards.
 const SHARD_BITS: usize = 5;
 
-#[cfg(not(parallel_compiler))]
-const SHARD_BITS: usize = 0;
-
-pub const SHARDS: usize = 1 << SHARD_BITS;
+#[cfg(parallel_compiler)]
+const SHARDS: usize = 1 << SHARD_BITS;
 
 /// An array of cache-line aligned inner locked structures with convenience methods.
-pub struct Sharded<T> {
-    /// This mask is used to ensure that accesses are inbounds of `shards`.
-    /// When dynamic thread safety is off, this field is set to 0 causing only
-    /// a single shard to be used for greater cache efficiency.
+/// A single field is used when the compiler uses only one thread.
+pub enum Sharded<T> {
+    Single(Lock<T>),
     #[cfg(parallel_compiler)]
-    mask: usize,
-    shards: [CacheAligned<Lock<T>>; SHARDS],
+    Shards(Box<[CacheAligned<Lock<T>>; SHARDS]>),
 }
 
 impl<T: Default> Default for Sharded<T> {
@@ -38,35 +33,24 @@ impl<T: Default> Default for Sharded<T> {
 impl<T> Sharded<T> {
     #[inline]
     pub fn new(mut value: impl FnMut() -> T) -> Self {
-        Sharded {
-            #[cfg(parallel_compiler)]
-            mask: if is_dyn_thread_safe() { SHARDS - 1 } else { 0 },
-            shards: [(); SHARDS].map(|()| CacheAligned(Lock::new(value()))),
-        }
-    }
-
-    #[inline(always)]
-    fn mask(&self) -> usize {
         #[cfg(parallel_compiler)]
-        {
-            if SHARDS == 1 { 0 } else { self.mask }
-        }
-        #[cfg(not(parallel_compiler))]
-        {
-            0
+        if is_dyn_thread_safe() {
+            return Sharded::Shards(Box::new(
+                [(); SHARDS].map(|()| CacheAligned(Lock::new(value()))),
+            ));
         }
-    }
 
-    #[inline(always)]
-    fn count(&self) -> usize {
-        // `self.mask` is always one below the used shard count
-        self.mask() + 1
+        Sharded::Single(Lock::new(value()))
     }
 
     /// The shard is selected by hashing `val` with `FxHasher`.
     #[inline]
-    pub fn get_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> &Lock<T> {
-        self.get_shard_by_hash(if SHARDS == 1 { 0 } else { make_hash(val) })
+    pub fn get_shard_by_value<K: Hash + ?Sized>(&self, _val: &K) -> &Lock<T> {
+        match self {
+            Self::Single(single) => &single,
+            #[cfg(parallel_compiler)]
+            Self::Shards(..) => self.get_shard_by_hash(make_hash(_val)),
+        }
     }
 
     #[inline]
@@ -75,20 +59,44 @@ impl<T> Sharded<T> {
     }
 
     #[inline]
-    pub fn get_shard_by_index(&self, i: usize) -> &Lock<T> {
-        // SAFETY: The index get ANDed with the mask, ensuring it is always inbounds.
-        unsafe { &self.shards.get_unchecked(i & self.mask()).0 }
+    pub fn get_shard_by_index(&self, _i: usize) -> &Lock<T> {
+        match self {
+            Self::Single(single) => &single,
+            #[cfg(parallel_compiler)]
+            Self::Shards(shards) => {
+                // SAFETY: The index gets ANDed with the shard mask, ensuring it is always inbounds.
+                unsafe { &shards.get_unchecked(_i & (SHARDS - 1)).0 }
+            }
+        }
     }
 
     pub fn lock_shards(&self) -> Vec<LockGuard<'_, T>> {
-        (0..self.count()).map(|i| self.get_shard_by_index(i).lock()).collect()
+        match self {
+            Self::Single(single) => vec![single.lock()],
+            #[cfg(parallel_compiler)]
+            Self::Shards(shards) => shards.iter().map(|shard| shard.0.lock()).collect(),
+        }
     }
 
     pub fn try_lock_shards(&self) -> Option<Vec<LockGuard<'_, T>>> {
-        (0..self.count()).map(|i| self.get_shard_by_index(i).try_lock()).collect()
+        match self {
+            Self::Single(single) => Some(vec![single.try_lock()?]),
+            #[cfg(parallel_compiler)]
+            Self::Shards(shards) => shards.iter().map(|shard| shard.0.try_lock()).collect(),
+        }
     }
 }
 
+#[inline]
+pub fn shards() -> usize {
+    #[cfg(parallel_compiler)]
+    if is_dyn_thread_safe() {
+        return SHARDS;
+    }
+
+    1
+}
+
 pub type ShardedHashMap<K, V> = Sharded<FxHashMap<K, V>>;
 
 impl<K: Eq, V> ShardedHashMap<K, V> {
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index 8c84daf4f16..27d687c3cfe 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -171,3 +171,9 @@ impl<T> Deref for WorkerLocal<T> {
         unsafe { &self.locals.get_unchecked(self.registry.id().verify()).0 }
     }
 }
+
+impl<T: Default> Default for WorkerLocal<T> {
+    fn default() -> Self {
+        WorkerLocal::new(|_| T::default())
+    }
+}
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 7bbed0877f0..841c626d0a3 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -140,12 +140,6 @@ pub const EXIT_FAILURE: i32 = 1;
 pub const DEFAULT_BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/issues/new\
     ?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md";
 
-const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"];
-
-const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"];
-
-const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
-
 pub fn abort_on_err<T>(result: Result<T, ErrorGuaranteed>, sess: &Session) -> T {
     match result {
         Err(..) => {
@@ -1250,47 +1244,6 @@ fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
     }
 }
 
-/// Gets a list of extra command-line flags provided by the user, as strings.
-///
-/// This function is used during ICEs to show more information useful for
-/// debugging, since some ICEs only happens with non-default compiler flags
-/// (and the users don't always report them).
-fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
-    let mut args = env::args_os().map(|arg| arg.to_string_lossy().to_string()).peekable();
-
-    let mut result = Vec::new();
-    let mut excluded_cargo_defaults = false;
-    while let Some(arg) = args.next() {
-        if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
-            let content = if arg.len() == a.len() {
-                // A space-separated option, like `-C incremental=foo` or `--crate-type rlib`
-                match args.next() {
-                    Some(arg) => arg.to_string(),
-                    None => continue,
-                }
-            } else if arg.get(a.len()..a.len() + 1) == Some("=") {
-                // An equals option, like `--crate-type=rlib`
-                arg[a.len() + 1..].to_string()
-            } else {
-                // A non-space option, like `-Cincremental=foo`
-                arg[a.len()..].to_string()
-            };
-            let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
-            if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) {
-                excluded_cargo_defaults = true;
-            } else {
-                result.push(a.to_string());
-                match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
-                    Some(s) => result.push(format!("{s}=[REDACTED]")),
-                    None => result.push(content),
-                }
-            }
-        }
-    }
-
-    if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None }
-}
-
 /// Runs a closure and catches unwinds triggered by fatal errors.
 ///
 /// The compiler currently unwinds with a special sentinel value to abort
@@ -1449,7 +1402,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info:
         None
     };
 
-    if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() {
+    if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() {
         handler.emit_note(session_diagnostics::IceFlags { flags: flags.join(" ") });
         if excluded_cargo_defaults {
             handler.emit_note(session_diagnostics::IceExcludeCargoDefaults);
diff --git a/compiler/rustc_error_codes/src/error_codes/E0191.md b/compiler/rustc_error_codes/src/error_codes/E0191.md
index 46b773bdc50..344ac221698 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0191.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0191.md
@@ -7,8 +7,8 @@ trait Trait {
     type Bar;
 }
 
-type Foo = Trait; // error: the value of the associated type `Bar` (from
-                  //        the trait `Trait`) must be specified
+type Foo = dyn Trait; // error: the value of the associated type `Bar` (from
+                      //        the trait `Trait`) must be specified
 ```
 
 Trait objects need to have all associated types specified. Please verify that
@@ -20,5 +20,5 @@ trait Trait {
     type Bar;
 }
 
-type Foo = Trait<Bar=i32>; // ok!
+type Foo = dyn Trait<Bar=i32>; // ok!
 ```
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 3bf15505090..6c29144569d 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -4,7 +4,7 @@
 #![feature(type_alias_impl_trait)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 34518b53759..b7e1b0c8ad1 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -15,7 +15,7 @@
 #![feature(box_patterns)]
 #![feature(error_reporter)]
 #![allow(incomplete_features)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_macros;
@@ -197,8 +197,14 @@ impl CodeSuggestion {
 
         use rustc_span::{CharPos, Pos};
 
-        /// Append to a buffer the remainder of the line of existing source code, and return the
-        /// count of lines that have been added for accurate highlighting.
+        /// Extracts a substring from the provided `line_opt` based on the specified low and high indices,
+        /// appends it to the given buffer `buf`, and returns the count of newline characters in the substring
+        /// for accurate highlighting.
+        /// If `line_opt` is `None`, a newline character is appended to the buffer, and 0 is returned.
+        ///
+        /// ## Returns
+        ///
+        /// The count of newline characters in the extracted substring.
         fn push_trailing(
             buf: &mut String,
             line_opt: Option<&Cow<'_, str>>,
@@ -206,22 +212,30 @@ impl CodeSuggestion {
             hi_opt: Option<&Loc>,
         ) -> usize {
             let mut line_count = 0;
+            // Convert CharPos to Usize, as CharPose is character offset
+            // Extract low index and high index
             let (lo, hi_opt) = (lo.col.to_usize(), hi_opt.map(|hi| hi.col.to_usize()));
             if let Some(line) = line_opt {
                 if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) {
+                    // Get high index while account for rare unicode and emoji with char_indices
                     let hi_opt = hi_opt.and_then(|hi| line.char_indices().map(|(i, _)| i).nth(hi));
                     match hi_opt {
+                        // If high index exist, take string from low to high index
                         Some(hi) if hi > lo => {
+                            // count how many '\n' exist
                             line_count = line[lo..hi].matches('\n').count();
                             buf.push_str(&line[lo..hi])
                         }
                         Some(_) => (),
+                        // If high index absence, take string from low index till end string.len
                         None => {
+                            // count how many '\n' exist
                             line_count = line[lo..].matches('\n').count();
                             buf.push_str(&line[lo..])
                         }
                     }
                 }
+                // If high index is None
                 if hi_opt.is_none() {
                     buf.push('\n');
                 }
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index c4a9b2ace9a..8b1fc5b90b4 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -11,7 +11,7 @@
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index f5708f933d5..1941390dc4a 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -282,7 +282,7 @@ declare_features! (
     (active, arm_target_feature, "1.27.0", Some(44839), None),
     (active, avx512_target_feature, "1.27.0", Some(44839), None),
     (active, bpf_target_feature, "1.54.0", Some(44839), None),
-    (active, csky_target_feature, "CURRENT_RUSTC_VERSION", Some(44839), None),
+    (active, csky_target_feature, "1.73.0", Some(44839), None),
     (active, ermsb_target_feature, "1.49.0", Some(44839), None),
     (active, hexagon_target_feature, "1.27.0", Some(44839), None),
     (active, mips_target_feature, "1.27.0", Some(44839), None),
@@ -315,7 +315,7 @@ declare_features! (
     /// Allows `extern "ptx-*" fn()`.
     (active, abi_ptx, "1.15.0", Some(38788), None),
     /// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.
-    (active, abi_riscv_interrupt, "CURRENT_RUSTC_VERSION", Some(111889), None),
+    (active, abi_riscv_interrupt, "1.73.0", Some(111889), None),
     /// Allows `extern "x86-interrupt" fn()`.
     (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
     /// Allows additional const parameter types, such as `&'static str` or user defined types
@@ -341,7 +341,7 @@ declare_features! (
     /// Allows async functions to be declared, implemented, and used in traits.
     (active, async_fn_in_trait, "1.66.0", Some(91611), None),
     /// Allows `#[track_caller]` on async functions.
-    (active, async_fn_track_caller, "CURRENT_RUSTC_VERSION", Some(110011), None),
+    (active, async_fn_track_caller, "1.73.0", Some(110011), None),
     /// Allows builtin # foo() syntax
     (active, builtin_syntax, "1.71.0", Some(110680), None),
     /// Allows `c"foo"` literals.
@@ -353,7 +353,7 @@ declare_features! (
     /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
     (active, cfg_overflow_checks, "1.71.0", Some(111466), None),
     /// Provides the relocation model information as cfg entry
-    (active, cfg_relocation_model, "CURRENT_RUSTC_VERSION", Some(114929), None),
+    (active, cfg_relocation_model, "1.73.0", Some(114929), None),
     /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
     (active, cfg_sanitize, "1.41.0", Some(39699), None),
     /// Allows `cfg(target_abi = "...")`.
@@ -411,7 +411,7 @@ declare_features! (
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
     (active, deprecated_suggestion, "1.61.0", Some(94785), None),
     /// Allows using the `#[diagnostic]` attribute tool namespace
-    (active, diagnostic_namespace, "CURRENT_RUSTC_VERSION", Some(94785), None),
+    (active, diagnostic_namespace, "1.73.0", Some(94785), None),
     /// Controls errors in trait implementations.
     (active, do_not_recommend, "1.67.0", Some(51992), None),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
@@ -456,7 +456,7 @@ declare_features! (
     /// Allows non-trivial generic constants which have to have wfness manually propagated to callers
     (incomplete, generic_const_exprs, "1.56.0", Some(76560), None),
     /// Allows generic parameters and where-clauses on free & associated const items.
-    (incomplete, generic_const_items, "CURRENT_RUSTC_VERSION", Some(113521), None),
+    (incomplete, generic_const_items, "1.73.0", Some(113521), None),
     /// Allows using `..=X` as a patterns in slices.
     (active, half_open_range_patterns_in_slices, "1.66.0", Some(67264), None),
     /// Allows `if let` guard in match arms.
@@ -584,6 +584,8 @@ declare_features! (
     (active, type_privacy_lints, "1.72.0", Some(48054), None),
     /// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
     (active, unix_sigpipe, "1.65.0", Some(97889), None),
+    /// Allows unnamed fields of struct and union type
+    (incomplete, unnamed_fields, "CURRENT_RUSTC_VERSION", Some(49804), None),
     /// Allows unsized fn parameters.
     (active, unsized_fn_params, "1.49.0", Some(48055), None),
     /// Allows unsized rvalues at arguments and parameters.
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 302a9498413..23b20543d53 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -238,6 +238,7 @@ language_item_table! {
     PanicLocation,           sym::panic_location,      panic_location,             Target::Struct,         GenericRequirement::None;
     PanicImpl,               sym::panic_impl,          panic_impl,                 Target::Fn,             GenericRequirement::None;
     PanicCannotUnwind,       sym::panic_cannot_unwind, panic_cannot_unwind,        Target::Fn,             GenericRequirement::Exact(0);
+    PanicInCleanup,          sym::panic_in_cleanup,    panic_in_cleanup,           Target::Fn,             GenericRequirement::Exact(0);
     /// libstd panic entry point. Necessary for const eval to be able to catch it
     BeginPanic,              sym::begin_panic,         begin_panic_fn,             Target::Fn,             GenericRequirement::None;
 
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 34214931a08..094d5b1e77c 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -13,7 +13,7 @@
 #![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index bd311c98fac..6082d446979 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -597,7 +597,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 }
             }
         }
-        if !suggestions.is_empty() {
+        suggestions.sort_by_key(|&(span, _)| span);
+        // There are cases where one bound points to a span within another bound's span, like when
+        // you have code like the following (#115019), so we skip providing a suggestion in those
+        // cases to avoid having a malformed suggestion.
+        //
+        // pub struct Flatten<I> {
+        //     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::core,
+        //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        //             |                  ^^^^^^^^^^^^^^^^^^^^^
+        //             |                  |
+        //             |                  associated types `Item`, `IntoIter` must be specified
+        //             associated types `Item`, `IntoIter` must be specified
+        // }
+        let overlaps = suggestions.windows(2).any(|pair| pair[0].0.overlaps(pair[1].0));
+        if !suggestions.is_empty() && !overlaps {
             err.multipart_suggestion(
                 format!("specify the associated type{}", pluralize!(types_count)),
                 suggestions,
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index ad02ca252c4..bd0ab6463f0 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -342,9 +342,16 @@ fn compare_method_predicate_entailment<'tcx>(
                 continue;
             };
             for obligation in obligations {
+                debug!(?obligation);
                 match obligation.predicate.kind().skip_binder() {
+                    // We need to register Projection oblgiations too, because we may end up with
+                    // an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
+                    // If we only register the region outlives obligation, this leads to an unconstrained var.
+                    // See `implied_bounds_entailment_alias_var` test.
                     ty::PredicateKind::Clause(
-                        ty::ClauseKind::RegionOutlives(..) | ty::ClauseKind::TypeOutlives(..),
+                        ty::ClauseKind::RegionOutlives(..)
+                        | ty::ClauseKind::TypeOutlives(..)
+                        | ty::ClauseKind::Projection(..),
                     ) => ocx.register_obligation(obligation),
                     ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
                         if wf_args_seen.insert(arg) {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 945953edd5a..cd7e9917204 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -44,20 +44,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         false
     }
 
-    fn check_asm_operand_type(
-        &self,
-        idx: usize,
-        reg: InlineAsmRegOrRegClass,
-        expr: &'tcx hir::Expr<'tcx>,
-        template: &[InlineAsmTemplatePiece],
-        is_input: bool,
-        tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>,
-        target_features: &FxIndexSet<Symbol>,
-    ) -> Option<InlineAsmType> {
-        let ty = (self.get_operand_ty)(expr);
-        if ty.has_non_region_infer() {
-            bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty);
-        }
+    fn get_asm_ty(&self, ty: Ty<'tcx>) -> Option<InlineAsmType> {
         let asm_ty_isize = match self.tcx.sess.target.pointer_width {
             16 => InlineAsmType::I16,
             32 => InlineAsmType::I32,
@@ -65,10 +52,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             _ => unreachable!(),
         };
 
-        let asm_ty = match *ty.kind() {
-            // `!` is allowed for input but not for output (issue #87802)
-            ty::Never if is_input => return None,
-            _ if ty.references_error() => return None,
+        match *ty.kind() {
             ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
             ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
             ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
@@ -99,7 +83,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                 };
 
                 match ty.kind() {
-                    ty::Never | ty::Error(_) => return None,
                     ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)),
                     ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => {
                         Some(InlineAsmType::VecI16(size))
@@ -128,6 +111,38 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             }
             ty::Infer(_) => unreachable!(),
             _ => None,
+        }
+    }
+
+    fn check_asm_operand_type(
+        &self,
+        idx: usize,
+        reg: InlineAsmRegOrRegClass,
+        expr: &'tcx hir::Expr<'tcx>,
+        template: &[InlineAsmTemplatePiece],
+        is_input: bool,
+        tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>,
+        target_features: &FxIndexSet<Symbol>,
+    ) -> Option<InlineAsmType> {
+        let ty = (self.get_operand_ty)(expr);
+        if ty.has_non_region_infer() {
+            bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty);
+        }
+
+        let asm_ty = match *ty.kind() {
+            // `!` is allowed for input but not for output (issue #87802)
+            ty::Never if is_input => return None,
+            _ if ty.references_error() => return None,
+            ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => {
+                let fields = &adt.non_enum_variant().fields;
+                let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args);
+                let ty::Adt(ty, args) = ty.kind() else { unreachable!() };
+                assert!(ty.is_manually_drop());
+                let fields = &ty.non_enum_variant().fields;
+                let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
+                self.get_asm_ty(ty)
+            }
+            _ => self.get_asm_ty(ty),
         };
         let Some(asm_ty) = asm_ty else {
             let msg = format!("cannot use value of type `{ty}` for inline assembly");
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 4cf3587327d..d8331661366 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -289,6 +289,7 @@ fn default_body_is_unstable(
         &tcx.sess.parse_sess,
         feature,
         rustc_feature::GateIssue::Library(issue),
+        false,
     );
 
     err.emit();
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index c44d12e61e3..f6a5b8f97a1 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -1,6 +1,6 @@
 use crate::FnCtxt;
 use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -133,15 +133,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                 }
-                // Notably, we only point to params that are local to the
-                // item we're checking, since those are the ones we are able
-                // to look in the final `hir::PathSegment` for. Everything else
-                // would require a deeper search into the `qpath` than I think
-                // is worthwhile.
-                if let Some(param_to_point_at) = param_to_point_at
-                    && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
+
+                for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+                    .into_iter()
+                    .flatten()
                 {
-                    return true;
+                    if self.point_at_path_if_possible(error, def_id, param, qpath) {
+                        return true;
+                    }
                 }
             }
             hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
@@ -166,12 +165,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 {
                     return true;
                 }
+                // Handle `Self` param specifically, since it's separated in
+                // the method call representation
+                if self_param_to_point_at.is_some() {
+                    error.obligation.cause.span = receiver
+                        .span
+                        .find_ancestor_in_same_ctxt(error.obligation.cause.span)
+                        .unwrap_or(receiver.span);
+                    return true;
+                }
             }
             hir::ExprKind::Struct(qpath, fields, ..) => {
-                if let Res::Def(
-                    hir::def::DefKind::Struct | hir::def::DefKind::Variant,
-                    variant_def_id,
-                ) = self.typeck_results.borrow().qpath_res(qpath, hir_id)
+                if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
+                    self.typeck_results.borrow().qpath_res(qpath, hir_id)
                 {
                     for param in
                         [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
@@ -193,10 +199,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                 }
-                if let Some(param_to_point_at) = param_to_point_at
-                    && self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
+
+                for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+                    .into_iter()
+                    .flatten()
                 {
-                    return true;
+                    if self.point_at_path_if_possible(error, def_id, param, qpath) {
+                        return true;
+                    }
                 }
             }
             _ => {}
@@ -213,17 +223,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         qpath: &hir::QPath<'tcx>,
     ) -> bool {
         match qpath {
-            hir::QPath::Resolved(_, path) => {
-                if let Some(segment) = path.segments.last()
-                    && self.point_at_generic_if_possible(error, def_id, param, segment)
+            hir::QPath::Resolved(self_ty, path) => {
+                for segment in path.segments.iter().rev() {
+                    if let Res::Def(kind, def_id) = segment.res
+                        && !matches!(kind, DefKind::Mod | DefKind::ForeignMod)
+                        && self.point_at_generic_if_possible(error, def_id, param, segment)
+                    {
+                        return true;
+                    }
+                }
+                // Handle `Self` param specifically, since it's separated in
+                // the path representation
+                if let Some(self_ty) = self_ty
+                    && let ty::GenericArgKind::Type(ty) = param.unpack()
+                    && ty == self.tcx.types.self_param
                 {
+                    error.obligation.cause.span = self_ty
+                        .span
+                        .find_ancestor_in_same_ctxt(error.obligation.cause.span)
+                        .unwrap_or(self_ty.span);
                     return true;
                 }
             }
-            hir::QPath::TypeRelative(_, segment) => {
+            hir::QPath::TypeRelative(self_ty, segment) => {
                 if self.point_at_generic_if_possible(error, def_id, param, segment) {
                     return true;
                 }
+                // Handle `Self` param specifically, since it's separated in
+                // the path representation
+                if let ty::GenericArgKind::Type(ty) = param.unpack()
+                    && ty == self.tcx.types.self_param
+                {
+                    error.obligation.cause.span = self_ty
+                        .span
+                        .find_ancestor_in_same_ctxt(error.obligation.cause.span)
+                        .unwrap_or(self_ty.span);
+                    return true;
+                }
             }
             _ => {}
         }
@@ -618,14 +654,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
 
             let variant_def_id = match expr_struct_def_kind {
-                hir::def::DefKind::Struct => {
+                DefKind::Struct => {
                     if in_ty_adt.did() != expr_struct_def_id {
                         // FIXME: Deal with type aliases?
                         return Err(expr);
                     }
                     expr_struct_def_id
                 }
-                hir::def::DefKind::Variant => {
+                DefKind::Variant => {
                     // If this is a variant, its parent is the type definition.
                     if in_ty_adt.did() != self.tcx.parent(expr_struct_def_id) {
                         // FIXME: Deal with type aliases?
@@ -727,14 +763,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
 
             let variant_def_id = match expr_struct_def_kind {
-                hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
+                DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
                     if in_ty_adt.did() != self.tcx.parent(expr_ctor_def_id) {
                         // FIXME: Deal with type aliases?
                         return Err(expr);
                     }
                     self.tcx.parent(expr_ctor_def_id)
                 }
-                hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
+                DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
                     // For a typical enum like
                     // `enum Blah<T> { Variant(T) }`
                     // we get the following resolutions:
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index c4d3cbc9faa..f17f1d14bf3 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -436,6 +436,12 @@ fn fatally_break_rust(tcx: TyCtxt<'_>) {
         tcx.sess.cfg_version,
         config::host_triple(),
     ));
+    if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() {
+        handler.note_without_error(format!("compiler flags: {}", flags.join(" ")));
+        if excluded_cargo_defaults {
+            handler.note_without_error("some of the compiler flags provided by cargo are hidden");
+        }
+    }
 }
 
 fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool {
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 9942c70c4ae..061c55c0150 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -12,7 +12,7 @@
         test
     )
 )]
-#![cfg_attr(all(not(bootstrap), feature = "nightly"), allow(internal_features))]
+#![cfg_attr(feature = "nightly", allow(internal_features))]
 
 #[cfg(feature = "nightly")]
 pub mod bit_set;
@@ -29,6 +29,18 @@ pub use {idx::Idx, slice::IndexSlice, vec::IndexVec};
 pub use rustc_macros::newtype_index;
 
 /// Type size assertion. The first argument is a type and the second argument is its expected size.
+///
+/// <div class="warning">
+///
+/// Emitting hard errors from size assertions like this is generally not
+/// recommended, especially in libraries, because they can cause build failures if the layout
+/// algorithm or dependencies change. Here in rustc we control the toolchain and layout algorithm,
+/// so the former is not a problem. For the latter we have a lockfile as rustc is an application and
+/// precompiled library.
+///
+/// Short version: Don't copy this macro into your own code. Use a `#[test]` instead.
+///
+/// </div>
 #[macro_export]
 macro_rules! static_assert_size {
     ($ty:ty, $size:expr) => {
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index e3d66d18388..db669ca7250 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -821,7 +821,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(profile_emit, Some(PathBuf::from("abc")));
     tracked!(profile_sample_use, Some(PathBuf::from("abc")));
     tracked!(profiler_runtime, "abc".to_string());
-    tracked!(relax_elf_relocations, Some(true));
+    tracked!(relax_elf_relocations, Some(false));
     tracked!(relro_level, Some(RelroLevel::Full));
     tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
     tracked!(report_delayed_bugs, true);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index c4a7f717840..7f7f36ca170 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -158,13 +158,15 @@ lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}`
 
 lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name}
 
+lint_check_name_removed = lint `{$lint_name}` has been removed: {$reason}
+
+lint_check_name_renamed = lint `{$lint_name}` has been renamed to `{$replace}`
+
 lint_check_name_unknown = unknown lint: `{$lint_name}`
     .help = did you mean: `{$suggestion}`
 
 lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}`
 
-lint_check_name_warning = {$msg}
-
 lint_command_line_source = `forbid` lint level was set on command line
 
 lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike
@@ -323,6 +325,8 @@ lint_invalid_reference_casting_assign_to_ref = assigning to `&T` is undefined be
 lint_invalid_reference_casting_borrow_as_mut = casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
     .label = casting happend here
 
+lint_invalid_reference_casting_note_book = for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
 lint_lintpass_by_hand = implementing `LintPass` by hand
     .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
 
@@ -482,8 +486,11 @@ lint_redundant_semicolons =
         *[false] this semicolon
     }
 
-lint_renamed_or_removed_lint = {$msg}
+lint_removed_lint = lint `{$name}` has been removed: {$reason}
+
+lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}`
     .suggestion = use the new name
+    .help = use the new name `{$replace}`
 
 lint_requested_level = requested on the command line with `{$level} {$lint_name}`
 
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index f73797415bc..9dfde84b552 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -17,8 +17,8 @@
 use self::TargetLint::*;
 
 use crate::errors::{
-    CheckNameDeprecated, CheckNameUnknown, CheckNameUnknownTool, CheckNameWarning, RequestedLevel,
-    UnsupportedGroup,
+    CheckNameDeprecated, CheckNameRemoved, CheckNameRenamed, CheckNameUnknown,
+    CheckNameUnknownTool, RequestedLevel, UnsupportedGroup,
 };
 use crate::levels::LintLevelsBuilder;
 use crate::passes::{EarlyLintPassObject, LateLintPassObject};
@@ -124,9 +124,10 @@ pub enum CheckLintNameResult<'a> {
     NoLint(Option<Symbol>),
     /// The lint refers to a tool that has not been registered.
     NoTool,
-    /// The lint is either renamed or removed. This is the warning
-    /// message, and an optional new name (`None` if removed).
-    Warning(String, Option<String>),
+    /// The lint has been renamed to a new name.
+    Renamed(String),
+    /// The lint has been removed due to the given reason.
+    Removed(String),
     /// The lint is from a tool. If the Option is None, then either
     /// the lint does not exist in the tool or the code was not
     /// compiled with the tool and therefore the lint was never
@@ -342,25 +343,32 @@ impl LintStore {
             sess.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() });
             return;
         }
-        let lint_name = lint_name.to_string();
         match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
-            CheckLintNameResult::Warning(msg, _) => {
-                sess.emit_warning(CheckNameWarning {
-                    msg,
+            CheckLintNameResult::Renamed(replace) => {
+                sess.emit_warning(CheckNameRenamed {
+                    lint_name,
+                    replace: &replace,
+                    sub: RequestedLevel { level, lint_name },
+                });
+            }
+            CheckLintNameResult::Removed(reason) => {
+                sess.emit_warning(CheckNameRemoved {
+                    lint_name,
+                    reason: &reason,
                     sub: RequestedLevel { level, lint_name },
                 });
             }
             CheckLintNameResult::NoLint(suggestion) => {
                 sess.emit_err(CheckNameUnknown {
-                    lint_name: lint_name.clone(),
+                    lint_name,
                     suggestion,
                     sub: RequestedLevel { level, lint_name },
                 });
             }
             CheckLintNameResult::Tool(Err((Some(_), new_name))) => {
                 sess.emit_warning(CheckNameDeprecated {
-                    lint_name: lint_name.clone(),
-                    new_name,
+                    lint_name,
+                    new_name: &new_name,
                     sub: RequestedLevel { level, lint_name },
                 });
             }
@@ -445,14 +453,8 @@ impl LintStore {
             }
         }
         match self.by_name.get(&complete_name) {
-            Some(Renamed(new_name, _)) => CheckLintNameResult::Warning(
-                format!("lint `{complete_name}` has been renamed to `{new_name}`"),
-                Some(new_name.to_owned()),
-            ),
-            Some(Removed(reason)) => CheckLintNameResult::Warning(
-                format!("lint `{complete_name}` has been removed: {reason}"),
-                None,
-            ),
+            Some(Renamed(new_name, _)) => CheckLintNameResult::Renamed(new_name.to_string()),
+            Some(Removed(reason)) => CheckLintNameResult::Removed(reason.to_string()),
             None => match self.lint_groups.get(&*complete_name) {
                 // If neither the lint, nor the lint group exists check if there is a `clippy::`
                 // variant of this lint
@@ -966,6 +968,14 @@ pub trait LintContext: Sized {
                         Applicability::MachineApplicable
                     );
                 }
+                BuiltinLintDiagnostics::AssociatedConstElidedLifetime { elided, span } => {
+                    db.span_suggestion_verbose(
+                        if elided { span.shrink_to_hi() } else { span },
+                        "use the `'static` lifetime",
+                        if elided { "'static " } else { "'static" },
+                        Applicability::MachineApplicable
+                    );
+                }
             }
             // Rewrap `db`, and pass control to the user.
             decorate(db)
diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs
index 68167487a1b..607875b3faa 100644
--- a/compiler/rustc_lint/src/errors.rs
+++ b/compiler/rustc_lint/src/errors.rs
@@ -91,9 +91,9 @@ pub struct BuiltinEllipsisInclusiveRangePatterns {
 
 #[derive(Subdiagnostic)]
 #[note(lint_requested_level)]
-pub struct RequestedLevel {
+pub struct RequestedLevel<'a> {
     pub level: Level,
-    pub lint_name: String,
+    pub lint_name: &'a str,
 }
 
 #[derive(Diagnostic)]
@@ -102,13 +102,13 @@ pub struct UnsupportedGroup {
     pub lint_group: String,
 }
 
-pub struct CheckNameUnknown {
-    pub lint_name: String,
+pub struct CheckNameUnknown<'a> {
+    pub lint_name: &'a str,
     pub suggestion: Option<Symbol>,
-    pub sub: RequestedLevel,
+    pub sub: RequestedLevel<'a>,
 }
 
-impl IntoDiagnostic<'_> for CheckNameUnknown {
+impl IntoDiagnostic<'_> for CheckNameUnknown<'_> {
     fn into_diagnostic(
         self,
         handler: &Handler,
@@ -127,25 +127,35 @@ impl IntoDiagnostic<'_> for CheckNameUnknown {
 
 #[derive(Diagnostic)]
 #[diag(lint_check_name_unknown_tool, code = "E0602")]
-pub struct CheckNameUnknownTool {
+pub struct CheckNameUnknownTool<'a> {
     pub tool_name: Symbol,
     #[subdiagnostic]
-    pub sub: RequestedLevel,
+    pub sub: RequestedLevel<'a>,
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_check_name_warning)]
-pub struct CheckNameWarning {
-    pub msg: String,
+#[diag(lint_check_name_renamed)]
+pub struct CheckNameRenamed<'a> {
+    pub lint_name: &'a str,
+    pub replace: &'a str,
     #[subdiagnostic]
-    pub sub: RequestedLevel,
+    pub sub: RequestedLevel<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(lint_check_name_removed)]
+pub struct CheckNameRemoved<'a> {
+    pub lint_name: &'a str,
+    pub reason: &'a str,
+    #[subdiagnostic]
+    pub sub: RequestedLevel<'a>,
 }
 
 #[derive(Diagnostic)]
 #[diag(lint_check_name_deprecated)]
-pub struct CheckNameDeprecated {
-    pub lint_name: String,
-    pub new_name: String,
+pub struct CheckNameDeprecated<'a> {
+    pub lint_name: &'a str,
+    pub new_name: &'a str,
     #[subdiagnostic]
-    pub sub: RequestedLevel,
+    pub sub: RequestedLevel<'a>,
 }
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 1f4e5fa4d3b..f58782c0f22 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -4,15 +4,15 @@ use crate::{
     fluent_generated as fluent,
     late::unerased_lint_store,
     lints::{
-        DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAttributeLint,
-        RenamedOrRemovedLint, RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion,
+        DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAttributeLint, RemovedLint,
+        RenamedLint, RenamedLintSuggestion, UnknownLint, UnknownLintSuggestion,
     },
 };
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
-use rustc_feature::Features;
+use rustc_feature::{Features, GateIssue};
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
@@ -24,12 +24,14 @@ use rustc_middle::lint::{
 };
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{RegisteredTools, TyCtxt};
-use rustc_session::lint::builtin::{RENAMED_AND_REMOVED_LINTS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES};
 use rustc_session::lint::{
-    builtin::{self, FORBIDDEN_LINT_GROUPS, SINGLE_USE_LIFETIMES, UNFULFILLED_LINT_EXPECTATIONS},
+    builtin::{
+        self, FORBIDDEN_LINT_GROUPS, RENAMED_AND_REMOVED_LINTS, SINGLE_USE_LIFETIMES,
+        UNFULFILLED_LINT_EXPECTATIONS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES,
+    },
     Level, Lint, LintExpectationId, LintId,
 };
-use rustc_session::parse::{add_feature_diagnostics, feature_err};
+use rustc_session::parse::feature_err;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
@@ -566,7 +568,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                     continue;
                 }
 
-                if self.check_gated_lint(id, DUMMY_SP) {
+                if self.check_gated_lint(id, DUMMY_SP, true) {
                     let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
                     self.insert(id, (level, src));
                 }
@@ -837,7 +839,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                             reason,
                         };
                         for &id in *ids {
-                            if self.check_gated_lint(id, attr.span) {
+                            if self.check_gated_lint(id, attr.span, false) {
                                 self.insert_spec(id, (level, src));
                             }
                         }
@@ -854,7 +856,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                                     reason,
                                 };
                                 for &id in ids {
-                                    if self.check_gated_lint(id, attr.span) {
+                                    if self.check_gated_lint(id, attr.span, false) {
                                         self.insert_spec(id, (level, src));
                                     }
                                 }
@@ -913,18 +915,26 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
 
                     _ if !self.warn_about_weird_lints => {}
 
-                    CheckLintNameResult::Warning(msg, renamed) => {
+                    CheckLintNameResult::Renamed(new_name) => {
                         let suggestion =
-                            renamed.as_ref().map(|replace| RenamedOrRemovedLintSuggestion {
-                                suggestion: sp,
-                                replace: replace.as_str(),
-                            });
+                            RenamedLintSuggestion { suggestion: sp, replace: new_name.as_str() };
+                        let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
+                        self.emit_spanned_lint(
+                            RENAMED_AND_REMOVED_LINTS,
+                            sp.into(),
+                            RenamedLint { name: name.as_str(), suggestion },
+                        );
+                    }
+
+                    CheckLintNameResult::Removed(reason) => {
+                        let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name);
                         self.emit_spanned_lint(
                             RENAMED_AND_REMOVED_LINTS,
                             sp.into(),
-                            RenamedOrRemovedLint { msg, suggestion },
+                            RemovedLint { name: name.as_str(), reason: reason.as_str() },
                         );
                     }
+
                     CheckLintNameResult::NoLint(suggestion) => {
                         let name = if let Some(tool_ident) = tool_ident {
                             format!("{}::{}", tool_ident.name, name)
@@ -943,7 +953,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                 // If this lint was renamed, apply the new lint instead of ignoring the attribute.
                 // This happens outside of the match because the new lint should be applied even if
                 // we don't warn about the name change.
-                if let CheckLintNameResult::Warning(_, Some(new_name)) = lint_result {
+                if let CheckLintNameResult::Renamed(new_name) = lint_result {
                     // Ignore any errors or warnings that happen because the new name is inaccurate
                     // NOTE: `new_name` already includes the tool name, so we don't have to add it again.
                     if let CheckLintNameResult::Ok(ids) =
@@ -955,7 +965,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                             reason,
                         };
                         for &id in ids {
-                            if self.check_gated_lint(id, attr.span) {
+                            if self.check_gated_lint(id, attr.span, false) {
                                 self.insert_spec(id, (level, src));
                             }
                         }
@@ -1000,7 +1010,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     // FIXME only emit this once for each attribute, instead of repeating it 4 times for
     // pre-expansion lints, post-expansion lints, `shallow_lint_levels_on` and `lint_expectations`.
     #[track_caller]
-    fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool {
+    fn check_gated_lint(&self, lint_id: LintId, span: Span, lint_from_cli: bool) -> bool {
         if let Some(feature) = lint_id.lint.feature_gate {
             if !self.features.enabled(feature) {
                 let lint = builtin::UNKNOWN_LINTS;
@@ -1015,7 +1025,13 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                     |lint| {
                         lint.set_arg("name", lint_id.lint.name_lower());
                         lint.note(fluent::lint_note);
-                        add_feature_diagnostics(lint, &self.sess.parse_sess, feature);
+                        rustc_session::parse::add_feature_diagnostics_for_issue(
+                            lint,
+                            &self.sess.parse_sess,
+                            feature,
+                            GateIssue::Language,
+                            lint_from_cli,
+                        );
                         lint
                     },
                 );
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 585b10e79e4..e578f09b58f 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -40,7 +40,7 @@
 #![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 25982a45853..0e942d774a7 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -764,11 +764,13 @@ pub enum InvalidFromUtf8Diag {
 #[derive(LintDiagnostic)]
 pub enum InvalidReferenceCastingDiag {
     #[diag(lint_invalid_reference_casting_borrow_as_mut)]
+    #[note(lint_invalid_reference_casting_note_book)]
     BorrowAsMut {
         #[label]
         orig_cast: Option<Span>,
     },
     #[diag(lint_invalid_reference_casting_assign_to_ref)]
+    #[note(lint_invalid_reference_casting_note_book)]
     AssignToRef {
         #[label]
         orig_cast: Option<Span>,
@@ -1010,24 +1012,30 @@ pub struct DeprecatedLintName<'a> {
     pub replace: &'a str,
 }
 
-// FIXME: Non-translatable msg
 #[derive(LintDiagnostic)]
-#[diag(lint_renamed_or_removed_lint)]
-pub struct RenamedOrRemovedLint<'a> {
-    pub msg: &'a str,
+#[diag(lint_renamed_lint)]
+pub struct RenamedLint<'a> {
+    pub name: &'a str,
     #[subdiagnostic]
-    pub suggestion: Option<RenamedOrRemovedLintSuggestion<'a>>,
+    pub suggestion: RenamedLintSuggestion<'a>,
 }
 
 #[derive(Subdiagnostic)]
 #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
-pub struct RenamedOrRemovedLintSuggestion<'a> {
+pub struct RenamedLintSuggestion<'a> {
     #[primary_span]
     pub suggestion: Span,
     pub replace: &'a str,
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_removed_lint)]
+pub struct RemovedLint<'a> {
+    pub name: &'a str,
+    pub reason: &'a str,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(lint_unknown_lint)]
 pub struct UnknownLint {
     pub name: String,
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 2577cabb3f0..883f6242b56 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -56,20 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        // &mut <expr>
-        let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
-            expr
-        // <expr> = ...
-        } else if let ExprKind::Assign(expr, _, _) = expr.kind {
-            expr
-        // <expr> += ...
-        } else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
-            expr
-        } else {
-            return;
-        };
-
-        let ExprKind::Unary(UnOp::Deref, e) = &inner.kind else {
+        let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else {
             return;
         };
 
@@ -86,15 +73,58 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
         cx.emit_spanned_lint(
             INVALID_REFERENCE_CASTING,
             expr.span,
-            if matches!(expr.kind, ExprKind::AddrOf(..)) {
-                InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
-            } else {
+            if is_assignment {
                 InvalidReferenceCastingDiag::AssignToRef { orig_cast }
+            } else {
+                InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
             },
         );
     }
 }
 
+fn is_operation_we_care_about<'tcx>(
+    cx: &LateContext<'tcx>,
+    e: &'tcx Expr<'tcx>,
+) -> Option<(bool, &'tcx Expr<'tcx>)> {
+    fn deref_assign_or_addr_of<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(bool, &'tcx Expr<'tcx>)> {
+        // &mut <expr>
+        let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
+            expr
+        // <expr> = ...
+        } else if let ExprKind::Assign(expr, _, _) = expr.kind {
+            expr
+        // <expr> += ...
+        } else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
+            expr
+        } else {
+            return None;
+        };
+
+        if let ExprKind::Unary(UnOp::Deref, e) = &inner.kind {
+            Some((!matches!(expr.kind, ExprKind::AddrOf(..)), e))
+        } else {
+            None
+        }
+    }
+
+    fn ptr_write<'tcx>(
+        cx: &LateContext<'tcx>,
+        e: &'tcx Expr<'tcx>,
+    ) -> Option<(bool, &'tcx Expr<'tcx>)> {
+        if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned))
+        {
+            Some((true, arg_ptr))
+        } else {
+            None
+        }
+    }
+
+    deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e))
+}
+
 fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
     let e = e.peel_blocks();
 
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 96c31a90da8..0aa37642b74 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3376,6 +3376,7 @@ declare_lint_pass! {
         DEPRECATED_IN_FUTURE,
         DEPRECATED_WHERE_CLAUSE_LOCATION,
         DUPLICATE_MACRO_ATTRIBUTES,
+        ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
         ELIDED_LIFETIMES_IN_PATHS,
         EXPORTED_PRIVATE_DEPENDENCIES,
         FFI_UNWIND_CALLS,
@@ -4527,3 +4528,44 @@ declare_lint! {
         reference: "issue #114095 <https://github.com/rust-lang/rust/issues/114095>",
     };
 }
+
+declare_lint! {
+    /// The `elided_lifetimes_in_associated_constant` lint detects elided lifetimes
+    /// that were erroneously allowed in associated constants.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(elided_lifetimes_in_associated_constant)]
+    ///
+    /// struct Foo;
+    ///
+    /// impl Foo {
+    ///     const STR: &str = "hello, world";
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Previous version of Rust
+    ///
+    /// Implicit static-in-const behavior was decided [against] for associated
+    /// constants because of ambiguity. This, however, regressed and the compiler
+    /// erroneously treats elided lifetimes in associated constants as lifetime
+    /// parameters on the impl.
+    ///
+    /// This is a [future-incompatible] lint to transition this to a
+    /// hard error in the future.
+    ///
+    /// [against]: https://github.com/rust-lang/rust/issues/38831
+    /// [future-incompatible]: ../index.md#future-incompatible-lints
+    pub ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
+    Warn,
+    "elided lifetimes cannot be used in associated constants in impls",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseError,
+        reference: "issue #115010 <https://github.com/rust-lang/rust/issues/115010>",
+    };
+}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index f350957f72f..76e736859d3 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -23,8 +23,9 @@ pub mod builtin;
 
 #[macro_export]
 macro_rules! pluralize {
+    // Pluralize based on count (e.g., apples)
     ($x:expr) => {
-        if $x != 1 { "s" } else { "" }
+        if $x == 1 { "" } else { "s" }
     };
     ("has", $x:expr) => {
         if $x == 1 { "has" } else { "have" }
@@ -572,6 +573,10 @@ pub enum BuiltinLintDiagnostics {
         /// The span of the unnecessarily-qualified path to remove.
         removal_span: Span,
     },
+    AssociatedConstElidedLifetime {
+        elided: bool,
+        span: Span,
+    },
 }
 
 /// Lints that are buffered up early on in the `Session` before the
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
index 35d6b9ed7a4..54fdc84c77d 100644
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
@@ -203,7 +203,12 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers,
     }
   }
 
+#if LLVM_VERSION_LT(18, 0)
   auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
+#else
+  auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab : SymtabWritingMode::NoSymtab;
+  auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false);
+#endif
   if (!Result)
     return LLVMRustResult::Success;
   LLVMRustSetLastError(toString(std::move(Result)).c_str());
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index f4593d0fe73..85829906f4e 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -7,7 +7,7 @@
 #![allow(rustc::default_hash_types)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 #![recursion_limit = "128"]
 
 use synstructure::decl_derive;
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index d3fc1b2850e..50b69181d67 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -63,7 +63,7 @@
 #![feature(macro_metavar_expr)]
 #![recursion_limit = "512"]
 #![allow(rustc::potential_query_instability)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate bitflags;
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 9ef3a1b30e4..6484c30167c 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1275,9 +1275,11 @@ impl<O> AssertKind<O> {
         matches!(self, OverflowNeg(..) | Overflow(Add | Sub | Mul | Shl | Shr, ..))
     }
 
-    /// Getting a description does not require `O` to be printable, and does not
-    /// require allocation.
-    /// The caller is expected to handle `BoundsCheck` and `MisalignedPointerDereference` separately.
+    /// Get the message that is printed at runtime when this assertion fails.
+    ///
+    /// The caller is expected to handle `BoundsCheck` and `MisalignedPointerDereference` by
+    /// invoking the appropriate lang item (panic_bounds_check/panic_misaligned_pointer_dereference)
+    /// instead of printing a static message.
     pub fn description(&self) -> &'static str {
         use AssertKind::*;
         match self {
@@ -1303,6 +1305,11 @@ impl<O> AssertKind<O> {
     }
 
     /// Format the message arguments for the `assert(cond, msg..)` terminator in MIR printing.
+    ///
+    /// Needs to be kept in sync with the run-time behavior (which is defined by
+    /// `AssertKind::description` and the lang items mentioned in its docs).
+    /// Note that we deliberately show more details here than we do at runtime, such as the actual
+    /// numbers that overflowed -- it is much easier to do so here than at runtime.
     pub fn fmt_assert_args<W: Write>(&self, f: &mut W) -> fmt::Result
     where
         O: Debug,
@@ -1358,6 +1365,12 @@ impl<O> AssertKind<O> {
         }
     }
 
+    /// Format the diagnostic message for use in a lint (e.g. when the assertion fails during const-eval).
+    ///
+    /// Needs to be kept in sync with the run-time behavior (which is defined by
+    /// `AssertKind::description` and the lang items mentioned in its docs).
+    /// Note that we deliberately show more details here than we do at runtime, such as the actual
+    /// numbers that overflowed -- it is much easier to do so here than at runtime.
     pub fn diagnostic_message(&self) -> DiagnosticMessage {
         use crate::fluent_generated::*;
         use AssertKind::*;
diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs
index cd74a403ff6..da486c3465a 100644
--- a/compiler/rustc_middle/src/mir/patch.rs
+++ b/compiler/rustc_middle/src/mir/patch.rs
@@ -14,7 +14,8 @@ pub struct MirPatch<'tcx> {
     resume_block: Option<BasicBlock>,
     // Only for unreachable in cleanup path.
     unreachable_cleanup_block: Option<BasicBlock>,
-    terminate_block: Option<BasicBlock>,
+    // Cached block for UnwindTerminate (with reason)
+    terminate_block: Option<(BasicBlock, UnwindTerminateReason)>,
     body_span: Span,
     next_local: usize,
 }
@@ -35,13 +36,15 @@ impl<'tcx> MirPatch<'tcx> {
 
         for (bb, block) in body.basic_blocks.iter_enumerated() {
             // Check if we already have a resume block
-            if let TerminatorKind::UnwindResume = block.terminator().kind && block.statements.is_empty() {
+            if matches!(block.terminator().kind, TerminatorKind::UnwindResume)
+                && block.statements.is_empty()
+            {
                 result.resume_block = Some(bb);
                 continue;
             }
 
             // Check if we already have an unreachable block
-            if let TerminatorKind::Unreachable = block.terminator().kind
+            if matches!(block.terminator().kind, TerminatorKind::Unreachable)
                 && block.statements.is_empty()
                 && block.is_cleanup
             {
@@ -50,8 +53,10 @@ impl<'tcx> MirPatch<'tcx> {
             }
 
             // Check if we already have a terminate block
-            if let TerminatorKind::UnwindTerminate = block.terminator().kind && block.statements.is_empty() {
-                result.terminate_block = Some(bb);
+            if let TerminatorKind::UnwindTerminate(reason) = block.terminator().kind
+                && block.statements.is_empty()
+            {
+                result.terminate_block = Some((bb, reason));
                 continue;
             }
         }
@@ -93,20 +98,20 @@ impl<'tcx> MirPatch<'tcx> {
         bb
     }
 
-    pub fn terminate_block(&mut self) -> BasicBlock {
-        if let Some(bb) = self.terminate_block {
-            return bb;
+    pub fn terminate_block(&mut self, reason: UnwindTerminateReason) -> BasicBlock {
+        if let Some((cached_bb, cached_reason)) = self.terminate_block && reason == cached_reason {
+            return cached_bb;
         }
 
         let bb = self.new_block(BasicBlockData {
             statements: vec![],
             terminator: Some(Terminator {
                 source_info: SourceInfo::outermost(self.body_span),
-                kind: TerminatorKind::UnwindTerminate,
+                kind: TerminatorKind::UnwindTerminate(reason),
             }),
             is_cleanup: true,
         });
-        self.terminate_block = Some(bb);
+        self.terminate_block = Some((bb, reason));
         bb
     }
 
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index e91e822f915..79b64a491f4 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -621,7 +621,7 @@ pub enum TerminatorKind<'tcx> {
     ///
     /// Used to prevent unwinding for foreign items or with `-C unwind=abort`. Only permitted in
     /// cleanup blocks.
-    UnwindTerminate,
+    UnwindTerminate(UnwindTerminateReason),
 
     /// Returns from the function.
     ///
@@ -813,7 +813,7 @@ impl TerminatorKind<'_> {
             TerminatorKind::Goto { .. } => "Goto",
             TerminatorKind::SwitchInt { .. } => "SwitchInt",
             TerminatorKind::UnwindResume => "UnwindResume",
-            TerminatorKind::UnwindTerminate => "UnwindTerminate",
+            TerminatorKind::UnwindTerminate(_) => "UnwindTerminate",
             TerminatorKind::Return => "Return",
             TerminatorKind::Unreachable => "Unreachable",
             TerminatorKind::Drop { .. } => "Drop",
@@ -842,11 +842,22 @@ pub enum UnwindAction {
     /// Terminates the execution if unwind happens.
     ///
     /// Depending on the platform and situation this may cause a non-unwindable panic or abort.
-    Terminate,
+    Terminate(UnwindTerminateReason),
     /// Cleanups to be done.
     Cleanup(BasicBlock),
 }
 
+/// The reason we are terminating the process during unwinding.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
+#[derive(TypeFoldable, TypeVisitable)]
+pub enum UnwindTerminateReason {
+    /// Unwinding is just not possible given the ABI of this function.
+    Abi,
+    /// We were already cleaning up for an ongoing unwind, and a *second*, *nested* unwind was
+    /// triggered by the drop glue.
+    InCleanup,
+}
+
 /// Information about an assertion failure.
 #[derive(Clone, Hash, HashStable, PartialEq, Debug)]
 #[derive(TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index bd87563e2bb..7eddf13b3fb 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -1,3 +1,4 @@
+use rustc_hir::LangItem;
 use smallvec::SmallVec;
 
 use super::{BasicBlock, InlineAsmOperand, Operand, SourceInfo, TerminatorKind, UnwindAction};
@@ -100,6 +101,40 @@ impl<'a> Iterator for SwitchTargetsIter<'a> {
 
 impl<'a> ExactSizeIterator for SwitchTargetsIter<'a> {}
 
+impl UnwindAction {
+    fn cleanup_block(self) -> Option<BasicBlock> {
+        match self {
+            UnwindAction::Cleanup(bb) => Some(bb),
+            UnwindAction::Continue | UnwindAction::Unreachable | UnwindAction::Terminate(_) => None,
+        }
+    }
+}
+
+impl UnwindTerminateReason {
+    pub fn as_str(self) -> &'static str {
+        // Keep this in sync with the messages in `core/src/panicking.rs`.
+        match self {
+            UnwindTerminateReason::Abi => "panic in a function that cannot unwind",
+            UnwindTerminateReason::InCleanup => "panic in a destructor during cleanup",
+        }
+    }
+
+    /// A short representation of this used for MIR printing.
+    pub fn as_short_str(self) -> &'static str {
+        match self {
+            UnwindTerminateReason::Abi => "abi",
+            UnwindTerminateReason::InCleanup => "cleanup",
+        }
+    }
+
+    pub fn lang_item(self) -> LangItem {
+        match self {
+            UnwindTerminateReason::Abi => LangItem::PanicCannotUnwind,
+            UnwindTerminateReason::InCleanup => LangItem::PanicInCleanup,
+        }
+    }
+}
+
 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
 pub struct Terminator<'tcx> {
     pub source_info: SourceInfo,
@@ -156,7 +191,7 @@ impl<'tcx> TerminatorKind<'tcx> {
                 Some(t).into_iter().chain((&[]).into_iter().copied())
             }
             UnwindResume
-            | UnwindTerminate
+            | UnwindTerminate(_)
             | GeneratorDrop
             | Return
             | Unreachable
@@ -198,7 +233,7 @@ impl<'tcx> TerminatorKind<'tcx> {
                 Some(t).into_iter().chain(&mut [])
             }
             UnwindResume
-            | UnwindTerminate
+            | UnwindTerminate(_)
             | GeneratorDrop
             | Return
             | Unreachable
@@ -215,7 +250,7 @@ impl<'tcx> TerminatorKind<'tcx> {
         match *self {
             TerminatorKind::Goto { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::GeneratorDrop
@@ -234,7 +269,7 @@ impl<'tcx> TerminatorKind<'tcx> {
         match *self {
             TerminatorKind::Goto { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::GeneratorDrop
@@ -271,18 +306,28 @@ impl<'tcx> Debug for TerminatorKind<'tcx> {
         let labels = self.fmt_successor_labels();
         assert_eq!(successor_count, labels.len());
 
-        let unwind = match self.unwind() {
-            // Not needed or included in successors
-            None | Some(UnwindAction::Cleanup(_)) => None,
-            Some(UnwindAction::Continue) => Some("unwind continue"),
-            Some(UnwindAction::Unreachable) => Some("unwind unreachable"),
-            Some(UnwindAction::Terminate) => Some("unwind terminate"),
+        // `Cleanup` is already included in successors
+        let show_unwind = !matches!(self.unwind(), None | Some(UnwindAction::Cleanup(_)));
+        let fmt_unwind = |fmt: &mut Formatter<'_>| -> fmt::Result {
+            write!(fmt, "unwind ")?;
+            match self.unwind() {
+                // Not needed or included in successors
+                None | Some(UnwindAction::Cleanup(_)) => unreachable!(),
+                Some(UnwindAction::Continue) => write!(fmt, "continue"),
+                Some(UnwindAction::Unreachable) => write!(fmt, "unreachable"),
+                Some(UnwindAction::Terminate(reason)) => {
+                    write!(fmt, "terminate({})", reason.as_short_str())
+                }
+            }
         };
 
-        match (successor_count, unwind) {
-            (0, None) => Ok(()),
-            (0, Some(unwind)) => write!(fmt, " -> {unwind}"),
-            (1, None) => write!(fmt, " -> {:?}", self.successors().next().unwrap()),
+        match (successor_count, show_unwind) {
+            (0, false) => Ok(()),
+            (0, true) => {
+                write!(fmt, " -> ")?;
+                fmt_unwind(fmt)
+            }
+            (1, false) => write!(fmt, " -> {:?}", self.successors().next().unwrap()),
             _ => {
                 write!(fmt, " -> [")?;
                 for (i, target) in self.successors().enumerate() {
@@ -291,8 +336,9 @@ impl<'tcx> Debug for TerminatorKind<'tcx> {
                     }
                     write!(fmt, "{}: {:?}", labels[i], target)?;
                 }
-                if let Some(unwind) = unwind {
-                    write!(fmt, ", {unwind}")?;
+                if show_unwind {
+                    write!(fmt, ", ")?;
+                    fmt_unwind(fmt)?;
                 }
                 write!(fmt, "]")
             }
@@ -312,7 +358,9 @@ impl<'tcx> TerminatorKind<'tcx> {
             Return => write!(fmt, "return"),
             GeneratorDrop => write!(fmt, "generator_drop"),
             UnwindResume => write!(fmt, "resume"),
-            UnwindTerminate => write!(fmt, "abort"),
+            UnwindTerminate(reason) => {
+                write!(fmt, "abort({})", reason.as_short_str())
+            }
             Yield { value, resume_arg, .. } => write!(fmt, "{resume_arg:?} = yield({value:?})"),
             Unreachable => write!(fmt, "unreachable"),
             Drop { place, .. } => write!(fmt, "drop({place:?})"),
@@ -391,7 +439,7 @@ impl<'tcx> TerminatorKind<'tcx> {
     pub fn fmt_successor_labels(&self) -> Vec<Cow<'static, str>> {
         use self::TerminatorKind::*;
         match *self {
-            Return | UnwindResume | UnwindTerminate | Unreachable | GeneratorDrop => vec![],
+            Return | UnwindResume | UnwindTerminate(_) | Unreachable | GeneratorDrop => vec![],
             Goto { .. } => vec!["".into()],
             SwitchInt { ref targets, .. } => targets
                 .values
@@ -443,7 +491,8 @@ pub enum TerminatorEdges<'mir, 'tcx> {
     /// Special action for `Yield`, `Call` and `InlineAsm` terminators.
     AssignOnReturn {
         return_: Option<BasicBlock>,
-        unwind: UnwindAction,
+        /// The cleanup block, if it exists.
+        cleanup: Option<BasicBlock>,
         place: CallReturnPlaces<'mir, 'tcx>,
     },
     /// Special edge for `SwitchInt`.
@@ -486,7 +535,7 @@ impl<'tcx> TerminatorKind<'tcx> {
     pub fn edges(&self) -> TerminatorEdges<'_, 'tcx> {
         use TerminatorKind::*;
         match *self {
-            Return | UnwindResume | UnwindTerminate | GeneratorDrop | Unreachable => {
+            Return | UnwindResume | UnwindTerminate(_) | GeneratorDrop | Unreachable => {
                 TerminatorEdges::None
             }
 
@@ -496,7 +545,7 @@ impl<'tcx> TerminatorKind<'tcx> {
             | Drop { target, unwind, place: _, replace: _ }
             | FalseUnwind { real_target: target, unwind } => match unwind {
                 UnwindAction::Cleanup(unwind) => TerminatorEdges::Double(target, unwind),
-                UnwindAction::Continue | UnwindAction::Terminate | UnwindAction::Unreachable => {
+                UnwindAction::Continue | UnwindAction::Terminate(_) | UnwindAction::Unreachable => {
                     TerminatorEdges::Single(target)
                 }
             },
@@ -508,7 +557,7 @@ impl<'tcx> TerminatorKind<'tcx> {
             Yield { resume: target, drop, resume_arg, value: _ } => {
                 TerminatorEdges::AssignOnReturn {
                     return_: Some(target),
-                    unwind: drop.map_or(UnwindAction::Terminate, UnwindAction::Cleanup),
+                    cleanup: drop,
                     place: CallReturnPlaces::Yield(resume_arg),
                 }
             }
@@ -516,7 +565,7 @@ impl<'tcx> TerminatorKind<'tcx> {
             Call { unwind, destination, target, func: _, args: _, fn_span: _, call_source: _ } => {
                 TerminatorEdges::AssignOnReturn {
                     return_: target,
-                    unwind,
+                    cleanup: unwind.cleanup_block(),
                     place: CallReturnPlaces::Call(destination),
                 }
             }
@@ -530,7 +579,7 @@ impl<'tcx> TerminatorKind<'tcx> {
                 unwind,
             } => TerminatorEdges::AssignOnReturn {
                 return_: destination,
-                unwind,
+                cleanup: unwind.cleanup_block(),
                 place: CallReturnPlaces::InlineAsm(operands),
             },
 
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index b3d3366ae10..87b04aabe6a 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -470,7 +470,7 @@ macro_rules! make_mir_visitor {
                 match kind {
                     TerminatorKind::Goto { .. } |
                     TerminatorKind::UnwindResume |
-                    TerminatorKind::UnwindTerminate |
+                    TerminatorKind::UnwindTerminate(_) |
                     TerminatorKind::GeneratorDrop |
                     TerminatorKind::Unreachable |
                     TerminatorKind::FalseEdge { .. } |
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 1274f427e4f..8fedf4dca95 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2150,6 +2150,7 @@ impl<'tcx> TyCtxt<'tcx> {
         for attr in self.get_attrs(did, sym::repr) {
             for r in attr::parse_repr_attr(&self.sess, attr) {
                 flags.insert(match r {
+                    attr::ReprRust => ReprFlags::empty(),
                     attr::ReprC => ReprFlags::IS_C,
                     attr::ReprPacked(pack) => {
                         let pack = Align::from_bytes(pack as u64).unwrap();
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 2a23a69b584..e614046e83e 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -56,7 +56,8 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
 /// Construct the MIR for a given `DefId`.
 fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
     // Ensure unsafeck and abstract const building is ran before we steal the THIR.
-    tcx.ensure_with_value().thir_check_unsafety(def);
+    tcx.ensure_with_value()
+        .thir_check_unsafety(tcx.typeck_root_def_id(def.to_def_id()).expect_local());
     tcx.ensure_with_value().thir_abstract_const(def);
     if let Err(e) = tcx.check_match(def) {
         return construct_error(tcx, def, e);
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 567e7bfb5bf..4cf6a349af7 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -370,7 +370,7 @@ impl DropTree {
                     let terminator = TerminatorKind::Drop {
                         target: blocks[drop_data.1].unwrap(),
                         // The caller will handle this if needed.
-                        unwind: UnwindAction::Terminate,
+                        unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup),
                         place: drop_data.0.local.into(),
                         replace: false,
                     };
@@ -1507,7 +1507,7 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind {
             TerminatorKind::Goto { .. }
             | TerminatorKind::SwitchInt { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::Yield { .. }
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index 84c80bf41a4..94be38beee4 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -186,7 +186,7 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx
 
         match self.body[bb].terminator().kind {
             // These terminators return control flow to the caller.
-            TerminatorKind::UnwindTerminate
+            TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::GeneratorDrop
             | TerminatorKind::UnwindResume
             | TerminatorKind::Return
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 383e80851f0..f46cf0dc0ff 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -7,6 +7,7 @@ use crate::errors::*;
 
 use rustc_arena::TypedArena;
 use rustc_ast::Mutability;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
     struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
@@ -660,6 +661,17 @@ fn report_arm_reachability<'p, 'tcx>(
     }
 }
 
+fn collect_non_exhaustive_tys<'p, 'tcx>(
+    pat: &DeconstructedPat<'p, 'tcx>,
+    non_exhaustive_tys: &mut FxHashSet<Ty<'tcx>>,
+) {
+    if matches!(pat.ctor(), Constructor::NonExhaustive) {
+        non_exhaustive_tys.insert(pat.ty());
+    }
+    pat.iter_fields()
+        .for_each(|field_pat| collect_non_exhaustive_tys(field_pat, non_exhaustive_tys))
+}
+
 /// Report that a match is not exhaustive.
 fn non_exhaustive_match<'p, 'tcx>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
@@ -717,22 +729,27 @@ fn non_exhaustive_match<'p, 'tcx>(
         scrut_ty,
         if is_variant_list_non_exhaustive { ", which is marked as non-exhaustive" } else { "" }
     ));
-    if (scrut_ty == cx.tcx.types.usize || scrut_ty == cx.tcx.types.isize)
-        && !is_empty_match
-        && witnesses.len() == 1
-        && matches!(witnesses[0].ctor(), Constructor::NonExhaustive)
-    {
-        err.note(format!(
-            "`{scrut_ty}` does not have a fixed maximum value, so a wildcard `_` is necessary to match \
-             exhaustively",
-        ));
-        if cx.tcx.sess.is_nightly_build() {
-            err.help(format!(
-                "add `#![feature(precise_pointer_size_matching)]` to the crate attributes to \
-                 enable precise `{scrut_ty}` matching",
-            ));
+
+    if !is_empty_match && witnesses.len() == 1 {
+        let mut non_exhaustive_tys = FxHashSet::default();
+        collect_non_exhaustive_tys(&witnesses[0], &mut non_exhaustive_tys);
+
+        for ty in non_exhaustive_tys {
+            if ty == cx.tcx.types.usize || ty == cx.tcx.types.isize {
+                err.note(format!(
+                    "`{ty}` does not have a fixed maximum value, so a wildcard `_` is necessary to match \
+                     exhaustively",
+                ));
+                if cx.tcx.sess.is_nightly_build() {
+                    err.help(format!(
+                        "add `#![feature(precise_pointer_size_matching)]` to the crate attributes to \
+                         enable precise `{ty}` matching",
+                    ));
+                }
+            }
         }
     }
+
     if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() {
         if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.param_env) {
             err.note("references are always considered inhabited");
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 9e02b027182..ad5f83d9e25 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -80,7 +80,7 @@ impl Unwind {
     fn into_action(self) -> UnwindAction {
         match self {
             Unwind::To(bb) => UnwindAction::Cleanup(bb),
-            Unwind::InCleanup => UnwindAction::Terminate,
+            Unwind::InCleanup => UnwindAction::Terminate(UnwindTerminateReason::InCleanup),
         }
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 8a9e37c5a4f..70451edd500 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -1,5 +1,5 @@
 use rustc_middle::mir::{
-    self, BasicBlock, CallReturnPlaces, Location, SwitchTargets, TerminatorEdges, UnwindAction,
+    self, BasicBlock, CallReturnPlaces, Location, SwitchTargets, TerminatorEdges,
 };
 use std::ops::RangeInclusive;
 
@@ -486,10 +486,10 @@ impl Direction for Forward {
                 propagate(target, exit_state);
                 propagate(unwind, exit_state);
             }
-            TerminatorEdges::AssignOnReturn { return_, unwind, place } => {
+            TerminatorEdges::AssignOnReturn { return_, cleanup, place } => {
                 // This must be done *first*, otherwise the unwind path will see the assignments.
-                if let UnwindAction::Cleanup(unwind) = unwind {
-                    propagate(unwind, exit_state);
+                if let Some(cleanup) = cleanup {
+                    propagate(cleanup, exit_state);
                 }
                 if let Some(return_) = return_ {
                     analysis.apply_call_return_effect(exit_state, bb, place);
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 5ed8f20b73f..3ad9d3d4264 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -131,7 +131,7 @@ where
                 }
             }
 
-            TerminatorKind::UnwindTerminate
+            TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Assert { .. }
             | TerminatorKind::Call { .. }
             | TerminatorKind::FalseEdge { .. }
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 531390c2f07..94d6eb67d49 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -291,7 +291,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
 
             // Nothing to do for these. Match exhaustively so this fails to compile when new
             // variants are added.
-            TerminatorKind::UnwindTerminate
+            TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Assert { .. }
             | TerminatorKind::Drop { .. }
             | TerminatorKind::FalseEdge { .. }
@@ -328,7 +328,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
             // Nothing to do for these. Match exhaustively so this fails to compile when new
             // variants are added.
             TerminatorKind::Yield { .. }
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Assert { .. }
             | TerminatorKind::Drop { .. }
             | TerminatorKind::FalseEdge { .. }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 4adf3dec61b..2e3b9577b50 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -371,7 +371,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             // need recording.
             | TerminatorKind::Return
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::GeneratorDrop
             | TerminatorKind::Unreachable
             | TerminatorKind::Drop { .. } => {}
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 1eea8eef0ad..6872ef5e985 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -270,7 +270,7 @@ pub trait ValueAnalysis<'tcx> {
             }
             TerminatorKind::Goto { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::Assert { .. }
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index 5aed89139e2..4500bb7ff0f 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -104,7 +104,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
 
         for id in calls_to_terminate {
             let cleanup = body.basic_blocks_mut()[id].terminator_mut().unwind_mut().unwrap();
-            *cleanup = UnwindAction::Terminate;
+            *cleanup = UnwindAction::Terminate(UnwindTerminateReason::Abi);
         }
 
         for id in cleanups_to_remove {
diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs
index fb4705e0754..b814fbf32b1 100644
--- a/compiler/rustc_mir_transform/src/add_call_guards.rs
+++ b/compiler/rustc_mir_transform/src/add_call_guards.rs
@@ -53,8 +53,10 @@ impl AddCallGuards {
                     kind: TerminatorKind::Call { target: Some(ref mut destination), unwind, .. },
                     source_info,
                 }) if pred_count[*destination] > 1
-                    && (matches!(unwind, UnwindAction::Cleanup(_) | UnwindAction::Terminate)
-                        || self == &AllCallEdges) =>
+                    && (matches!(
+                        unwind,
+                        UnwindAction::Cleanup(_) | UnwindAction::Terminate(_)
+                    ) || self == &AllCallEdges) =>
                 {
                     // It's a critical edge, break it
                     let call_guard = BasicBlockData {
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index e72db1a59a0..0fce9cb19a8 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -58,7 +58,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
             | TerminatorKind::Assert { .. }
             | TerminatorKind::GeneratorDrop
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::FalseEdge { .. }
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 4f8ca916d5b..da8913d604b 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -679,7 +679,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
             // None of these have Operands to const-propagate.
             TerminatorKind::Goto { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::Drop { .. }
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index d3d4fcd3a52..60461691e7f 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -116,7 +116,7 @@ impl CoverageGraph {
 
             match term.kind {
                 TerminatorKind::Return { .. }
-                | TerminatorKind::UnwindTerminate
+                | TerminatorKind::UnwindTerminate(_)
                 | TerminatorKind::Yield { .. }
                 | TerminatorKind::SwitchInt { .. } => {
                     // The `bb` has more than one _outgoing_ edge, or exits the function. Save the
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 6fabaca524a..717763a94a0 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -868,7 +868,7 @@ pub(super) fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Sp
 
         // Retain spans from all other terminators
         TerminatorKind::UnwindResume
-        | TerminatorKind::UnwindTerminate
+        | TerminatorKind::UnwindTerminate(_)
         | TerminatorKind::Return
         | TerminatorKind::Yield { .. }
         | TerminatorKind::GeneratorDrop
diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
index 3f988930b5e..ef14105041b 100644
--- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs
+++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
@@ -12,6 +12,7 @@
 //!     will still not cause any further changes.
 //!
 
+use crate::util::is_within_packed;
 use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
@@ -49,6 +50,11 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
                     && !place.is_indirect()
                     && !borrowed.contains(place.local)
                     && !state.contains(place.local)
+                    // If `place` is a projection of a disaligned field in a packed ADT,
+                    // the move may be codegened as a pointer to that field.
+                    // Using that disaligned pointer may trigger UB in the callee,
+                    // so do nothing.
+                    && is_within_packed(tcx, body, place).is_none()
                 {
                     call_operands_to_move.push((bb, index));
                 }
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 041f7c7221e..d9a132e5cf1 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -648,7 +648,7 @@ impl WriteInfo {
             }
             TerminatorKind::Goto { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable { .. } => (),
             TerminatorKind::Drop { .. } => {
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index a80ae480089..78d7ffb3698 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -362,8 +362,13 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                                     UnwindAction::Unreachable => {
                                         Unwind::To(self.patch.unreachable_cleanup_block())
                                     }
-                                    UnwindAction::Terminate => {
-                                        Unwind::To(self.patch.terminate_block())
+                                    UnwindAction::Terminate(reason) => {
+                                        debug_assert_ne!(
+                                            reason,
+                                            UnwindTerminateReason::InCleanup,
+                                            "we are not in a cleanup block, InCleanup reason should be impossible"
+                                        );
+                                        Unwind::To(self.patch.terminate_block(reason))
                                     }
                                 }
                             };
@@ -496,7 +501,8 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
             if let TerminatorKind::Call {
                 destination,
                 target: Some(_),
-                unwind: UnwindAction::Continue | UnwindAction::Unreachable | UnwindAction::Terminate,
+                unwind:
+                    UnwindAction::Continue | UnwindAction::Unreachable | UnwindAction::Terminate(_),
                 ..
             } = data.terminator().kind
             {
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 96077322575..1e7161189c3 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1091,7 +1091,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                 UnwindAction::Cleanup(tgt) => tgt,
                 UnwindAction::Continue => elaborator.patch.resume_block(),
                 UnwindAction::Unreachable => elaborator.patch.unreachable_cleanup_block(),
-                UnwindAction::Terminate => elaborator.patch.terminate_block(),
+                UnwindAction::Terminate(reason) => elaborator.patch.terminate_block(reason),
             })
         };
         elaborate_drop(
@@ -1239,7 +1239,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
             // These never unwind.
             TerminatorKind::Goto { .. }
             | TerminatorKind::SwitchInt { .. }
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::GeneratorDrop
@@ -1759,7 +1759,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
             | TerminatorKind::Goto { .. }
             | TerminatorKind::SwitchInt { .. }
             | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::Drop { .. }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 734e93783d1..9551c7a2a8d 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -906,12 +906,12 @@ impl Integrator<'_, '_> {
                 UnwindAction::Cleanup(_) | UnwindAction::Continue => {
                     bug!("cleanup on cleanup block");
                 }
-                UnwindAction::Unreachable | UnwindAction::Terminate => return unwind,
+                UnwindAction::Unreachable | UnwindAction::Terminate(_) => return unwind,
             }
         }
 
         match unwind {
-            UnwindAction::Unreachable | UnwindAction::Terminate => unwind,
+            UnwindAction::Unreachable | UnwindAction::Terminate(_) => unwind,
             UnwindAction::Cleanup(target) => UnwindAction::Cleanup(self.map_block(target)),
             // Add an unwind edge to the original call's cleanup block
             UnwindAction::Continue => self.cleanup_block,
@@ -1022,10 +1022,10 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
                     UnwindAction::Cleanup(tgt) => TerminatorKind::Goto { target: tgt },
                     UnwindAction::Continue => TerminatorKind::UnwindResume,
                     UnwindAction::Unreachable => TerminatorKind::Unreachable,
-                    UnwindAction::Terminate => TerminatorKind::UnwindTerminate,
+                    UnwindAction::Terminate(reason) => TerminatorKind::UnwindTerminate(reason),
                 };
             }
-            TerminatorKind::UnwindTerminate => {}
+            TerminatorKind::UnwindTerminate(_) => {}
             TerminatorKind::Unreachable => {}
             TerminatorKind::FalseEdge { ref mut real_target, ref mut imaginary_target } => {
                 *real_target = self.map_block(*real_target);
diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
index 5782adbb3ff..8c48a667786 100644
--- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
@@ -72,7 +72,7 @@ impl RemoveNoopLandingPads {
             TerminatorKind::GeneratorDrop
             | TerminatorKind::Yield { .. }
             | TerminatorKind::Return
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Unreachable
             | TerminatorKind::Call { .. }
             | TerminatorKind::Assert { .. }
diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs
index de1b80585d1..e1e4acccccd 100644
--- a/compiler/rustc_mir_transform/src/separate_const_switch.rs
+++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs
@@ -114,7 +114,7 @@ pub fn separate_const_switch(body: &mut Body<'_>) -> usize {
                         | TerminatorKind::Assert { .. }
                         | TerminatorKind::FalseUnwind { .. }
                         | TerminatorKind::Yield { .. }
-                        | TerminatorKind::UnwindTerminate
+                        | TerminatorKind::UnwindTerminate(_)
                         | TerminatorKind::Return
                         | TerminatorKind::Unreachable
                         | TerminatorKind::InlineAsm { .. }
@@ -166,7 +166,7 @@ pub fn separate_const_switch(body: &mut Body<'_>) -> usize {
             }
 
             TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate
+            | TerminatorKind::UnwindTerminate(_)
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
             | TerminatorKind::GeneratorDrop
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 046eed2dd19..e1000d96932 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -99,7 +99,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
     };
     debug!("make_shim({:?}) = untransformed {:?}", instance, result);
 
-    pm::run_passes(
+    // We don't validate MIR here because the shims may generate code that's
+    // only valid in a reveal-all param-env. However, since we do initial
+    // validation with the MirBuilt phase, which uses a user-facing param-env.
+    // This causes validation errors when TAITs are involved.
+    pm::run_passes_no_validate(
         tcx,
         &mut result,
         &[
@@ -566,10 +570,10 @@ impl<'tcx> CloneShimBuilder<'tcx> {
                 TerminatorKind::Drop {
                     place: dest_field,
                     target: unwind,
-                    unwind: UnwindAction::Terminate,
+                    unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup),
                     replace: false,
                 },
-                true,
+                /* is_cleanup */ true,
             );
             unwind = next_unwind;
         }
@@ -847,10 +851,10 @@ fn build_call_shim<'tcx>(
             TerminatorKind::Drop {
                 place: rcvr_place(),
                 target: BasicBlock::new(4),
-                unwind: UnwindAction::Terminate,
+                unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup),
                 replace: false,
             },
-            true,
+            /* is_cleanup */ true,
         );
 
         // BB #4 - resume
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index cd7908e75e2..f917e52109a 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -737,6 +737,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
         let source = self.body.source_info(location).span;
 
         let tcx = self.tcx;
+        let push_mono_lang_item = |this: &mut Self, lang_item: LangItem| {
+            let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source)));
+            if should_codegen_locally(tcx, &instance) {
+                this.output.push(create_fn_mono_item(tcx, instance, source));
+            }
+        };
+
         match terminator.kind {
             mir::TerminatorKind::Call { ref func, .. } => {
                 let callee_ty = func.ty(self.body, tcx);
@@ -771,19 +778,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
                     mir::AssertKind::BoundsCheck { .. } => LangItem::PanicBoundsCheck,
                     _ => LangItem::Panic,
                 };
-                let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source)));
-                if should_codegen_locally(tcx, &instance) {
-                    self.output.push(create_fn_mono_item(tcx, instance, source));
-                }
+                push_mono_lang_item(self, lang_item);
             }
-            mir::TerminatorKind::UnwindTerminate { .. } => {
-                let instance = Instance::mono(
-                    tcx,
-                    tcx.require_lang_item(LangItem::PanicCannotUnwind, Some(source)),
-                );
-                if should_codegen_locally(tcx, &instance) {
-                    self.output.push(create_fn_mono_item(tcx, instance, source));
-                }
+            mir::TerminatorKind::UnwindTerminate(reason) => {
+                push_mono_lang_item(self, reason.lang_item());
             }
             mir::TerminatorKind::Goto { .. }
             | mir::TerminatorKind::SwitchInt { .. }
@@ -796,14 +794,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
             | mir::TerminatorKind::FalseUnwind { .. } => bug!(),
         }
 
-        if let Some(mir::UnwindAction::Terminate) = terminator.unwind() {
-            let instance = Instance::mono(
-                tcx,
-                tcx.require_lang_item(LangItem::PanicCannotUnwind, Some(source)),
-            );
-            if should_codegen_locally(tcx, &instance) {
-                self.output.push(create_fn_mono_item(tcx, instance, source));
-            }
+        if let Some(mir::UnwindAction::Terminate(reason)) = terminator.unwind() {
+            push_mono_lang_item(self, reason.lang_item());
         }
 
         self.super_terminator(terminator, location);
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 892be36aae7..598adbe7985 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -8,7 +8,7 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![recursion_limit = "256"]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 24c65d061f9..5db31c23478 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1594,7 +1594,7 @@ impl<'a> Parser<'a> {
         Ok((class_name, ItemKind::Union(vdata, generics)))
     }
 
-    fn parse_record_struct_body(
+    pub(crate) fn parse_record_struct_body(
         &mut self,
         adt_ty: &str,
         ident_span: Span,
@@ -1869,7 +1869,7 @@ impl<'a> Parser<'a> {
             }
         }
         self.expect_field_ty_separator()?;
-        let ty = self.parse_ty()?;
+        let ty = self.parse_ty_for_field_def()?;
         if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
             self.sess.emit_err(errors::SingleColonStructType { span: self.token.span });
         }
@@ -1894,7 +1894,9 @@ impl<'a> Parser<'a> {
     /// for better diagnostics and suggestions.
     fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
         let (ident, is_raw) = self.ident_or_err(true)?;
-        if !is_raw && ident.is_reserved() {
+        if ident.name == kw::Underscore {
+            self.sess.gated_spans.gate(sym::unnamed_fields, lo);
+        } else if !is_raw && ident.is_reserved() {
             let snapshot = self.create_snapshot_for_diagnostic();
             let err = if self.check_fn_front_matter(false, Case::Sensitive) {
                 let inherited_vis = Visibility {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 2d888efb1f3..661113666cd 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -136,6 +136,17 @@ impl<'a> Parser<'a> {
         )
     }
 
+    /// Parse a type suitable for a field defintion.
+    /// The difference from `parse_ty` is that this version
+    /// allows anonymous structs and unions.
+    pub fn parse_ty_for_field_def(&mut self) -> PResult<'a, P<Ty>> {
+        if self.can_begin_anon_struct_or_union() {
+            self.parse_anon_struct_or_union()
+        } else {
+            self.parse_ty()
+        }
+    }
+
     /// Parse a type suitable for a function or function pointer parameter.
     /// The difference from `parse_ty` is that this version allows `...`
     /// (`CVarArgs`) at the top level of the type.
@@ -336,6 +347,36 @@ impl<'a> Parser<'a> {
         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
     }
 
+    /// Parse an anonymous struct or union (only for field definitions):
+    /// ```ignore (feature-not-ready)
+    /// #[repr(C)]
+    /// struct Foo {
+    ///     _: struct { // anonymous struct
+    ///         x: u32,
+    ///         y: f64,
+    ///     }
+    ///     _: union { // anonymous union
+    ///         z: u32,
+    ///         w: f64,
+    ///     }
+    /// }
+    /// ```
+    fn parse_anon_struct_or_union(&mut self) -> PResult<'a, P<Ty>> {
+        assert!(self.token.is_keyword(kw::Union) || self.token.is_keyword(kw::Struct));
+        let is_union = self.token.is_keyword(kw::Union);
+
+        let lo = self.token.span;
+        self.bump();
+
+        let (fields, _recovered) =
+            self.parse_record_struct_body(if is_union { "union" } else { "struct" }, lo, false)?;
+        let span = lo.to(self.prev_token.span);
+        self.sess.gated_spans.gate(sym::unnamed_fields, span);
+        // These can be rejected during AST validation in `deny_anon_struct_or_union`.
+        let kind = if is_union { TyKind::AnonUnion(fields) } else { TyKind::AnonStruct(fields) };
+        Ok(self.mk_ty(span, kind))
+    }
+
     /// Parses either:
     /// - `(TYPE)`, a parenthesized type.
     /// - `(TYPE,)`, a tuple with a single field of type TYPE.
@@ -696,6 +737,11 @@ impl<'a> Parser<'a> {
         Ok(bounds)
     }
 
+    pub(super) fn can_begin_anon_struct_or_union(&mut self) -> bool {
+        (self.token.is_keyword(kw::Struct) || self.token.is_keyword(kw::Union))
+            && self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace))
+    }
+
     /// Can the current token begin a bound?
     fn can_begin_bound(&mut self) -> bool {
         // This needs to be synchronized with `TokenKind::can_begin_bound`.
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 6eacbebe75f..b2a4da885aa 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -721,7 +721,7 @@ passes_unrecognized_field =
 
 passes_unrecognized_repr_hint =
     unrecognized representation hint
-    .help = valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+    .help = valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 passes_unused =
     unused attribute
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 197b335bdec..50a087c7847 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1732,6 +1732,7 @@ impl CheckAttrVisitor<'_> {
             }
 
             match hint.name_or_empty() {
+                sym::Rust => {}
                 sym::C => {
                     is_c = true;
                     match target {
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 5aa8aef6a85..24087a4eabb 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -587,6 +587,8 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
                 BareFn,
                 Never,
                 Tup,
+                AnonStruct,
+                AnonUnion,
                 Path,
                 TraitObject,
                 ImplTrait,
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index f9d34ea71ba..e62833b358b 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -98,15 +98,11 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
                 self.worklist.push(def_id);
             } else {
                 match res {
-                    // If this path leads to a constant, then we need to
-                    // recurse into the constant to continue finding
-                    // items that are reachable.
-                    Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
+                    // Reachable constants and reachable statics can have their contents inlined
+                    // into other crates. Mark them as reachable and recurse into their body.
+                    Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static(_), _) => {
                         self.worklist.push(def_id);
                     }
-
-                    // If this wasn't a static, then the destination is
-                    // surely reachable.
                     _ => {
                         self.reachable_symbols.insert(def_id);
                     }
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 53005ede843..775870106b1 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -11,7 +11,7 @@
 #![allow(rustc::potential_query_instability, unused_parens)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 30422ea1102..0d4d13ac20d 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -1166,7 +1166,7 @@ impl<K: DepKind> CurrentDepGraph<K> {
             )),
             new_node_to_index: Sharded::new(|| {
                 FxHashMap::with_capacity_and_hasher(
-                    new_node_count_estimate / sharded::SHARDS,
+                    new_node_count_estimate / sharded::shards(),
                     Default::default(),
                 )
             }),
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 127bec22c17..476b5f733a6 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -870,10 +870,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let imported_binding = self.r.import(binding, import);
         if parent == self.r.graph_root {
             if let Some(entry) = self.r.extern_prelude.get(&ident.normalize_to_macros_2_0()) {
-                if expansion != LocalExpnId::ROOT
-                    && orig_name.is_some()
-                    && entry.extern_crate_item.is_none()
-                {
+                if expansion != LocalExpnId::ROOT && orig_name.is_some() && !entry.is_import() {
                     let msg = "macro-expanded `extern crate` items cannot \
                                        shadow names passed with `--extern`";
                     self.r.tcx.sess.span_err(item.span, msg);
@@ -884,10 +881,14 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                     return;
                 }
             }
-            let entry = self.r.extern_prelude.entry(ident.normalize_to_macros_2_0()).or_insert(
-                ExternPreludeEntry { extern_crate_item: None, introduced_by_item: true },
-            );
-            entry.extern_crate_item = Some(imported_binding);
+            let entry = self
+                .r
+                .extern_prelude
+                .entry(ident.normalize_to_macros_2_0())
+                .or_insert(ExternPreludeEntry { binding: None, introduced_by_item: true });
+            // Binding from `extern crate` item in source code can replace
+            // a binding from `--extern` on command line here.
+            entry.binding = Some(imported_binding);
             if orig_name.is_some() {
                 entry.introduced_by_item = true;
             }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index cd1a9b934cf..d99fc07a7cd 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1032,7 +1032,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 .get(&expn_id)
                                 .into_iter()
                                 .flatten()
-                                .map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
+                                .map(|(ident, _)| TypoSuggestion::typo_from_ident(*ident, res)),
                         );
                     }
                 }
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 3bd9cea27ce..61e05b65f90 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1,7 +1,5 @@
 use rustc_ast::{self as ast, NodeId};
-use rustc_feature::is_builtin_attr_name;
 use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS};
-use rustc_hir::PrimTy;
 use rustc_middle::bug;
 use rustc_middle::ty;
 use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
@@ -9,7 +7,7 @@ use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
 use rustc_span::symbol::{kw, Ident};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 
 use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
 use crate::late::{
@@ -423,32 +421,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             orig_ident.span.ctxt(),
             |this, scope, use_prelude, ctxt| {
                 let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
-                let ok = |res, span, arenas| {
-                    Ok((
-                        (res, Visibility::Public, span, LocalExpnId::ROOT).to_name_binding(arenas),
-                        Flags::empty(),
-                    ))
-                };
                 let result = match scope {
                     Scope::DeriveHelpers(expn_id) => {
-                        if let Some(attr) = this
-                            .helper_attrs
-                            .get(&expn_id)
-                            .and_then(|attrs| attrs.iter().rfind(|i| ident == **i))
-                        {
-                            let binding = (
-                                Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
-                                Visibility::Public,
-                                attr.span,
-                                expn_id,
-                            )
-                                .to_name_binding(this.arenas);
+                        if let Some(binding) = this.helper_attrs.get(&expn_id).and_then(|attrs| {
+                            attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, binding)| *binding)
+                        }) {
                             Ok((binding, Flags::empty()))
                         } else {
                             Err(Determinacy::Determined)
                         }
                     }
                     Scope::DeriveHelpersCompat => {
+                        // FIXME: Try running this logic eariler, to allocate name bindings for
+                        // legacy derive helpers when creating an attribute invocation with
+                        // following derives. Legacy derive helpers are not common, so it shouldn't
+                        // affect performance. It should also allow to remove the `derives`
+                        // component from `ParentScope`.
                         let mut result = Err(Determinacy::Determined);
                         for derive in parent_scope.derives {
                             let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
@@ -461,11 +449,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             ) {
                                 Ok((Some(ext), _)) => {
                                     if ext.helper_attrs.contains(&ident.name) {
-                                        result = ok(
+                                        let binding = (
                                             Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
+                                            Visibility::Public,
                                             derive.span,
-                                            this.arenas,
-                                        );
+                                            LocalExpnId::ROOT,
+                                        )
+                                            .to_name_binding(this.arenas);
+                                        result = Ok((binding, Flags::empty()));
                                         break;
                                     }
                                 }
@@ -562,17 +553,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             )),
                         }
                     }
-                    Scope::BuiltinAttrs => {
-                        if is_builtin_attr_name(ident.name) {
-                            ok(
-                                Res::NonMacroAttr(NonMacroAttrKind::Builtin(ident.name)),
-                                DUMMY_SP,
-                                this.arenas,
-                            )
-                        } else {
-                            Err(Determinacy::Determined)
-                        }
-                    }
+                    Scope::BuiltinAttrs => match this.builtin_attrs_bindings.get(&ident.name) {
+                        Some(binding) => Ok((*binding, Flags::empty())),
+                        None => Err(Determinacy::Determined),
+                    },
                     Scope::ExternPrelude => {
                         match this.extern_prelude_get(ident, finalize.is_some()) {
                             Some(binding) => Ok((binding, Flags::empty())),
@@ -581,8 +565,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             )),
                         }
                     }
-                    Scope::ToolPrelude => match this.registered_tools.get(&ident).cloned() {
-                        Some(ident) => ok(Res::ToolMod, ident.span, this.arenas),
+                    Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) {
+                        Some(binding) => Ok((*binding, Flags::empty())),
                         None => Err(Determinacy::Determined),
                     },
                     Scope::StdLibPrelude => {
@@ -603,8 +587,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         }
                         result
                     }
-                    Scope::BuiltinTypes => match PrimTy::from_name(ident.name) {
-                        Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas),
+                    Scope::BuiltinTypes => match this.builtin_types_bindings.get(&ident.name) {
+                        Some(binding) => Ok((*binding, Flags::empty())),
                         None => Err(Determinacy::Determined),
                     },
                 };
@@ -842,9 +826,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 if ns == TypeNS {
                     if ident.name == kw::Crate || ident.name == kw::DollarCrate {
                         let module = self.resolve_crate_root(ident);
-                        let binding = (module, Visibility::Public, module.span, LocalExpnId::ROOT)
-                            .to_name_binding(self.arenas);
-                        return Ok(binding);
+                        return Ok(self.module_self_bindings[&module]);
                     } else if ident.name == kw::Super || ident.name == kw::SelfLower {
                         // FIXME: Implement these with renaming requirements so that e.g.
                         // `use super;` doesn't work, but `use super as name;` does.
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index c87db96a5dd..22d084c8e0b 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -311,6 +311,10 @@ enum LifetimeRibKind {
     /// error on default object bounds (e.g., `Box<dyn Foo>`).
     AnonymousReportError,
 
+    /// Resolves elided lifetimes to `'static`, but gives a warning that this behavior
+    /// is a bug and will be reverted soon.
+    AnonymousWarnToStatic(NodeId),
+
     /// Signal we cannot find which should be the anonymous lifetime.
     ElisionFailure,
 
@@ -1148,6 +1152,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                             }
                             LifetimeRibKind::AnonymousCreateParameter { .. }
                             | LifetimeRibKind::AnonymousReportError
+                            | LifetimeRibKind::AnonymousWarnToStatic(_)
                             | LifetimeRibKind::Elided(_)
                             | LifetimeRibKind::ElisionFailure
                             | LifetimeRibKind::ConcreteAnonConst(_)
@@ -1515,6 +1520,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                                     // lifetime would be illegal.
                                     LifetimeRibKind::Item
                                     | LifetimeRibKind::AnonymousReportError
+                                    | LifetimeRibKind::AnonymousWarnToStatic(_)
                                     | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
                                     // An anonymous lifetime is legal here, and bound to the right
                                     // place, go ahead.
@@ -1576,7 +1582,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 | LifetimeRibKind::Elided(_)
                 | LifetimeRibKind::Generics { .. }
                 | LifetimeRibKind::ElisionFailure
-                | LifetimeRibKind::AnonymousReportError => {}
+                | LifetimeRibKind::AnonymousReportError
+                | LifetimeRibKind::AnonymousWarnToStatic(_) => {}
             }
         }
 
@@ -1616,6 +1623,25 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     self.record_lifetime_res(lifetime.id, res, elision_candidate);
                     return;
                 }
+                LifetimeRibKind::AnonymousWarnToStatic(node_id) => {
+                    self.record_lifetime_res(lifetime.id, LifetimeRes::Static, elision_candidate);
+                    let msg = if elided {
+                        "`&` without an explicit lifetime name cannot be used here"
+                    } else {
+                        "`'_` cannot be used here"
+                    };
+                    self.r.lint_buffer.buffer_lint_with_diagnostic(
+                        lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
+                        node_id,
+                        lifetime.ident.span,
+                        msg,
+                        lint::BuiltinLintDiagnostics::AssociatedConstElidedLifetime {
+                            elided,
+                            span: lifetime.ident.span,
+                        },
+                    );
+                    return;
+                }
                 LifetimeRibKind::AnonymousReportError => {
                     let (msg, note) = if elided {
                         (
@@ -1811,7 +1837,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     //
                     //     impl Foo for std::cell::Ref<u32> // note lack of '_
                     //     async fn foo(_: std::cell::Ref<u32>) { ... }
-                    LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } => {
+                    LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
+                    | LifetimeRibKind::AnonymousWarnToStatic(_) => {
                         let sess = self.r.tcx.sess;
                         let mut err = rustc_errors::struct_span_err!(
                             sess,
@@ -2898,7 +2925,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         match &item.kind {
             AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
                 debug!("resolve_implementation AssocItemKind::Const");
-
                 self.with_generic_param_rib(
                     &generics.params,
                     RibKind::AssocItem,
@@ -2908,28 +2934,33 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         kind: LifetimeBinderKind::ConstItem,
                     },
                     |this| {
-                        // If this is a trait impl, ensure the const
-                        // exists in trait
-                        this.check_trait_item(
-                            item.id,
-                            item.ident,
-                            &item.kind,
-                            ValueNS,
-                            item.span,
-                            seen_trait_items,
-                            |i, s, c| ConstNotMemberOfTrait(i, s, c),
-                        );
+                        this.with_lifetime_rib(
+                            LifetimeRibKind::AnonymousWarnToStatic(item.id),
+                            |this| {
+                                // If this is a trait impl, ensure the const
+                                // exists in trait
+                                this.check_trait_item(
+                                    item.id,
+                                    item.ident,
+                                    &item.kind,
+                                    ValueNS,
+                                    item.span,
+                                    seen_trait_items,
+                                    |i, s, c| ConstNotMemberOfTrait(i, s, c),
+                                );
 
-                        this.visit_generics(generics);
-                        this.visit_ty(ty);
-                        if let Some(expr) = expr {
-                            // We allow arbitrary const expressions inside of associated consts,
-                            // even if they are potentially not const evaluatable.
-                            //
-                            // Type parameters can already be used and as associated consts are
-                            // not used as part of the type system, this is far less surprising.
-                            this.resolve_const_body(expr, None);
-                        }
+                                this.visit_generics(generics);
+                                this.visit_ty(ty);
+                                if let Some(expr) = expr {
+                                    // We allow arbitrary const expressions inside of associated consts,
+                                    // even if they are potentially not const evaluatable.
+                                    //
+                                    // Type parameters can already be used and as associated consts are
+                                    // not used as part of the type system, this is far less surprising.
+                                    this.resolve_const_body(expr, None);
+                                }
+                            },
+                        );
                     },
                 );
             }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 76e54e60d14..6d3a1d69ef0 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -18,7 +18,7 @@
 #![recursion_limit = "256"]
 #![allow(rustdoc::private_intra_doc_links)]
 #![allow(rustc::potential_query_instability)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate tracing;
@@ -39,13 +39,15 @@ use rustc_errors::{
     Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage,
 };
 use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
+use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_fluent_macro::fluent_messages;
 use rustc_hir::def::Namespace::{self, *};
+use rustc_hir::def::NonMacroAttrKind;
 use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet};
 use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathData;
-use rustc_hir::TraitCandidate;
+use rustc_hir::{PrimTy, TraitCandidate};
 use rustc_index::IndexVec;
 use rustc_metadata::creader::{CStore, CrateLoader};
 use rustc_middle::metadata::ModChild;
@@ -517,7 +519,7 @@ struct ModuleData<'a> {
 
 /// All modules are unique and allocated on a same arena,
 /// so we can use referential equality to compare them.
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
 #[rustc_pass_by_value]
 struct Module<'a>(Interned<'a, ModuleData<'a>>);
 
@@ -883,10 +885,16 @@ impl<'a> NameBindingData<'a> {
 
 #[derive(Default, Clone)]
 struct ExternPreludeEntry<'a> {
-    extern_crate_item: Option<NameBinding<'a>>,
+    binding: Option<NameBinding<'a>>,
     introduced_by_item: bool,
 }
 
+impl ExternPreludeEntry<'_> {
+    fn is_import(&self) -> bool {
+        self.binding.is_some_and(|binding| binding.is_import())
+    }
+}
+
 /// Used for better errors for E0773
 enum BuiltinMacroState {
     NotYetSeen(SyntaxExtensionKind),
@@ -996,6 +1004,12 @@ pub struct Resolver<'a, 'tcx> {
 
     arenas: &'a ResolverArenas<'a>,
     dummy_binding: NameBinding<'a>,
+    builtin_types_bindings: FxHashMap<Symbol, NameBinding<'a>>,
+    builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'a>>,
+    registered_tool_bindings: FxHashMap<Ident, NameBinding<'a>>,
+    /// Binding for implicitly declared names that come with a module,
+    /// like `self` (not yet used), or `crate`/`$crate` (for root modules).
+    module_self_bindings: FxHashMap<Module<'a>, NameBinding<'a>>,
 
     used_extern_options: FxHashSet<Symbol>,
     macro_names: FxHashSet<Ident>,
@@ -1033,7 +1047,7 @@ pub struct Resolver<'a, 'tcx> {
     /// `macro_rules` scopes produced by `macro_rules` item definitions.
     macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'a>>,
     /// Helper attributes that are in scope for the given expansion.
-    helper_attrs: FxHashMap<LocalExpnId, Vec<Ident>>,
+    helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'a>)>>,
     /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute
     /// with the given `ExpnId`.
     derive_data: FxHashMap<LocalExpnId, DeriveData>,
@@ -1111,6 +1125,7 @@ impl<'a> ResolverArenas<'a> {
         span: Span,
         no_implicit_prelude: bool,
         module_map: &mut FxHashMap<DefId, Module<'a>>,
+        module_self_bindings: &mut FxHashMap<Module<'a>, NameBinding<'a>>,
     ) -> Module<'a> {
         let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new(
             parent,
@@ -1125,6 +1140,9 @@ impl<'a> ResolverArenas<'a> {
         }
         if let Some(def_id) = def_id {
             module_map.insert(def_id, module);
+            let vis = ty::Visibility::<DefId>::Public;
+            let binding = (module, vis, module.span, LocalExpnId::ROOT).to_name_binding(self);
+            module_self_bindings.insert(module, binding);
         }
         module
     }
@@ -1236,6 +1254,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     ) -> Resolver<'a, 'tcx> {
         let root_def_id = CRATE_DEF_ID.to_def_id();
         let mut module_map = FxHashMap::default();
+        let mut module_self_bindings = FxHashMap::default();
         let graph_root = arenas.new_module(
             None,
             ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
@@ -1243,6 +1262,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             crate_span,
             attr::contains_name(attrs, sym::no_implicit_prelude),
             &mut module_map,
+            &mut module_self_bindings,
         );
         let empty_module = arenas.new_module(
             None,
@@ -1251,6 +1271,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             DUMMY_SP,
             true,
             &mut FxHashMap::default(),
+            &mut FxHashMap::default(),
         );
 
         let mut visibilities = FxHashMap::default();
@@ -1283,6 +1304,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let registered_tools = tcx.registered_tools(());
 
         let features = tcx.features();
+        let pub_vis = ty::Visibility::<DefId>::Public;
 
         let mut resolver = Resolver {
             tcx,
@@ -1330,14 +1352,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             macro_expanded_macro_export_errors: BTreeSet::new(),
 
             arenas,
-            dummy_binding: arenas.alloc_name_binding(NameBindingData {
-                kind: NameBindingKind::Res(Res::Err),
-                ambiguity: None,
-                warn_ambiguity: false,
-                expansion: LocalExpnId::ROOT,
-                span: DUMMY_SP,
-                vis: ty::Visibility::Public,
-            }),
+            dummy_binding: (Res::Err, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas),
+            builtin_types_bindings: PrimTy::ALL
+                .iter()
+                .map(|prim_ty| {
+                    let binding = (Res::PrimTy(*prim_ty), pub_vis, DUMMY_SP, LocalExpnId::ROOT)
+                        .to_name_binding(arenas);
+                    (prim_ty.name(), binding)
+                })
+                .collect(),
+            builtin_attrs_bindings: BUILTIN_ATTRIBUTES
+                .iter()
+                .map(|builtin_attr| {
+                    let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(builtin_attr.name));
+                    let binding =
+                        (res, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas);
+                    (builtin_attr.name, binding)
+                })
+                .collect(),
+            registered_tool_bindings: registered_tools
+                .iter()
+                .map(|ident| {
+                    let binding = (Res::ToolMod, pub_vis, ident.span, LocalExpnId::ROOT)
+                        .to_name_binding(arenas);
+                    (*ident, binding)
+                })
+                .collect(),
+            module_self_bindings,
 
             used_extern_options: Default::default(),
             macro_names: FxHashSet::default(),
@@ -1407,7 +1448,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         no_implicit_prelude: bool,
     ) -> Module<'a> {
         let module_map = &mut self.module_map;
-        self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude, module_map)
+        let module_self_bindings = &mut self.module_self_bindings;
+        self.arenas.new_module(
+            parent,
+            kind,
+            expn_id,
+            span,
+            no_implicit_prelude,
+            module_map,
+            module_self_bindings,
+        )
     }
 
     fn next_node_id(&mut self) -> NodeId {
@@ -1727,7 +1777,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             // but not introduce it, as used if they are accessed from lexical scope.
             if is_lexical_scope {
                 if let Some(entry) = self.extern_prelude.get(&ident.normalize_to_macros_2_0()) {
-                    if !entry.introduced_by_item && entry.extern_crate_item == Some(used_binding) {
+                    if !entry.introduced_by_item && entry.binding == Some(used_binding) {
                         return;
                     }
                 }
@@ -1885,12 +1935,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             // Make sure `self`, `super` etc produce an error when passed to here.
             return None;
         }
-        self.extern_prelude.get(&ident.normalize_to_macros_2_0()).cloned().and_then(|entry| {
-            if let Some(binding) = entry.extern_crate_item {
-                if finalize && entry.introduced_by_item {
-                    self.record_use(ident, binding, false);
+
+        let norm_ident = ident.normalize_to_macros_2_0();
+        let binding = self.extern_prelude.get(&norm_ident).cloned().and_then(|entry| {
+            Some(if let Some(binding) = entry.binding {
+                if finalize {
+                    if !entry.is_import() {
+                        self.crate_loader(|c| c.process_path_extern(ident.name, ident.span));
+                    } else if entry.introduced_by_item {
+                        self.record_use(ident, binding, false);
+                    }
                 }
-                Some(binding)
+                binding
             } else {
                 let crate_id = if finalize {
                     let Some(crate_id) =
@@ -1903,10 +1959,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     self.crate_loader(|c| c.maybe_process_path_extern(ident.name))?
                 };
                 let crate_root = self.expect_module(crate_id.as_def_id());
-                let vis = ty::Visibility::<LocalDefId>::Public;
-                Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas))
-            }
-        })
+                let vis = ty::Visibility::<DefId>::Public;
+                (crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas)
+            })
+        });
+
+        if let Some(entry) = self.extern_prelude.get_mut(&norm_ident) {
+            entry.binding = binding;
+        }
+
+        binding
     }
 
     /// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>`
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 6a5b675b4bb..1199290a4d1 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -7,7 +7,7 @@ use crate::errors::{
 use crate::Namespace::*;
 use crate::{BuiltinMacroState, Determinacy};
 use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
-use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment};
+use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
 use rustc_ast::expand::StrippedCfgItem;
 use rustc_ast::{self as ast, attr, Crate, Inline, ItemKind, ModKind, NodeId};
 use rustc_ast_pretty::pprust;
@@ -20,10 +20,10 @@ use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::compile_declarative_macro;
 use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
 use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
-use rustc_hir::def_id::{CrateNum, LocalDefId};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_middle::middle::stability;
 use rustc_middle::ty::RegisteredTools;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{TyCtxt, Visibility};
 use rustc_session::lint::builtin::{
     LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
 };
@@ -401,8 +401,17 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
         }
         // Sort helpers in a stable way independent from the derive resolution order.
         entry.helper_attrs.sort_by_key(|(i, _)| *i);
-        self.helper_attrs
-            .insert(expn_id, entry.helper_attrs.iter().map(|(_, ident)| *ident).collect());
+        let helper_attrs = entry
+            .helper_attrs
+            .iter()
+            .map(|(_, ident)| {
+                let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
+                let binding = (res, Visibility::<DefId>::Public, ident.span, expn_id)
+                    .to_name_binding(self.arenas);
+                (*ident, binding)
+            })
+            .collect();
+        self.helper_attrs.insert(expn_id, helper_attrs);
         // Mark this derive as having `Copy` either if it has `Copy` itself or if its parent derive
         // has `Copy`, to support cases like `#[derive(Clone, Copy)] #[derive(Debug)]`.
         if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) {
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index b07c6db599e..e06b6380944 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -8,6 +8,9 @@ session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible
 session_cgu_not_recorded =
     CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded
 
+session_cli_feature_diagnostic_help =
+    add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
+
 session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}`
 
 session_crate_name_empty = crate name must not be empty
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 78940462b2c..5f8bbfca890 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -57,6 +57,12 @@ pub struct FeatureDiagnosticHelp {
     pub feature: Symbol,
 }
 
+#[derive(Subdiagnostic)]
+#[help(session_cli_feature_diagnostic_help)]
+pub struct CliFeatureDiagnosticHelp {
+    pub feature: Symbol,
+}
+
 #[derive(Diagnostic)]
 #[diag(session_not_circumvent_feature)]
 pub struct NotCircumventFeature;
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index a270817f310..d6c746a7bd8 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -10,7 +10,7 @@
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 1cf63e9b7ba..671204c0d8e 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -2,7 +2,9 @@
 //! It also serves as an input to the parser itself.
 
 use crate::config::CheckCfg;
-use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError};
+use crate::errors::{
+    CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError,
+};
 use crate::lint::{
     builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
 };
@@ -110,7 +112,7 @@ pub fn feature_err_issue(
     }
 
     let mut err = sess.create_err(FeatureGateError { span, explain: explain.into() });
-    add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
+    add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);
     err
 }
 
@@ -139,7 +141,7 @@ pub fn feature_warn_issue(
     explain: &'static str,
 ) {
     let mut err = sess.span_diagnostic.struct_span_warn(span, explain);
-    add_feature_diagnostics_for_issue(&mut err, sess, feature, issue);
+    add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);
 
     // Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
     let lint = UNSTABLE_SYNTAX_PRE_EXPANSION;
@@ -158,7 +160,7 @@ pub fn feature_warn_issue(
 
 /// Adds the diagnostics for a feature to an existing error.
 pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature: Symbol) {
-    add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language);
+    add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false);
 }
 
 /// Adds the diagnostics for a feature to an existing error.
@@ -171,6 +173,7 @@ pub fn add_feature_diagnostics_for_issue(
     sess: &ParseSess,
     feature: Symbol,
     issue: GateIssue,
+    feature_from_cli: bool,
 ) {
     if let Some(n) = find_feature_issue(feature, issue) {
         err.subdiagnostic(FeatureDiagnosticForIssue { n });
@@ -178,7 +181,11 @@ pub fn add_feature_diagnostics_for_issue(
 
     // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
     if sess.unstable_features.is_nightly_build() {
-        err.subdiagnostic(FeatureDiagnosticHelp { feature });
+        if feature_from_cli {
+            err.subdiagnostic(CliFeatureDiagnosticHelp { feature });
+        } else {
+            err.subdiagnostic(FeatureDiagnosticHelp { feature });
+        }
     }
 }
 
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 71f2591fe66..f76c69af526 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -111,3 +111,50 @@ impl CanonicalizedPath {
         &self.original
     }
 }
+
+/// Gets a list of extra command-line flags provided by the user, as strings.
+///
+/// This function is used during ICEs to show more information useful for
+/// debugging, since some ICEs only happens with non-default compiler flags
+/// (and the users don't always report them).
+pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
+    const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"];
+
+    const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"];
+
+    const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
+
+    let mut args = std::env::args_os().map(|arg| arg.to_string_lossy().to_string()).peekable();
+
+    let mut result = Vec::new();
+    let mut excluded_cargo_defaults = false;
+    while let Some(arg) = args.next() {
+        if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
+            let content = if arg.len() == a.len() {
+                // A space-separated option, like `-C incremental=foo` or `--crate-type rlib`
+                match args.next() {
+                    Some(arg) => arg.to_string(),
+                    None => continue,
+                }
+            } else if arg.get(a.len()..a.len() + 1) == Some("=") {
+                // An equals option, like `--crate-type=rlib`
+                arg[a.len() + 1..].to_string()
+            } else {
+                // A non-space option, like `-Cincremental=foo`
+                arg[a.len()..].to_string()
+            };
+            let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
+            if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) {
+                excluded_cargo_defaults = true;
+            } else {
+                result.push(a.to_string());
+                match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
+                    Some(s) => result.push(format!("{s}=[REDACTED]")),
+                    None => result.push(content),
+                }
+            }
+        }
+    }
+
+    if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None }
+}
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 078ff67446f..ebacb7cce83 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -80,6 +80,10 @@ impl<'tcx> Tables<'tcx> {
         self.def_ids[impl_def.0]
     }
 
+    pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId {
+        self.def_ids[generic_def.0]
+    }
+
     pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
         stable_mir::CrateItem(self.create_def_id(did))
     }
@@ -120,6 +124,10 @@ impl<'tcx> Tables<'tcx> {
         stable_mir::ty::TraitDef(self.create_def_id(did))
     }
 
+    pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef {
+        stable_mir::ty::GenericDef(self.create_def_id(did))
+    }
+
     pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
         stable_mir::ty::ConstDef(self.create_def_id(did))
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 7e8ac9a141a..925d4a3bdd8 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -10,11 +10,11 @@
 use crate::rustc_internal::{self, opaque};
 use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
 use crate::stable_mir::ty::{
-    allocation_filter, new_allocation, Const, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
+    allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy,
+    Movability, RigidTy, TyKind, UintTy,
 };
 use crate::stable_mir::{self, Context};
 use rustc_hir as hir;
-use rustc_middle::mir::coverage::CodeRegion;
 use rustc_middle::mir::interpret::alloc_range;
 use rustc_middle::mir::{self, ConstantKind};
 use rustc_middle::ty::{self, Ty, TyCtxt, Variance};
@@ -101,6 +101,29 @@ impl<'tcx> Context for Tables<'tcx> {
         let ty = self.types[ty.0];
         ty.stable(self)
     }
+
+    fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics {
+        let def_id = self.generic_def_id(generic_def);
+        let generic_def = self.tcx.generics_of(def_id);
+        generic_def.stable(self)
+    }
+
+    fn predicates_of(
+        &mut self,
+        trait_def: &stable_mir::ty::TraitDef,
+    ) -> stable_mir::GenericPredicates {
+        let trait_def_id = self.trait_def_id(trait_def);
+        let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(trait_def_id);
+        stable_mir::GenericPredicates {
+            parent: parent.map(|did| self.trait_def(did)),
+            predicates: predicates
+                .iter()
+                .map(|(clause, span)| {
+                    (clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
+                })
+                .collect(),
+        }
+    }
 }
 
 pub struct Tables<'tcx> {
@@ -168,10 +191,7 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
                     variance: variance.stable(tables),
                 }
             }
-            Coverage(coverage) => stable_mir::mir::Statement::Coverage(stable_mir::mir::Coverage {
-                kind: coverage.kind.stable(tables),
-                code_region: coverage.code_region.as_ref().map(|reg| reg.stable(tables)),
-            }),
+            Coverage(coverage) => stable_mir::mir::Statement::Coverage(opaque(coverage)),
             Intrinsic(intrinstic) => {
                 stable_mir::mir::Statement::Intrinsic(intrinstic.stable(tables))
             }
@@ -193,7 +213,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
             }
             Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
-                opaque(region),
+                region.stable(tables),
                 kind.stable(tables),
                 place.stable(tables),
             ),
@@ -457,7 +477,19 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
         match self {
             Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)),
             Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)),
-            Constant(c) => stable_mir::mir::Operand::Constant(c.to_string()),
+            Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)),
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for mir::Constant<'tcx> {
+    type T = stable_mir::mir::Constant;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        stable_mir::mir::Constant {
+            span: self.span.stable(tables),
+            user_ty: self.user_ty.map(|u| u.as_usize()).or(None),
+            literal: self.literal.stable(tables),
         }
     }
 }
@@ -472,30 +504,6 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
     }
 }
 
-impl<'tcx> Stable<'tcx> for mir::coverage::CoverageKind {
-    type T = stable_mir::mir::CoverageKind;
-    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        use rustc_middle::mir::coverage::CoverageKind;
-        match self {
-            CoverageKind::Counter { function_source_hash, id } => {
-                stable_mir::mir::CoverageKind::Counter {
-                    function_source_hash: *function_source_hash as usize,
-                    id: opaque(id),
-                }
-            }
-            CoverageKind::Expression { id, lhs, op, rhs } => {
-                stable_mir::mir::CoverageKind::Expression {
-                    id: opaque(id),
-                    lhs: opaque(lhs),
-                    op: op.stable(tables),
-                    rhs: opaque(rhs),
-                }
-            }
-            CoverageKind::Unreachable => stable_mir::mir::CoverageKind::Unreachable,
-        }
-    }
-}
-
 impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
     type T = stable_mir::mir::UserTypeProjection;
 
@@ -504,18 +512,6 @@ impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
     }
 }
 
-impl<'tcx> Stable<'tcx> for mir::coverage::Op {
-    type T = stable_mir::mir::Op;
-
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
-        use rustc_middle::mir::coverage::Op::*;
-        match self {
-            Subtract => stable_mir::mir::Op::Subtract,
-            Add => stable_mir::mir::Op::Add,
-        }
-    }
-}
-
 impl<'tcx> Stable<'tcx> for mir::Local {
     type T = stable_mir::mir::Local;
     fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -562,20 +558,6 @@ impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
     }
 }
 
-impl<'tcx> Stable<'tcx> for CodeRegion {
-    type T = stable_mir::mir::CodeRegion;
-
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
-        stable_mir::mir::CodeRegion {
-            file_name: self.file_name.as_str().to_string(),
-            start_line: self.start_line as usize,
-            start_col: self.start_col as usize,
-            end_line: self.end_line as usize,
-            end_col: self.end_col as usize,
-        }
-    }
-}
-
 impl<'tcx> Stable<'tcx> for mir::UnwindAction {
     type T = stable_mir::mir::UnwindAction;
     fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -583,7 +565,7 @@ impl<'tcx> Stable<'tcx> for mir::UnwindAction {
         match self {
             UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue,
             UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable,
-            UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate,
+            UnwindAction::Terminate(_) => stable_mir::mir::UnwindAction::Terminate,
             UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()),
         }
     }
@@ -781,7 +763,7 @@ impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
                 otherwise: targets.otherwise().as_usize(),
             },
             UnwindResume => Terminator::Resume,
-            UnwindTerminate => Terminator::Abort,
+            UnwindTerminate(_) => Terminator::Abort,
             Return => Terminator::Return,
             Unreachable => Terminator::Unreachable,
             Drop { place, target, unwind, replace: _ } => Terminator::Drop {
@@ -835,12 +817,9 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use stable_mir::ty::GenericArgKind;
         match self {
-            ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(opaque(region)),
+            ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)),
             ty::GenericArgKind::Type(ty) => GenericArgKind::Type(tables.intern_ty(*ty)),
-            ty::GenericArgKind::Const(cnst) => {
-                let cnst = ConstantKind::from_const(*cnst, tables.tcx);
-                GenericArgKind::Const(stable_mir::ty::Const { literal: cnst.stable(tables) })
-            }
+            ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)),
         }
     }
 }
@@ -943,12 +922,12 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
 impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
     type T = stable_mir::ty::BoundRegionKind;
 
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use stable_mir::ty::BoundRegionKind;
 
         match self {
             ty::BoundRegionKind::BrAnon(option_span) => {
-                BoundRegionKind::BrAnon(option_span.map(|span| opaque(&span)))
+                BoundRegionKind::BrAnon(option_span.map(|span| span.stable(tables)))
             }
             ty::BoundRegionKind::BrNamed(def_id, symbol) => {
                 BoundRegionKind::BrNamed(rustc_internal::br_named_def(*def_id), symbol.to_string())
@@ -1046,16 +1025,14 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
             }
             ty::Str => TyKind::RigidTy(RigidTy::Str),
             ty::Array(ty, constant) => {
-                let cnst = ConstantKind::from_const(*constant, tables.tcx);
-                let cnst = stable_mir::ty::Const { literal: cnst.stable(tables) };
-                TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), cnst))
+                TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables)))
             }
             ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(tables.intern_ty(*ty))),
             ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => {
                 TyKind::RigidTy(RigidTy::RawPtr(tables.intern_ty(*ty), mutbl.stable(tables)))
             }
             ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
-                opaque(region),
+                region.stable(tables),
                 tables.intern_ty(*ty),
                 mutbl.stable(tables),
             )),
@@ -1070,7 +1047,7 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
                         .iter()
                         .map(|existential_predicate| existential_predicate.stable(tables))
                         .collect(),
-                    opaque(region),
+                    region.stable(tables),
                     dyn_kind.stable(tables),
                 ))
             }
@@ -1105,6 +1082,15 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
     }
 }
 
+impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
+    type T = stable_mir::ty::Const;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let cnst = ConstantKind::from_const(*self, tables.tcx);
+        stable_mir::ty::Const { literal: cnst.stable(tables) }
+    }
+}
+
 impl<'tcx> Stable<'tcx> for ty::ParamTy {
     type T = stable_mir::ty::ParamTy;
     fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -1205,3 +1191,244 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
         TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
     }
 }
+
+impl<'tcx> Stable<'tcx> for ty::Generics {
+    type T = stable_mir::ty::Generics;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        use stable_mir::ty::Generics;
+
+        let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect();
+        let param_def_id_to_index =
+            params.iter().map(|param| (param.def_id, param.index)).collect();
+
+        Generics {
+            parent: self.parent.map(|did| tables.generic_def(did)),
+            parent_count: self.parent_count,
+            params,
+            param_def_id_to_index,
+            has_self: self.has_self,
+            has_late_bound_regions: self
+                .has_late_bound_regions
+                .as_ref()
+                .map(|late_bound_regions| late_bound_regions.stable(tables)),
+            host_effect_index: self.host_effect_index,
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
+    type T = stable_mir::ty::GenericParamDefKind;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        use stable_mir::ty::GenericParamDefKind;
+        match self {
+            ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
+            ty::GenericParamDefKind::Type { has_default, synthetic } => {
+                GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
+            }
+            ty::GenericParamDefKind::Const { has_default } => {
+                GenericParamDefKind::Const { has_default: *has_default }
+            }
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
+    type T = stable_mir::ty::GenericParamDef;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        GenericParamDef {
+            name: self.name.to_string(),
+            def_id: tables.generic_def(self.def_id),
+            index: self.index,
+            pure_wrt_drop: self.pure_wrt_drop,
+            kind: self.kind.stable(tables),
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
+    type T = stable_mir::ty::PredicateKind;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        use ty::PredicateKind;
+        match self {
+            PredicateKind::Clause(clause_kind) => {
+                stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables))
+            }
+            PredicateKind::ObjectSafe(did) => {
+                stable_mir::ty::PredicateKind::ObjectSafe(tables.trait_def(*did))
+            }
+            PredicateKind::ClosureKind(did, generic_args, closure_kind) => {
+                stable_mir::ty::PredicateKind::ClosureKind(
+                    tables.closure_def(*did),
+                    generic_args.stable(tables),
+                    closure_kind.stable(tables),
+                )
+            }
+            PredicateKind::Subtype(subtype_predicate) => {
+                stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables))
+            }
+            PredicateKind::Coerce(coerce_predicate) => {
+                stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables))
+            }
+            PredicateKind::ConstEquate(a, b) => {
+                stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables))
+            }
+            PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous,
+            PredicateKind::AliasRelate(a, b, alias_relation_direction) => {
+                stable_mir::ty::PredicateKind::AliasRelate(
+                    a.unpack().stable(tables),
+                    b.unpack().stable(tables),
+                    alias_relation_direction.stable(tables),
+                )
+            }
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
+    type T = stable_mir::ty::ClauseKind;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        use ty::ClauseKind::*;
+        match *self {
+            Trait(trait_object) => stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables)),
+            RegionOutlives(region_outlives) => {
+                stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables))
+            }
+            TypeOutlives(type_outlives) => {
+                let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
+                stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
+                    tables.intern_ty(a),
+                    b.stable(tables),
+                ))
+            }
+            Projection(projection_predicate) => {
+                stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables))
+            }
+            ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
+                const_.stable(tables),
+                tables.intern_ty(ty),
+            ),
+            WellFormed(generic_arg) => {
+                stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables))
+            }
+            ConstEvaluatable(const_) => {
+                stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
+            }
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ClosureKind {
+    type T = stable_mir::ty::ClosureKind;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        use ty::ClosureKind::*;
+        match self {
+            Fn => stable_mir::ty::ClosureKind::Fn,
+            FnMut => stable_mir::ty::ClosureKind::FnMut,
+            FnOnce => stable_mir::ty::ClosureKind::FnOnce,
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
+    type T = stable_mir::ty::SubtypePredicate;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
+        stable_mir::ty::SubtypePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
+    type T = stable_mir::ty::CoercePredicate;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let ty::CoercePredicate { a, b } = self;
+        stable_mir::ty::CoercePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection {
+    type T = stable_mir::ty::AliasRelationDirection;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        use ty::AliasRelationDirection::*;
+        match self {
+            Equate => stable_mir::ty::AliasRelationDirection::Equate,
+            Subtype => stable_mir::ty::AliasRelationDirection::Subtype,
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> {
+    type T = stable_mir::ty::TraitPredicate;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let ty::TraitPredicate { trait_ref, polarity } = self;
+        stable_mir::ty::TraitPredicate {
+            trait_ref: trait_ref.stable(tables),
+            polarity: polarity.stable(tables),
+        }
+    }
+}
+
+impl<'tcx, A, B, U, V> Stable<'tcx> for ty::OutlivesPredicate<A, B>
+where
+    A: Stable<'tcx, T = U>,
+    B: Stable<'tcx, T = V>,
+{
+    type T = stable_mir::ty::OutlivesPredicate<U, V>;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let ty::OutlivesPredicate(a, b) = self;
+        stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables))
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
+    type T = stable_mir::ty::ProjectionPredicate;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        let ty::ProjectionPredicate { projection_ty, term } = self;
+        stable_mir::ty::ProjectionPredicate {
+            projection_ty: projection_ty.stable(tables),
+            term: term.unpack().stable(tables),
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
+    type T = stable_mir::ty::ImplPolarity;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        use ty::ImplPolarity::*;
+        match self {
+            Positive => stable_mir::ty::ImplPolarity::Positive,
+            Negative => stable_mir::ty::ImplPolarity::Negative,
+            Reservation => stable_mir::ty::ImplPolarity::Reservation,
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
+    type T = stable_mir::ty::Region;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        // FIXME: add a real implementation of stable regions
+        opaque(self)
+    }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_span::Span {
+    type T = stable_mir::ty::Span;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        // FIXME: add a real implementation of stable spans
+        opaque(self)
+    }
+}
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index c16bd6cbd70..72f719c2a5e 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -1,8 +1,8 @@
 use crate::rustc_internal::Opaque;
 use crate::stable_mir::ty::{
-    AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region,
+    AdtDef, ClosureDef, Const, ConstantKind, GeneratorDef, GenericArgs, Movability, Region,
 };
-use crate::stable_mir::{self, ty::Ty};
+use crate::stable_mir::{self, ty::Ty, Span};
 
 #[derive(Clone, Debug)]
 pub struct Body {
@@ -135,9 +135,10 @@ pub enum AsyncGeneratorKind {
 }
 
 pub(crate) type LocalDefId = Opaque;
-pub(crate) type CounterValueReference = Opaque;
-pub(crate) type InjectedExpressionId = Opaque;
-pub(crate) type ExpressionOperandId = Opaque;
+/// [`rustc_middle::mir::Coverage`] is heavily tied to internal details of the
+/// coverage implementation that are likely to change, and are unlikely to be
+/// useful to third-party tools for the foreseeable future.
+pub(crate) type Coverage = Opaque;
 
 /// The FakeReadCause describes the type of pattern why a FakeRead statement exists.
 #[derive(Clone, Debug)]
@@ -167,42 +168,6 @@ pub enum Variance {
 }
 
 #[derive(Clone, Debug)]
-pub enum Op {
-    Subtract,
-    Add,
-}
-
-#[derive(Clone, Debug)]
-pub enum CoverageKind {
-    Counter {
-        function_source_hash: usize,
-        id: CounterValueReference,
-    },
-    Expression {
-        id: InjectedExpressionId,
-        lhs: ExpressionOperandId,
-        op: Op,
-        rhs: ExpressionOperandId,
-    },
-    Unreachable,
-}
-
-#[derive(Clone, Debug)]
-pub struct CodeRegion {
-    pub file_name: String,
-    pub start_line: usize,
-    pub start_col: usize,
-    pub end_line: usize,
-    pub end_col: usize,
-}
-
-#[derive(Clone, Debug)]
-pub struct Coverage {
-    pub kind: CoverageKind,
-    pub code_region: Option<CodeRegion>,
-}
-
-#[derive(Clone, Debug)]
 pub struct CopyNonOverlapping {
     pub src: Operand,
     pub dst: Operand,
@@ -359,7 +324,7 @@ pub enum AggregateKind {
 pub enum Operand {
     Copy(Place),
     Move(Place),
-    Constant(String),
+    Constant(Constant),
 }
 
 #[derive(Clone, Debug)]
@@ -384,6 +349,13 @@ pub type VariantIdx = usize;
 type UserTypeAnnotationIndex = usize;
 
 #[derive(Clone, Debug)]
+pub struct Constant {
+    pub span: Span,
+    pub user_ty: Option<UserTypeAnnotationIndex>,
+    pub literal: ConstantKind,
+}
+
+#[derive(Clone, Debug)]
 pub struct SwitchTarget {
     pub value: u128,
     pub target: usize,
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index 19061742b64..44938eaa035 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -1,6 +1,6 @@
 //! Module that implements the public interface to the Stable MIR.
 //!
-//! This module shall contain all type definitions and APIs that we expect 3P tools to invoke to
+//! This module shall contain all type definitions and APIs that we expect third-party tools to invoke to
 //! interact with the compiler.
 //!
 //! The goal is to eventually move this module to its own crate which shall be published on
@@ -15,7 +15,9 @@ use std::cell::Cell;
 
 use crate::rustc_smir::Tables;
 
-use self::ty::{ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
+use self::ty::{
+    GenericDef, Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind,
+};
 
 pub mod mir;
 pub mod ty;
@@ -38,6 +40,12 @@ pub type TraitDecls = Vec<TraitDef>;
 /// A list of impl trait decls.
 pub type ImplTraitDecls = Vec<ImplDef>;
 
+/// A list of predicates.
+pub struct GenericPredicates {
+    pub parent: Option<TraitDef>,
+    pub predicates: Vec<(PredicateKind, Span)>,
+}
+
 /// Holds information about a crate.
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct Crate {
@@ -101,6 +109,14 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
     with(|cx| cx.trait_impl(trait_impl))
 }
 
+pub fn generics_of(generic_def: &GenericDef) -> Generics {
+    with(|cx| cx.generics_of(generic_def))
+}
+
+pub fn predicates_of(trait_def: &TraitDef) -> GenericPredicates {
+    with(|cx| cx.predicates_of(trait_def))
+}
+
 pub trait Context {
     fn entry_fn(&mut self) -> Option<CrateItem>;
     /// Retrieve all items of the local crate that have a MIR associated with them.
@@ -110,6 +126,8 @@ pub trait Context {
     fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
     fn all_trait_impls(&mut self) -> ImplTraitDecls;
     fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
+    fn generics_of(&mut self, generic_def: &GenericDef) -> Generics;
+    fn predicates_of(&mut self, trait_def: &TraitDef) -> GenericPredicates;
     /// Get information about the local crate.
     fn local_crate(&self) -> Crate;
     /// Retrieve a list of all external crates.
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 7a6601f09da..5929823b1bb 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -22,7 +22,7 @@ pub struct Const {
 
 type Ident = Opaque;
 pub(crate) type Region = Opaque;
-type Span = Opaque;
+pub(crate) type Span = Opaque;
 
 #[derive(Clone, Debug)]
 pub enum TyKind {
@@ -87,34 +87,37 @@ pub enum Movability {
     Movable,
 }
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct ForeignDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct FnDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct ClosureDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct GeneratorDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct ParamDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct BrNamedDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct AdtDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct AliasDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct TraitDef(pub(crate) DefId);
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub struct GenericDef(pub(crate) DefId);
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub struct ConstDef(pub(crate) DefId);
 
 impl TraitDef {
@@ -132,6 +135,12 @@ impl ImplDef {
     }
 }
 
+impl GenericDef {
+    pub fn generics_of(&self) -> Generics {
+        with(|tcx| tcx.generics_of(self))
+    }
+}
+
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);
 
@@ -461,3 +470,108 @@ pub struct TraitRef {
     pub def_id: TraitDef,
     pub args: GenericArgs,
 }
+
+#[derive(Clone, Debug)]
+pub struct Generics {
+    pub parent: Option<GenericDef>,
+    pub parent_count: usize,
+    pub params: Vec<GenericParamDef>,
+    pub param_def_id_to_index: Vec<(GenericDef, u32)>,
+    pub has_self: bool,
+    pub has_late_bound_regions: Option<Span>,
+    pub host_effect_index: Option<usize>,
+}
+
+#[derive(Clone, Debug)]
+pub enum GenericParamDefKind {
+    Lifetime,
+    Type { has_default: bool, synthetic: bool },
+    Const { has_default: bool },
+}
+
+#[derive(Clone, Debug)]
+pub struct GenericParamDef {
+    pub name: super::Symbol,
+    pub def_id: GenericDef,
+    pub index: u32,
+    pub pure_wrt_drop: bool,
+    pub kind: GenericParamDefKind,
+}
+
+pub struct GenericPredicates {
+    pub parent: Option<DefId>,
+    pub predicates: Vec<PredicateKind>,
+}
+
+#[derive(Clone, Debug)]
+pub enum PredicateKind {
+    Clause(ClauseKind),
+    ObjectSafe(TraitDef),
+    ClosureKind(ClosureDef, GenericArgs, ClosureKind),
+    SubType(SubtypePredicate),
+    Coerce(CoercePredicate),
+    ConstEquate(Const, Const),
+    Ambiguous,
+    AliasRelate(TermKind, TermKind, AliasRelationDirection),
+}
+
+#[derive(Clone, Debug)]
+pub enum ClauseKind {
+    Trait(TraitPredicate),
+    RegionOutlives(RegionOutlivesPredicate),
+    TypeOutlives(TypeOutlivesPredicate),
+    Projection(ProjectionPredicate),
+    ConstArgHasType(Const, Ty),
+    WellFormed(GenericArgKind),
+    ConstEvaluatable(Const),
+}
+
+#[derive(Clone, Debug)]
+pub enum ClosureKind {
+    Fn,
+    FnMut,
+    FnOnce,
+}
+
+#[derive(Clone, Debug)]
+pub struct SubtypePredicate {
+    pub a: Ty,
+    pub b: Ty,
+}
+
+#[derive(Clone, Debug)]
+pub struct CoercePredicate {
+    pub a: Ty,
+    pub b: Ty,
+}
+
+#[derive(Clone, Debug)]
+pub enum AliasRelationDirection {
+    Equate,
+    Subtype,
+}
+
+#[derive(Clone, Debug)]
+pub struct TraitPredicate {
+    pub trait_ref: TraitRef,
+    pub polarity: ImplPolarity,
+}
+
+#[derive(Clone, Debug)]
+pub struct OutlivesPredicate<A, B>(pub A, pub B);
+
+pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
+pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
+
+#[derive(Clone, Debug)]
+pub struct ProjectionPredicate {
+    pub projection_ty: AliasTy,
+    pub term: TermKind,
+}
+
+#[derive(Clone, Debug)]
+pub enum ImplPolarity {
+    Positive,
+    Negative,
+    Reservation,
+}
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 9f2ff437842..88081700c3b 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -34,11 +34,13 @@ use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::HashingControls;
 use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
-use rustc_data_structures::sync::{Lock, Lrc};
+use rustc_data_structures::sync::{Lock, Lrc, WorkerLocal};
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_index::IndexVec;
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use std::cell::RefCell;
+use std::collections::hash_map::Entry;
 use std::fmt;
 use std::hash::Hash;
 
@@ -1241,13 +1243,25 @@ impl HygieneEncodeContext {
 
 #[derive(Default)]
 /// Additional information used to assist in decoding hygiene data
-pub struct HygieneDecodeContext {
+struct HygieneDecodeContextInner {
     // Maps serialized `SyntaxContext` ids to a `SyntaxContext` in the current
     // global `HygieneData`. When we deserialize a `SyntaxContext`, we need to create
     // a new id in the global `HygieneData`. This map tracks the ID we end up picking,
     // so that multiple occurrences of the same serialized id are decoded to the same
-    // `SyntaxContext`
-    remapped_ctxts: Lock<Vec<Option<SyntaxContext>>>,
+    // `SyntaxContext`. This only stores `SyntaxContext`s which are completly decoded.
+    remapped_ctxts: Vec<Option<SyntaxContext>>,
+
+    /// Maps serialized `SyntaxContext` ids that are currently being decoded to a `SyntaxContext`.
+    decoding: FxHashMap<u32, SyntaxContext>,
+}
+
+#[derive(Default)]
+/// Additional information used to assist in decoding hygiene data
+pub struct HygieneDecodeContext {
+    inner: Lock<HygieneDecodeContextInner>,
+
+    /// A set of serialized `SyntaxContext` ids that are currently being decoded on each thread.
+    local_in_progress: WorkerLocal<RefCell<FxHashMap<u32, ()>>>,
 }
 
 /// Register an expansion which has been decoded from the on-disk-cache for the local crate.
@@ -1277,11 +1291,11 @@ pub fn register_expn_id(
     let expn_id = ExpnId { krate, local_id };
     HygieneData::with(|hygiene_data| {
         let _old_data = hygiene_data.foreign_expn_data.insert(expn_id, data);
-        debug_assert!(_old_data.is_none());
+        debug_assert!(_old_data.is_none() || cfg!(parallel_compiler));
         let _old_hash = hygiene_data.foreign_expn_hashes.insert(expn_id, hash);
-        debug_assert!(_old_hash.is_none());
+        debug_assert!(_old_hash.is_none() || _old_hash == Some(hash));
         let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
-        debug_assert!(_old_id.is_none());
+        debug_assert!(_old_id.is_none() || _old_id == Some(expn_id));
     });
     expn_id
 }
@@ -1331,38 +1345,56 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
         return SyntaxContext::root();
     }
 
-    let outer_ctxts = &context.remapped_ctxts;
+    let ctxt = {
+        let mut inner = context.inner.lock();
 
-    // Ensure that the lock() temporary is dropped early
-    {
-        if let Some(ctxt) = outer_ctxts.lock().get(raw_id as usize).copied().flatten() {
+        if let Some(ctxt) = inner.remapped_ctxts.get(raw_id as usize).copied().flatten() {
+            // This has already beeen decoded.
             return ctxt;
         }
-    }
 
-    // Allocate and store SyntaxContext id *before* calling the decoder function,
-    // as the SyntaxContextData may reference itself.
-    let new_ctxt = HygieneData::with(|hygiene_data| {
-        let new_ctxt = SyntaxContext(hygiene_data.syntax_context_data.len() as u32);
-        // Push a dummy SyntaxContextData to ensure that nobody else can get the
-        // same ID as us. This will be overwritten after call `decode_Data`
-        hygiene_data.syntax_context_data.push(SyntaxContextData {
-            outer_expn: ExpnId::root(),
-            outer_transparency: Transparency::Transparent,
-            parent: SyntaxContext::root(),
-            opaque: SyntaxContext::root(),
-            opaque_and_semitransparent: SyntaxContext::root(),
-            dollar_crate_name: kw::Empty,
-        });
-        let mut ctxts = outer_ctxts.lock();
-        let new_len = raw_id as usize + 1;
-        if ctxts.len() < new_len {
-            ctxts.resize(new_len, None);
+        match inner.decoding.entry(raw_id) {
+            Entry::Occupied(ctxt_entry) => {
+                match context.local_in_progress.borrow_mut().entry(raw_id) {
+                    Entry::Occupied(..) => {
+                        // We're decoding this already on the current thread. Return here
+                        // and let the function higher up the stack finish decoding to handle
+                        // recursive cases.
+                        return *ctxt_entry.get();
+                    }
+                    Entry::Vacant(entry) => {
+                        entry.insert(());
+
+                        // Some other thread is current decoding this. Race with it.
+                        *ctxt_entry.get()
+                    }
+                }
+            }
+            Entry::Vacant(entry) => {
+                // We are the first thread to start decoding. Mark the current thread as being progress.
+                context.local_in_progress.borrow_mut().insert(raw_id, ());
+
+                // Allocate and store SyntaxContext id *before* calling the decoder function,
+                // as the SyntaxContextData may reference itself.
+                let new_ctxt = HygieneData::with(|hygiene_data| {
+                    let new_ctxt = SyntaxContext(hygiene_data.syntax_context_data.len() as u32);
+                    // Push a dummy SyntaxContextData to ensure that nobody else can get the
+                    // same ID as us. This will be overwritten after call `decode_Data`
+                    hygiene_data.syntax_context_data.push(SyntaxContextData {
+                        outer_expn: ExpnId::root(),
+                        outer_transparency: Transparency::Transparent,
+                        parent: SyntaxContext::root(),
+                        opaque: SyntaxContext::root(),
+                        opaque_and_semitransparent: SyntaxContext::root(),
+                        dollar_crate_name: kw::Empty,
+                    });
+                    new_ctxt
+                });
+                entry.insert(new_ctxt);
+                new_ctxt
+            }
         }
-        ctxts[raw_id as usize] = Some(new_ctxt);
-        drop(ctxts);
-        new_ctxt
-    });
+    };
 
     // Don't try to decode data while holding the lock, since we need to
     // be able to recursively decode a SyntaxContext
@@ -1375,14 +1407,32 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
     // Overwrite the dummy data with our decoded SyntaxContextData
     HygieneData::with(|hygiene_data| {
         let dummy = std::mem::replace(
-            &mut hygiene_data.syntax_context_data[new_ctxt.as_u32() as usize],
+            &mut hygiene_data.syntax_context_data[ctxt.as_u32() as usize],
             ctxt_data,
         );
-        // Make sure nothing weird happening while `decode_data` was running
-        assert_eq!(dummy.dollar_crate_name, kw::Empty);
+        if cfg!(not(parallel_compiler)) {
+            // Make sure nothing weird happened while `decode_data` was running.
+            // We used `kw::Empty` for the dummy value and we expect nothing to be
+            // modifying the dummy entry.
+            // This does not hold for the parallel compiler as another thread may
+            // have inserted the fully decoded data.
+            assert_eq!(dummy.dollar_crate_name, kw::Empty);
+        }
     });
 
-    new_ctxt
+    // Mark the context as completed
+
+    context.local_in_progress.borrow_mut().remove(&raw_id);
+
+    let mut inner = context.inner.lock();
+    let new_len = raw_id as usize + 1;
+    if inner.remapped_ctxts.len() < new_len {
+        inner.remapped_ctxts.resize(new_len, None);
+    }
+    inner.remapped_ctxts[raw_id as usize] = Some(ctxt);
+    inner.decoding.remove(&raw_id);
+
+    ctxt
 }
 
 fn for_all_ctxts_in<F: FnMut(u32, SyntaxContext, &SyntaxContextData)>(
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index c24b8d9ec17..efaed0f68ce 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -23,7 +23,7 @@
 #![feature(round_char_boundary)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 28a2dfebcfe..07bae08d558 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -232,11 +232,13 @@ symbols! {
         NonZeroI32,
         NonZeroI64,
         NonZeroI8,
+        NonZeroIsize,
         NonZeroU128,
         NonZeroU16,
         NonZeroU32,
         NonZeroU64,
         NonZeroU8,
+        NonZeroUsize,
         None,
         Ok,
         Option,
@@ -278,6 +280,7 @@ symbols! {
         RwLock,
         RwLockReadGuard,
         RwLockWriteGuard,
+        Saturating,
         Send,
         SeqCst,
         SliceIndex,
@@ -305,6 +308,7 @@ symbols! {
         Vec,
         VecDeque,
         Wrapper,
+        Wrapping,
         Yield,
         _DECLS,
         _Self,
@@ -1100,6 +1104,7 @@ symbols! {
         panic_handler,
         panic_impl,
         panic_implementation,
+        panic_in_cleanup,
         panic_info,
         panic_location,
         panic_misaligned_pointer_dereference,
@@ -1179,6 +1184,9 @@ symbols! {
         ptr_offset_from,
         ptr_offset_from_unsigned,
         ptr_unique,
+        ptr_write,
+        ptr_write_unaligned,
+        ptr_write_volatile,
         pub_macro_rules,
         pub_restricted,
         public,
@@ -1370,6 +1378,7 @@ symbols! {
         sanitizer_cfi_normalize_integers,
         sanitizer_runtime,
         saturating_add,
+        saturating_div,
         saturating_sub,
         self_in_typedefs,
         self_struct_ctor,
@@ -1615,6 +1624,7 @@ symbols! {
         unix_sigpipe,
         unlikely,
         unmarked_api,
+        unnamed_fields,
         unpin,
         unreachable,
         unreachable_2015,
@@ -1687,7 +1697,10 @@ symbols! {
         windows_subsystem,
         with_negative_coherence,
         wrapping_add,
+        wrapping_div,
         wrapping_mul,
+        wrapping_rem,
+        wrapping_rem_euclid,
         wrapping_sub,
         wreg,
         write_bytes,
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 d345368d552..77457c8daaa 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
@@ -447,7 +447,7 @@ fn encode_ty<'tcx>(
             typeid.push('b');
         }
 
-        ty::Int(..) | ty::Uint(..) | ty::Float(..) => {
+        ty::Int(..) | ty::Uint(..) => {
             // u<length><type-name> as vendor extended type
             let mut s = String::from(match ty.kind() {
                 ty::Int(IntTy::I8) => "u2i8",
@@ -462,14 +462,23 @@ fn encode_ty<'tcx>(
                 ty::Uint(UintTy::U64) => "u3u64",
                 ty::Uint(UintTy::U128) => "u4u128",
                 ty::Uint(UintTy::Usize) => "u5usize",
-                ty::Float(FloatTy::F32) => "u3f32",
-                ty::Float(FloatTy::F64) => "u3f64",
-                _ => "",
+                _ => bug!("encode_ty: unexpected `{:?}`", ty.kind()),
             });
             compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
             typeid.push_str(&s);
         }
 
+        // Rust's f32 and f64 single (32-bit) and double (64-bit) precision floating-point types
+        // have IEEE-754 binary32 and binary64 floating-point layouts, respectively.
+        //
+        // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#fixed-width-floating-point-types.)
+        ty::Float(float_ty) => {
+            typeid.push(match float_ty {
+                FloatTy::F32 => 'f',
+                FloatTy::F64 => 'd',
+            });
+        }
+
         ty::Char => {
             // u4char as vendor extended type
             let mut s = String::from("u4char");
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index b52002b1239..e838e11131f 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -19,7 +19,7 @@
 #![feature(step_trait)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 use std::path::{Path, PathBuf};
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 31b6961bb62..f8d40c4142d 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2216,7 +2216,7 @@ impl Default for TargetOptions {
             mcount: "mcount".into(),
             llvm_mcount_intrinsic: None,
             llvm_abiname: "".into(),
-            relax_elf_relocations: false,
+            relax_elf_relocations: true,
             llvm_args: cvs![],
             use_ctors_section: false,
             eh_frame_header: true,
diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
index a7ed74f4721..dc1e5967859 100644
--- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
@@ -69,7 +69,6 @@ pub fn target() -> Target {
         position_independent_executables: true,
         pre_link_args,
         override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(Cow::from).collect()),
-        relax_elf_relocations: true,
         ..Default::default()
     };
     Target {
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index b0f8ea7a05d..e0abc7f04f5 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -6,7 +6,7 @@
 #![feature(unwrap_infallible)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[macro_use]
 extern crate bitflags;
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index ffe6d637387..e43b6ac4039 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -88,8 +88,8 @@
 #![warn(missing_docs)]
 #![allow(explicit_outlives_requirements)]
 #![warn(multiple_supertrait_upcastable)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
-#![cfg_attr(not(bootstrap), allow(rustdoc::redundant_explicit_links))]
+#![allow(internal_features)]
+#![allow(rustdoc::redundant_explicit_links)]
 //
 // Library features:
 // tidy-alphabetical-start
@@ -120,6 +120,7 @@
 #![feature(const_waker)]
 #![feature(core_intrinsics)]
 #![feature(core_panic)]
+#![feature(deprecated_suggestion)]
 #![feature(dispatch_from_dyn)]
 #![feature(error_generic_member_access)]
 #![feature(error_in_core)]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index afed3fdf745..c485680f92e 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -2719,7 +2719,7 @@ impl<T> Weak<T> {
     /// ```
     #[inline]
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
-    #[rustc_const_stable(feature = "const_weak_new", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_weak_new", since = "1.73.0")]
     #[must_use]
     pub const fn new() -> Weak<T> {
         Weak {
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 093dcbbe8bf..aa3b7b7e191 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -592,7 +592,7 @@ impl<T> [T] {
     /// ```
     #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.3.0", note = "renamed to join")]
+    #[deprecated(since = "1.3.0", note = "renamed to join", suggestion = "join")]
     pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
     where
         Self: Join<Separator>,
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 476a4fea54f..d3b7558440c 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -2501,7 +2501,7 @@ impl<T> Weak<T> {
     /// ```
     #[inline]
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
-    #[rustc_const_stable(feature = "const_weak_new", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_weak_new", since = "1.73.0")]
     #[must_use]
     pub const fn new() -> Weak<T> {
         Weak {
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 183dd8e6e59..9cb27899f10 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -2499,7 +2499,6 @@ fn test_into_flattened_size_overflow() {
     let _ = v.into_flattened();
 }
 
-#[cfg(not(bootstrap))]
 #[test]
 fn test_box_zero_allocator() {
     use core::{alloc::AllocError, cell::RefCell};
diff --git a/library/backtrace b/library/backtrace
-Subproject e1c49fbd6124a1b626cdf19871aff68c362bdf0
+Subproject 99faef833f890fe89f1a959d89b951954118828
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index bf4c682d33e..4bbe61ca3e7 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1893,8 +1893,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// on an _exclusive_ `UnsafeCell<T>`. Even though `T` and `UnsafeCell<T>` have the
 /// same memory layout, the following is not allowed and undefined behavior:
 ///
-#[cfg_attr(bootstrap, doc = "```rust,no_run")]
-#[cfg_attr(not(bootstrap), doc = "```rust,compile_fail")]
+/// ```rust,compile_fail
 /// # use std::cell::UnsafeCell;
 /// unsafe fn not_allowed<T>(ptr: &UnsafeCell<T>) -> &mut T {
 ///   let t = ptr as *const UnsafeCell<T> as *mut T;
diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs
index 56ab63be27d..b048b513592 100644
--- a/library/core/src/convert/num.rs
+++ b/library/core/src/convert/num.rs
@@ -142,9 +142,9 @@ impl_from! { i16, isize, #[stable(feature = "lossless_iusize_conv", since = "1.2
 
 // RISC-V defines the possibility of a 128-bit address space (RV128).
 
-// CHERI proposes 256-bit “capabilities”. Unclear if this would be relevant to usize/isize.
+// CHERI proposes 128-bit “capabilities”. Unclear if this would be relevant to usize/isize.
 // https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/20171017a-cheri-poster.pdf
-// https://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf
+// https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-951.pdf
 
 // Note: integers can only be represented with full precision in a float if
 // they fit in the significand, which is 24 bits in f32 and 53 bits in f64.
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 676d4f2f38c..605870b8a7b 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2399,7 +2399,6 @@ extern "rust-intrinsic" {
     /// that differs.  That allows optimizations that can read in large chunks.
     ///
     /// [valid]: crate::ptr#safety
-    #[cfg(not(bootstrap))]
     #[rustc_const_unstable(feature = "const_intrinsic_compare_bytes", issue = "none")]
     #[rustc_nounwind]
     pub fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32;
@@ -2844,18 +2843,3 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
         write_bytes(dst, val, count)
     }
 }
-
-/// Backfill for bootstrap
-#[cfg(bootstrap)]
-pub unsafe fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32 {
-    extern "C" {
-        fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> crate::ffi::c_int;
-    }
-
-    if bytes != 0 {
-        // SAFETY: Since bytes is non-zero, the caller has met `memcmp`'s requirements.
-        unsafe { memcmp(left, right, bytes).into() }
-    } else {
-        0
-    }
-}
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index ef0a2fd4ec4..b99346b6ba6 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -14,7 +14,7 @@
 //!
 //! ```rust
 //! #![feature(core_intrinsics, custom_mir)]
-#![cfg_attr(not(bootstrap), doc = "#![allow(internal_features)]")]
+//! #![allow(internal_features)]
 //!
 //! use core::intrinsics::mir::*;
 //!
@@ -64,7 +64,7 @@
 //!
 //! ```rust
 //! #![feature(core_intrinsics, custom_mir)]
-#![cfg_attr(not(bootstrap), doc = "#![allow(internal_features)]")]
+//! #![allow(internal_features)]
 //!
 //! use core::intrinsics::mir::*;
 //!
@@ -318,7 +318,7 @@ define!(
     /// # Examples
     ///
     /// ```rust
-    #[cfg_attr(not(bootstrap), doc = "#![allow(internal_features)]")]
+    /// #![allow(internal_features)]
     /// #![feature(custom_mir, core_intrinsics)]
     ///
     /// use core::intrinsics::mir::*;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index a2729b3743c..f39c4176440 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -96,9 +96,9 @@
 #![allow(explicit_outlives_requirements)]
 #![allow(incomplete_features)]
 #![warn(multiple_supertrait_upcastable)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 // Do not check link redundancy on bootstraping phase
-#![cfg_attr(not(bootstrap), allow(rustdoc::redundant_explicit_links))]
+#![allow(rustdoc::redundant_explicit_links)]
 //
 // Library features:
 // tidy-alphabetical-start
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 2fff3f0efd7..732fcce0f29 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -413,7 +413,7 @@ pub const unsafe fn size_of_val_raw<T: ?Sized>(val: *const T) -> usize {
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(note = "use `align_of` instead", since = "1.2.0")]
+#[deprecated(note = "use `align_of` instead", since = "1.2.0", suggestion = "align_of")]
 pub fn min_align_of<T>() -> usize {
     intrinsics::min_align_of::<T>()
 }
@@ -436,7 +436,7 @@ pub fn min_align_of<T>() -> usize {
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(note = "use `align_of_val` instead", since = "1.2.0")]
+#[deprecated(note = "use `align_of_val` instead", since = "1.2.0", suggestion = "align_of_val")]
 pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
     // SAFETY: val is a reference, so it's a valid raw pointer
     unsafe { intrinsics::min_align_of_val(val) }
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 81148c7cc51..23ca37817d4 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2077,8 +2077,8 @@ macro_rules! uint_impl {
         /// ```
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".div_ceil(4), 2);")]
         /// ```
-        #[stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "int_roundings1", since = "1.73.0")]
+        #[rustc_const_stable(feature = "int_roundings1", since = "1.73.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -2113,8 +2113,8 @@ macro_rules! uint_impl {
         #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".next_multiple_of(8), 16);")]
         #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".next_multiple_of(8), 24);")]
         /// ```
-        #[stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "int_roundings1", since = "1.73.0")]
+        #[rustc_const_stable(feature = "int_roundings1", since = "1.73.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -2140,8 +2140,8 @@ macro_rules! uint_impl {
         #[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".checked_next_multiple_of(0), None);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_next_multiple_of(2), None);")]
         /// ```
-        #[stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "int_roundings1", since = "1.73.0")]
+        #[rustc_const_stable(feature = "int_roundings1", since = "1.73.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 7b6249207fe..ab6aa0df428 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -179,6 +179,8 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
 
 /// Panic because we cannot unwind out of a function.
 ///
+/// This is a separate function to avoid the codesize impact of each crate containing the string to
+/// pass to `panic_nounwind`.
 /// This function is called directly by the codegen backend, and must not have
 /// any extra arguments (including those synthesized by track_caller).
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
@@ -186,9 +188,26 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
 #[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
 fn panic_cannot_unwind() -> ! {
+    // Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`.
     panic_nounwind("panic in a function that cannot unwind")
 }
 
+/// Panic because we are unwinding out of a destructor during cleanup.
+///
+/// This is a separate function to avoid the codesize impact of each crate containing the string to
+/// pass to `panic_nounwind`.
+/// This function is called directly by the codegen backend, and must not have
+/// any extra arguments (including those synthesized by track_caller).
+#[cfg(not(bootstrap))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function
+#[rustc_nounwind]
+fn panic_in_cleanup() -> ! {
+    // Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`.
+    panic_nounwind("panic in a destructor during cleanup")
+}
+
 /// This function is used instead of panic_fmt in const eval.
 #[lang = "const_panic_fmt"]
 #[rustc_const_unstable(feature = "core_panic", issue = "none")]
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 5f094ac4e7e..01e36044899 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1357,6 +1357,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+#[rustc_diagnostic_item = "ptr_write"]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub const unsafe fn write<T>(dst: *mut T, src: T) {
     // Semantically, it would be fine for this to be implemented as a
@@ -1459,6 +1460,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
+#[rustc_diagnostic_item = "ptr_write_unaligned"]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
     // SAFETY: the caller must guarantee that `dst` is valid for writes.
@@ -1607,6 +1609,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
 /// ```
 #[inline]
 #[stable(feature = "volatile", since = "1.9.0")]
+#[rustc_diagnostic_item = "ptr_write_volatile"]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
     // SAFETY: the caller must uphold the safety contract for `volatile_store`.
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 9582ca9e0be..e0fd347a049 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -367,7 +367,7 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
-    #[rustc_const_stable(feature = "const_nonnull_as_ref", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_nonnull_as_ref", since = "1.73.0")]
     #[must_use]
     #[inline(always)]
     pub const unsafe fn as_ref<'a>(&self) -> &'a T {
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index e5f34952c7d..23cebdb6c3b 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -997,7 +997,7 @@ impl str {
 
     /// An iterator over the lines of a string.
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.4.0", note = "use lines() instead now")]
+    #[deprecated(since = "1.4.0", note = "use lines() instead now", suggestion = "lines")]
     #[inline]
     #[allow(deprecated)]
     pub fn lines_any(&self) -> LinesAny<'_> {
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 49f9f6d4ad1..2b37af66bd6 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -265,7 +265,7 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
 /// inclusion/exclusion) does not point to the starting byte offset of
 /// a character (as defined by `is_char_boundary`), if `begin > end`, or if
 /// `end > len`.
-#[stable(feature = "slice_index_str_with_ops_bound_pair", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_index_str_with_ops_bound_pair", since = "1.73.0")]
 unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) {
     type Output = str;
 
diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index 76b35919658..02534491da9 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -14,7 +14,7 @@
 #![feature(staged_api)]
 #![feature(rustc_attrs)]
 #![feature(c_unwind)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[cfg(target_os = "android")]
 mod android;
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index 009014de5c2..e7d34daa079 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -19,14 +19,13 @@
 #![feature(panic_unwind)]
 #![feature(staged_api)]
 #![feature(std_internals)]
-#![cfg_attr(bootstrap, feature(abi_thiscall))]
 #![feature(rustc_attrs)]
 #![panic_runtime]
 #![feature(panic_runtime)]
 #![feature(c_unwind)]
 // `real_imp` is unused with Miri, so silence warnings.
 #![cfg_attr(miri, allow(dead_code))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 use alloc::boxed::Box;
 use core::any::Any;
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 83d637b685a..d382fec9352 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -32,7 +32,7 @@
 #![feature(min_specialization)]
 #![feature(strict_provenance)]
 #![recursion_limit = "256"]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
 #[doc(hidden)]
diff --git a/library/profiler_builtins/src/lib.rs b/library/profiler_builtins/src/lib.rs
index a81d0a63547..ac685b18c29 100644
--- a/library/profiler_builtins/src/lib.rs
+++ b/library/profiler_builtins/src/lib.rs
@@ -7,5 +7,5 @@
     issue = "none"
 )]
 #![allow(unused_features)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 #![feature(staged_api)]
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index a659b552f47..c3506175715 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -822,6 +822,7 @@ impl f32 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[doc(alias = "log1p")]
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -988,7 +989,9 @@ impl f32 {
         unsafe { cmath::tgammaf(self) }
     }
 
-    /// Returns the natural logarithm of the gamma function.
+    /// Natural logarithm of the absolute value of the gamma function
+    ///
+    /// The integer part of the tuple indicates the sign of the gamma function.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 721e1fb754e..e4b7bfeeb84 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -822,6 +822,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-20);
     /// ```
+    #[doc(alias = "log1p")]
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -988,7 +989,9 @@ impl f64 {
         unsafe { cmath::tgamma(self) }
     }
 
-    /// Returns the natural logarithm of the gamma function.
+    /// Natural logarithm of the absolute value of the gamma function
+    ///
+    /// The integer part of the tuple indicates the sign of the gamma function.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index b0484474712..ee9f6ed087c 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -156,7 +156,7 @@
 
 #[stable(feature = "alloc_c_string", since = "1.64.0")]
 pub use alloc::ffi::{CString, FromVecWithNulError, IntoStringError, NulError};
-#[stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "cstr_from_bytes_until_nul", since = "1.73.0")]
 pub use core::ffi::FromBytesUntilNulError;
 #[stable(feature = "core_c_str", since = "1.64.0")]
 pub use core::ffi::{CStr, FromBytesWithNulError};
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index a7e65305386..3c67bea7a22 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -745,14 +745,17 @@ fn buffer_capacity_required(mut file: &File) -> Option<usize> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Read for &File {
+    #[inline]
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 
+    #[inline]
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         self.inner.read_vectored(bufs)
     }
 
+    #[inline]
     fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
         self.inner.read_buf(cursor)
     }
@@ -849,7 +852,7 @@ impl Seek for File {
     }
 }
 
-#[stable(feature = "io_traits_arc", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "io_traits_arc", since = "1.73.0")]
 impl Read for Arc<File> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         (&**self).read(buf)
@@ -871,7 +874,7 @@ impl Read for Arc<File> {
         (&**self).read_to_string(buf)
     }
 }
-#[stable(feature = "io_traits_arc", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "io_traits_arc", since = "1.73.0")]
 impl Write for Arc<File> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         (&**self).write(buf)
@@ -888,7 +891,7 @@ impl Write for Arc<File> {
         (&**self).flush()
     }
 }
-#[stable(feature = "io_traits_arc", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "io_traits_arc", since = "1.73.0")]
 impl Seek for Arc<File> {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (&**self).seek(pos)
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 34c0ce9dcf8..d6fce4ee78f 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -916,6 +916,16 @@ impl Error {
             ErrorData::SimpleMessage(m) => m.kind,
         }
     }
+
+    #[inline]
+    pub(crate) fn is_interrupted(&self) -> bool {
+        match self.repr.data() {
+            ErrorData::Os(code) => sys::is_interrupted(code),
+            ErrorData::Custom(c) => c.kind == ErrorKind::Interrupted,
+            ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
+            ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
+        }
+    }
 }
 
 impl fmt::Debug for Repr {
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 71d91f21362..e89843b5703 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -390,7 +390,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
         let mut cursor = read_buf.unfilled();
         match r.read_buf(cursor.reborrow()) {
             Ok(()) => {}
-            Err(e) if e.kind() == ErrorKind::Interrupted => continue,
+            Err(e) if e.is_interrupted() => continue,
             Err(e) => return Err(e),
         }
 
@@ -421,7 +421,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
                         buf.extend_from_slice(&probe[..n]);
                         break;
                     }
-                    Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+                    Err(ref e) if e.is_interrupted() => continue,
                     Err(e) => return Err(e),
                 }
             }
@@ -470,7 +470,7 @@ pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [
                 let tmp = buf;
                 buf = &mut tmp[n..];
             }
-            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
+            Err(ref e) if e.is_interrupted() => {}
             Err(e) => return Err(e),
         }
     }
@@ -860,7 +860,7 @@ pub trait Read {
             let prev_written = cursor.written();
             match self.read_buf(cursor.reborrow()) {
                 Ok(()) => {}
-                Err(e) if e.kind() == ErrorKind::Interrupted => continue,
+                Err(e) if e.is_interrupted() => continue,
                 Err(e) => return Err(e),
             }
 
@@ -1579,7 +1579,7 @@ pub trait Write {
                     ));
                 }
                 Ok(n) => buf = &buf[n..],
-                Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
+                Err(ref e) if e.is_interrupted() => {}
                 Err(e) => return Err(e),
             }
         }
@@ -1943,7 +1943,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> R
         let (done, used) = {
             let available = match r.fill_buf() {
                 Ok(n) => n,
-                Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+                Err(ref e) if e.is_interrupted() => continue,
                 Err(e) => return Err(e),
             };
             match memchr::memchr(delim, available) {
@@ -2734,7 +2734,7 @@ impl<R: Read> Iterator for Bytes<R> {
             return match self.inner.read(slice::from_mut(&mut byte)) {
                 Ok(0) => None,
                 Ok(..) => Some(Ok(byte)),
-                Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+                Err(ref e) if e.is_interrupted() => continue,
                 Err(e) => Some(Err(e)),
             };
         }
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index 3840ffe7eec..6bc8f181c90 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -100,7 +100,7 @@ impl SizeHint for Empty {
     }
 }
 
-#[stable(feature = "empty_write", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "empty_write", since = "1.73.0")]
 impl Write for Empty {
     #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
@@ -124,7 +124,7 @@ impl Write for Empty {
     }
 }
 
-#[stable(feature = "empty_write", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "empty_write", since = "1.73.0")]
 impl Write for &Empty {
     #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index eb46f4e54bb..873bfb6218b 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1820,7 +1820,7 @@ mod true_keyword {}
 
 #[doc(keyword = "type")]
 //
-/// Define an alias for an existing type.
+/// Define an [alias] for an existing type.
 ///
 /// The syntax is `type Name = ExistingType;`.
 ///
@@ -1838,6 +1838,13 @@ mod true_keyword {}
 /// assert_eq!(m, k);
 /// ```
 ///
+/// A type can be generic:
+///
+/// ```rust
+/// # use std::sync::{Arc, Mutex};
+/// type ArcMutex<T> = Arc<Mutex<T>>;
+/// ```
+///
 /// In traits, `type` is used to declare an [associated type]:
 ///
 /// ```rust
@@ -1860,6 +1867,7 @@ mod true_keyword {}
 ///
 /// [`trait`]: keyword.trait.html
 /// [associated type]: ../reference/items/associated-items.html#associated-types
+/// [alias]: ../reference/items/type-aliases.html
 mod type_keyword {}
 
 #[doc(keyword = "unsafe")]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 58684ffe500..1955ef815ff 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -220,10 +220,10 @@
 #![warn(missing_debug_implementations)]
 #![allow(explicit_outlives_requirements)]
 #![allow(unused_lifetimes)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 #![deny(rustc::existing_doc_keyword)]
 #![deny(fuzzy_provenance_casts)]
-#![cfg_attr(not(bootstrap), allow(rustdoc::redundant_explicit_links))]
+#![allow(rustdoc::redundant_explicit_links)]
 // Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind`
 #![deny(ffi_unwind_calls)]
 // std may use features in a platform-specific way
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index 88326aaf295..029de8fbf76 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -1007,7 +1007,7 @@ impl DirBuilderExt for fs::DirBuilder {
 ///     Ok(())
 /// }
 /// ```
-#[stable(feature = "unix_chown", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "unix_chown", since = "1.73.0")]
 pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
     sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
 }
@@ -1027,7 +1027,7 @@ pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::
 ///     Ok(())
 /// }
 /// ```
-#[stable(feature = "unix_chown", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "unix_chown", since = "1.73.0")]
 pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
     sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
 }
@@ -1047,7 +1047,7 @@ pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<
 ///     Ok(())
 /// }
 /// ```
-#[stable(feature = "unix_chown", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "unix_chown", since = "1.73.0")]
 pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
     sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX))
 }
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index f54d5934175..7380b45b00f 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1535,7 +1535,7 @@ impl From<fs::File> for Stdio {
 pub struct ExitStatus(imp::ExitStatus);
 
 /// The default value is one which indicates successful completion.
-#[stable(feature = "process-exitcode-default", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "process-exitcode-default", since = "1.73.0")]
 impl Default for ExitStatus {
     fn default() -> Self {
         // Ideally this would be done by ExitCode::default().into() but that is complicated.
diff --git a/library/std/src/sys/itron/error.rs b/library/std/src/sys/itron/error.rs
index 830c60d329e..fbc822d4eb6 100644
--- a/library/std/src/sys/itron/error.rs
+++ b/library/std/src/sys/itron/error.rs
@@ -79,6 +79,11 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
     }
 }
 
+#[inline]
+pub fn is_interrupted(er: abi::ER) -> bool {
+    er == abi::E_RLWAI
+}
+
 pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
     match er {
         // Success
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index 9865a945bad..09d3f7638ca 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -86,6 +86,12 @@ pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
     }
 }
 
+#[inline]
+pub fn is_interrupted(code: i32) -> bool {
+    use fortanix_sgx_abi::Error;
+    code == Error::Interrupted as _
+}
+
 pub fn decode_error_kind(code: i32) -> ErrorKind {
     use fortanix_sgx_abi::Error;
 
diff --git a/library/std/src/sys/solid/error.rs b/library/std/src/sys/solid/error.rs
index 547b4f3a984..d1877a8bcd2 100644
--- a/library/std/src/sys/solid/error.rs
+++ b/library/std/src/sys/solid/error.rs
@@ -31,6 +31,11 @@ pub fn error_name(er: abi::ER) -> Option<&'static str> {
     }
 }
 
+#[inline]
+fn is_interrupted(er: abi::ER) -> bool {
+    false
+}
+
 pub fn decode_error_kind(er: abi::ER) -> ErrorKind {
     match er {
         // Success
diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs
index 923d27fd936..e7029174511 100644
--- a/library/std/src/sys/solid/mod.rs
+++ b/library/std/src/sys/solid/mod.rs
@@ -72,6 +72,11 @@ pub fn unsupported_err() -> crate::io::Error {
     )
 }
 
+#[inline]
+pub fn is_interrupted(code: i32) -> bool {
+    error::is_interrupted(code)
+}
+
 pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind {
     error::decode_error_kind(code)
 }
diff --git a/library/std/src/sys/solid/net.rs b/library/std/src/sys/solid/net.rs
index 0bd2bc3b961..bdd64ab02b7 100644
--- a/library/std/src/sys/solid/net.rs
+++ b/library/std/src/sys/solid/net.rs
@@ -181,6 +181,12 @@ pub(super) fn error_name(er: abi::ER) -> Option<&'static str> {
     unsafe { CStr::from_ptr(netc::strerror(er)) }.to_str().ok()
 }
 
+#[inline]
+pub fn is_interrupted(er: abi::ER) -> bool {
+    let errno = netc::SOLID_NET_ERR_BASE - er;
+    errno as libc::c_int == libc::EINTR
+}
+
 pub(super) fn decode_error_kind(er: abi::ER) -> ErrorKind {
     let errno = netc::SOLID_NET_ERR_BASE - er;
     match errno as libc::c_int {
diff --git a/library/std/src/sys/solid/os.rs b/library/std/src/sys/solid/os.rs
index 9f4e66d628b..ff81544ba91 100644
--- a/library/std/src/sys/solid/os.rs
+++ b/library/std/src/sys/solid/os.rs
@@ -8,7 +8,7 @@ use crate::os::{
     solid::ffi::{OsStrExt, OsStringExt},
 };
 use crate::path::{self, PathBuf};
-use crate::sync::RwLock;
+use crate::sync::{PoisonError, RwLock};
 use crate::sys::common::small_c_string::run_with_cstr;
 use crate::vec;
 
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 77ef086f29b..6d743903314 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -240,6 +240,11 @@ pub use crate::sys::android::signal;
 #[cfg(not(target_os = "android"))]
 pub use libc::signal;
 
+#[inline]
+pub(crate) fn is_interrupted(errno: i32) -> bool {
+    errno == libc::EINTR
+}
+
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     use ErrorKind::*;
     match errno as libc::c_int {
diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs
index 5cd9e57de19..5c379992b20 100644
--- a/library/std/src/sys/unsupported/common.rs
+++ b/library/std/src/sys/unsupported/common.rs
@@ -23,6 +23,10 @@ pub fn unsupported_err() -> std_io::Error {
     )
 }
 
+pub fn is_interrupted(_code: i32) -> bool {
+    false
+}
+
 pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
     crate::io::ErrorKind::Uncategorized
 }
diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs
index 98517da1d0f..5cbb5cb65ba 100644
--- a/library/std/src/sys/wasi/mod.rs
+++ b/library/std/src/sys/wasi/mod.rs
@@ -76,6 +76,11 @@ cfg_if::cfg_if! {
 mod common;
 pub use common::*;
 
+#[inline]
+pub fn is_interrupted(errno: i32) -> bool {
+    errno == wasi::ERRNO_INTR.raw().into()
+}
+
 pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
     use std_io::ErrorKind::*;
     if errno > u16::MAX as i32 || errno < 0 {
diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs
index dbad425976a..a0eefa8811a 100644
--- a/library/std/src/sys/wasi/thread.rs
+++ b/library/std/src/sys/wasi/thread.rs
@@ -47,12 +47,20 @@ cfg_if::cfg_if! {
                     stack_size: libc::size_t,
                 ) -> ffi::c_int;
                 pub fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> ffi::c_int;
+                pub fn pthread_detach(thread: pthread_t) -> ffi::c_int;
             }
         }
 
         pub struct Thread {
             id: libc::pthread_t,
         }
+
+        impl Drop for Thread {
+            fn drop(&mut self) {
+                let ret = unsafe { libc::pthread_detach(self.id) };
+                debug_assert_eq!(ret, 0);
+            }
+        }
     } else {
         pub struct Thread(!);
     }
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index bcc172b0fae..b609ad2472c 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -60,6 +60,11 @@ pub unsafe fn cleanup() {
     net::cleanup();
 }
 
+#[inline]
+pub fn is_interrupted(_errno: i32) -> bool {
+    false
+}
+
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     use ErrorKind::*;
 
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 21515adc6c4..09994e47f0a 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -325,7 +325,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     ///
     /// assert_eq!(X.get(), 123);
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn set(&'static self, value: T) {
         self.initialize_with(Cell::new(value), |value, cell| {
             if let Some(value) = value {
@@ -358,7 +358,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     ///
     /// assert_eq!(X.get(), 1);
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn get(&'static self) -> T
     where
         T: Copy,
@@ -388,7 +388,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// assert_eq!(X.take(), Some(1));
     /// assert_eq!(X.take(), None);
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn take(&'static self) -> T
     where
         T: Default,
@@ -418,7 +418,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// assert_eq!(X.replace(2), 1);
     /// assert_eq!(X.replace(3), 2);
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn replace(&'static self, value: T) -> T {
         self.with(|cell| cell.replace(value))
     }
@@ -448,7 +448,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert!(v.is_empty()));
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn with_borrow<F, R>(&'static self, f: F) -> R
     where
         F: FnOnce(&T) -> R,
@@ -481,7 +481,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert_eq!(*v, vec![1]));
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn with_borrow_mut<F, R>(&'static self, f: F) -> R
     where
         F: FnOnce(&mut T) -> R,
@@ -517,7 +517,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert_eq!(*v, vec![1, 2, 3]));
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn set(&'static self, value: T) {
         self.initialize_with(RefCell::new(value), |value, cell| {
             if let Some(value) = value {
@@ -558,7 +558,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert!(v.is_empty()));
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn take(&'static self) -> T
     where
         T: Default,
@@ -589,7 +589,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert_eq!(*v, vec![1, 2, 3]));
     /// ```
-    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "local_key_cell_methods", since = "1.73.0")]
     pub fn replace(&'static self, value: T) -> T {
         self.with(|cell| cell.replace(value))
     }
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 64d10dd5712..413f0fba342 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -21,7 +21,7 @@
 #![feature(process_exitcode_internals)]
 #![feature(panic_can_unwind)]
 #![feature(test)]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 // Public reexports
 pub use self::bench::{black_box, Bencher};
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 0b4daeafe46..62e97c65569 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -5,7 +5,7 @@
 #![feature(c_unwind)]
 #![feature(cfg_target_abi)]
 #![cfg_attr(not(target_env = "msvc"), feature(libc))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![allow(internal_features)]
 
 cfg_if::cfg_if! {
     if #[cfg(target_env = "msvc")] {
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index f44a05a6b28..9dbc87c337c 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -623,7 +623,7 @@ class RustBuild(object):
 
     def should_fix_bins_and_dylibs(self):
         """Whether or not `fix_bin_or_dylib` needs to be run; can only be True
-        on NixOS.
+        on NixOS or if config.toml has `build.patch-binaries-for-nix` set.
         """
         if self._should_fix_bins_and_dylibs is not None:
             return self._should_fix_bins_and_dylibs
@@ -643,23 +643,31 @@ class RustBuild(object):
             if ostype != "Linux":
                 return False
 
-            # If the user has asked binaries to be patched for Nix, then
-            # don't check for NixOS or `/lib`.
+            # If the user has explicitly indicated whether binaries should be
+            # patched for Nix, then don't check for NixOS.
             if self.get_toml("patch-binaries-for-nix", "build") == "true":
                 return True
+            if self.get_toml("patch-binaries-for-nix", "build") == "false":
+                return False
 
             # Use `/etc/os-release` instead of `/etc/NIXOS`.
             # The latter one does not exist on NixOS when using tmpfs as root.
             try:
                 with open("/etc/os-release", "r") as f:
-                    if not any(ln.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for ln in f):
-                        return False
+                    is_nixos = any(ln.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"')
+                                   for ln in f)
             except FileNotFoundError:
-                return False
-            if os.path.exists("/lib"):
-                return False
+                is_nixos = False
 
-            return True
+            # If not on NixOS, then warn if user seems to be atop Nix shell
+            if not is_nixos:
+                in_nix_shell = os.getenv('IN_NIX_SHELL')
+                if in_nix_shell:
+                    print("The IN_NIX_SHELL environment variable is `{}`;".format(in_nix_shell),
+                          "you may need to set `patch-binaries-for-nix=true` in config.toml",
+                          file=sys.stderr)
+
+            return is_nixos
 
         answer = self._should_fix_bins_and_dylibs = get_answer()
         if answer:
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 4821d20a898..e5fdac3ceda 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -137,7 +137,7 @@ pub struct Config {
     pub json_output: bool,
     pub test_compare_mode: bool,
     pub color: Color,
-    pub patch_binaries_for_nix: bool,
+    pub patch_binaries_for_nix: Option<bool>,
     pub stage0_metadata: Stage0Metadata,
 
     pub stdout_is_tty: bool,
@@ -1276,7 +1276,8 @@ impl Config {
         }
 
         config.initial_rustc = if let Some(rustc) = build.rustc {
-            config.check_build_rustc_version(&rustc);
+            // FIXME(#115065): re-enable this check
+            // config.check_build_rustc_version(&rustc);
             PathBuf::from(rustc)
         } else {
             config.download_beta_toolchain();
@@ -1338,7 +1339,7 @@ impl Config {
         set(&mut config.local_rebuild, build.local_rebuild);
         set(&mut config.print_step_timings, build.print_step_timings);
         set(&mut config.print_step_rusage, build.print_step_rusage);
-        set(&mut config.patch_binaries_for_nix, build.patch_binaries_for_nix);
+        config.patch_binaries_for_nix = build.patch_binaries_for_nix;
 
         config.verbose = cmp::max(config.verbose, flags.verbose as usize);
 
diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs
index a4135b06e9d..17c308e915b 100644
--- a/src/bootstrap/download.rs
+++ b/src/bootstrap/download.rs
@@ -91,8 +91,8 @@ impl Config {
             // NOTE: this intentionally comes after the Linux check:
             // - patchelf only works with ELF files, so no need to run it on Mac or Windows
             // - On other Unix systems, there is no stable syscall interface, so Nix doesn't manage the global libc.
-            if self.patch_binaries_for_nix {
-                return true;
+            if let Some(explicit_value) = self.patch_binaries_for_nix {
+                return explicit_value;
             }
 
             // Use `/etc/os-release` instead of `/etc/NIXOS`.
@@ -105,7 +105,16 @@ impl Config {
                     matches!(l.trim(), "ID=nixos" | "ID='nixos'" | "ID=\"nixos\"")
                 }),
             };
-            is_nixos && !Path::new("/lib").exists()
+            if !is_nixos {
+                let in_nix_shell = env::var("IN_NIX_SHELL");
+                if let Ok(in_nix_shell) = in_nix_shell {
+                    eprintln!(
+                        "The IN_NIX_SHELL environment variable is `{in_nix_shell}`; \
+                         you may need to set `patch-binaries-for-nix=true` in config.toml"
+                    );
+                }
+            }
+            is_nixos
         });
         if val {
             eprintln!("info: You seem to be using Nix.");
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index d0d62db0807..d1018978f78 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -630,6 +630,10 @@ impl Step for Miri {
         cargo.env("MIRI_SYSROOT", &miri_sysroot);
         cargo.env("MIRI_HOST_SYSROOT", sysroot);
         cargo.env("MIRI", &miri);
+        if builder.config.locked_deps {
+            // enforce lockfiles
+            cargo.env("CARGO_EXTRA_FLAGS", "--locked");
+        }
 
         // Set the target.
         cargo.env("MIRI_TEST_TARGET", target.rustc_target_arg());
@@ -675,6 +679,9 @@ impl Step for Miri {
         );
         cargo.add_rustc_lib_path(builder, compiler);
         cargo.arg("--").arg("miri").arg("test");
+        if builder.config.locked_deps {
+            cargo.arg("--locked");
+        }
         cargo
             .arg("--manifest-path")
             .arg(builder.src.join("src/tools/miri/test-cargo-miri/Cargo.toml"));
@@ -1167,6 +1174,11 @@ impl Step for ExpandYamlAnchors {
     /// appropriate configuration for all our CI providers. This step ensures the tool was called
     /// by the user before committing CI changes.
     fn run(self, builder: &Builder<'_>) {
+        // Note: `.github/` is not included in dist-src tarballs
+        if !builder.src.join(".github/workflows/ci.yml").exists() {
+            builder.info("Skipping YAML anchors check: GitHub Actions config not found");
+            return;
+        }
         builder.info("Ensuring the YAML anchors in the GitHub Actions config were expanded");
         builder.run_delaying_failure(
             &mut builder.tool_cmd(Tool::ExpandYamlAnchors).arg("check").arg(&builder.src),
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index e6d27757ac6..07ff3da6b4a 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -601,7 +601,7 @@ pub struct RustAnalyzer {
 }
 
 impl RustAnalyzer {
-    pub const ALLOW_FEATURES: &str =
+    pub const ALLOW_FEATURES: &'static str =
         "proc_macro_internals,proc_macro_diagnostic,proc_macro_span,proc_macro_span_shrink";
 }
 
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
index 377d4a9ce5e..b3c5f41bdd7 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
@@ -13,6 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   sudo \
   bzip2 \
   xz-utils \
+  texinfo \
   wget \
   libssl-dev \
   pkg-config \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
index 9b274cc277e..02b023fe75b 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
@@ -4,7 +4,7 @@ set -ex
 
 source shared.sh
 
-LLVM=llvmorg-16.0.0
+LLVM=llvmorg-17.0.0-rc3
 
 mkdir llvm-project
 cd llvm-project
diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh
index 17cd456b995..0d02636db91 100755
--- a/src/ci/docker/scripts/freebsd-toolchain.sh
+++ b/src/ci/docker/scripts/freebsd-toolchain.sh
@@ -4,7 +4,7 @@
 set -eux
 
 arch=$1
-binutils_version=2.25.1
+binutils_version=2.40
 freebsd_version=12.3
 triple=$arch-unknown-freebsd12
 sysroot=/usr/local/$triple
diff --git a/src/ci/docker/scripts/illumos-toolchain.sh b/src/ci/docker/scripts/illumos-toolchain.sh
index 3f1d5f3426a..0b2c09b3eed 100644
--- a/src/ci/docker/scripts/illumos-toolchain.sh
+++ b/src/ci/docker/scripts/illumos-toolchain.sh
@@ -52,8 +52,8 @@ SYSROOT_URL='https://github.com/illumos/sysroot/releases/download/'
 SYSROOT_URL+="$SYSROOT_VER/$SYSROOT_TAR"
 SYSROOT_DIR="$PREFIX/sysroot"
 
-BINUTILS_VERSION='2.25.1'
-BINUTILS_SUM='b5b14added7d78a8d1ca70b5cb75fef57ce2197264f4f5835326b0df22ac9f22'
+BINUTILS_VERSION='2.40'
+BINUTILS_SUM='f8298eb153a4b37d112e945aa5cb2850040bcf26a3ea65b5a715c83afe05e48a'
 BINUTILS_BASE="binutils-$BINUTILS_VERSION"
 BINUTILS_TAR="$BINUTILS_BASE.tar.bz2"
 BINUTILS_URL="https://ftp.gnu.org/gnu/binutils/$BINUTILS_TAR"
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 371ee378d1a..7cc17e11bdb 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -176,7 +176,6 @@ target | std | notes
 `thumbv8m.base-none-eabi` | * | Bare ARMv8-M Baseline
 `thumbv8m.main-none-eabi` | * | Bare ARMv8-M Mainline
 `thumbv8m.main-none-eabihf` | * | Bare ARMv8-M Mainline, hardfloat
-[`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | Bare 32-bit SPARC V7+
 `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
 `wasm32-unknown-unknown` | ✓ | WebAssembly
 `wasm32-wasi` | ✓ | WebAssembly with WASI
@@ -271,8 +270,8 @@ target | std | host | notes
 `i686-uwp-windows-gnu` | ? |  |
 `i686-uwp-windows-msvc` | ? |  |
 `i686-wrs-vxworks` | ? |  |
-[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI)
-[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI)
+[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64D ABI)
+[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64S 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
@@ -314,6 +313,7 @@ target | std | host | notes
 [`riscv64-linux-android`](platform-support/android.md) |   |   | RISC-V 64-bit Android
 `s390x-unknown-linux-musl` |  |  | S390x Linux (kernel 3.2, MUSL)
 `sparc-unknown-linux-gnu` | ✓ |  | 32-bit SPARC Linux
+[`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | Bare 32-bit SPARC V7+
 [`sparc64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/sparc64
 [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64
 `thumbv4t-none-eabi` | * |  | Thumb-mode Bare ARMv4T
@@ -321,7 +321,7 @@ target | std | host | notes
 `thumbv7a-pc-windows-msvc` | ? |  |
 `thumbv7a-uwp-windows-msvc` | ✓ |  |
 `thumbv7neon-unknown-linux-musleabihf` | ? |  | Thumb2-mode ARMv7-A Linux with NEON, MUSL
-[`wasm32-wasi-preview1-threads`](platform-support/wasm32-wasi-preview1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads
+[`wasm32-wasi-preview1-threads`](platform-support/wasm32-wasi-preview1-threads.md) | ✓ |  | WebAssembly with WASI Preview 1 and threads
 [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? |  | WebAssembly
 `x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
 [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ? | | x86 64-bit tvOS
diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
index 8bc9381342d..f8cd92f9257 100644
--- a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
+++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
@@ -8,6 +8,7 @@ TEEOS is a mini os run in TrustZone, for trusted/security apps. The kernel of TE
 It's very small that there is no RwLock, no network, no stdin, and no file system for apps in TEEOS.
 
 Some abbreviation:
+
 | Abbreviation | The full text | Description |
 |  ----  | ----  | ---- |
 | TEE | Trusted Execution Environment | ARM TrustZone divides the system into two worlds/modes -- the secure world/mode and the normal world/mode. TEE is in the secure world/mode. |
diff --git a/src/doc/rustdoc/src/how-to-write-documentation.md b/src/doc/rustdoc/src/how-to-write-documentation.md
index 1fa9f814476..acab1a93690 100644
--- a/src/doc/rustdoc/src/how-to-write-documentation.md
+++ b/src/doc/rustdoc/src/how-to-write-documentation.md
@@ -254,6 +254,19 @@ characters:
 
 So, no need to manually enter those Unicode characters!
 
+### Adding a warning block
+
+If you want to make a warning or similar note stand out in the documentation,
+you can wrap it like this:
+
+```md
+/// documentation
+///
+/// <div class="warning">A big warning!</div>
+///
+/// more documentation
+```
+
 [`backtrace`]: https://docs.rs/backtrace/0.3.50/backtrace/
 [commonmark markdown specification]: https://commonmark.org/
 [commonmark quick reference]: https://commonmark.org/help/
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index cac21130740..cc86a3d7475 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -80,9 +80,9 @@ pub(crate) fn try_inline(
             clean::UnionItem(build_union(cx, did))
         }
         Res::Def(DefKind::TyAlias { .. }, did) => {
-            record_extern_fqn(cx, did, ItemType::Typedef);
+            record_extern_fqn(cx, did, ItemType::TypeAlias);
             build_impls(cx, did, attrs_without_docs, &mut ret);
-            clean::TypedefItem(build_type_alias(cx, did))
+            clean::TypeAliasItem(build_type_alias(cx, did))
         }
         Res::Def(DefKind::Enum, did) => {
             record_extern_fqn(cx, did, ItemType::Enum);
@@ -287,7 +287,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
     clean::Union { generics, fields }
 }
 
-fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef> {
+fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::TypeAlias> {
     let predicates = cx.tcx.explicit_predicates_of(did);
     let type_ = clean_middle_ty(
         ty::Binder::dummy(cx.tcx.type_of(did).instantiate_identity()),
@@ -296,7 +296,7 @@ fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef>
         None,
     );
 
-    Box::new(clean::Typedef {
+    Box::new(clean::TypeAlias {
         type_,
         generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
         item_type: None,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ee1d0be27bf..1e85284371d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1219,7 +1219,7 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
                     None,
                 );
                 AssocTypeItem(
-                    Box::new(Typedef {
+                    Box::new(TypeAlias {
                         type_: clean_ty(default, cx),
                         generics,
                         item_type: Some(item_type),
@@ -1264,7 +1264,7 @@ pub(crate) fn clean_impl_item<'tcx>(
                     None,
                 );
                 AssocTypeItem(
-                    Box::new(Typedef { type_, generics, item_type: Some(item_type) }),
+                    Box::new(TypeAlias { type_, generics, item_type: Some(item_type) }),
                     Vec::new(),
                 )
             }
@@ -1461,7 +1461,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
 
                 if tcx.defaultness(assoc_item.def_id).has_value() {
                     AssocTypeItem(
-                        Box::new(Typedef {
+                        Box::new(TypeAlias {
                             type_: clean_middle_ty(
                                 ty::Binder::dummy(
                                     tcx.type_of(assoc_item.def_id).instantiate_identity(),
@@ -1480,7 +1480,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
                 }
             } else {
                 AssocTypeItem(
-                    Box::new(Typedef {
+                    Box::new(TypeAlias {
                         type_: clean_middle_ty(
                             ty::Binder::dummy(
                                 tcx.type_of(assoc_item.def_id).instantiate_identity(),
@@ -2617,7 +2617,11 @@ fn clean_maybe_renamed_item<'tcx>(
                         cx.current_type_aliases.remove(&def_id);
                     }
                 }
-                TypedefItem(Box::new(Typedef { type_: rustdoc_ty, generics, item_type: Some(ty) }))
+                TypeAliasItem(Box::new(TypeAlias {
+                    type_: rustdoc_ty,
+                    generics,
+                    item_type: Some(ty),
+                }))
             }
             ItemKind::Enum(ref def, generics) => EnumItem(Enum {
                 variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(),
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 49bde1d3152..9cf3c068b60 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -530,8 +530,8 @@ impl Item {
     pub(crate) fn is_ty_method(&self) -> bool {
         self.type_() == ItemType::TyMethod
     }
-    pub(crate) fn is_typedef(&self) -> bool {
-        self.type_() == ItemType::Typedef
+    pub(crate) fn is_type_alias(&self) -> bool {
+        self.type_() == ItemType::TypeAlias
     }
     pub(crate) fn is_primitive(&self) -> bool {
         self.type_() == ItemType::Primitive
@@ -799,7 +799,7 @@ pub(crate) enum ItemKind {
     EnumItem(Enum),
     FunctionItem(Box<Function>),
     ModuleItem(Module),
-    TypedefItem(Box<Typedef>),
+    TypeAliasItem(Box<TypeAlias>),
     OpaqueTyItem(OpaqueTy),
     StaticItem(Static),
     ConstantItem(Constant),
@@ -832,7 +832,7 @@ pub(crate) enum ItemKind {
     /// The bounds may be non-empty if there is a `where` clause.
     TyAssocTypeItem(Generics, Vec<GenericBound>),
     /// An associated type in a trait impl or a provided one in a trait declaration.
-    AssocTypeItem(Box<Typedef>, Vec<GenericBound>),
+    AssocTypeItem(Box<TypeAlias>, Vec<GenericBound>),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemKind>),
     KeywordItem,
@@ -857,7 +857,7 @@ impl ItemKind {
             ExternCrateItem { .. }
             | ImportItem(_)
             | FunctionItem(_)
-            | TypedefItem(_)
+            | TypeAliasItem(_)
             | OpaqueTyItem(_)
             | StaticItem(_)
             | ConstantItem(_)
@@ -891,7 +891,7 @@ impl ItemKind {
                 | ModuleItem(_)
                 | ExternCrateItem { .. }
                 | FunctionItem(_)
-                | TypedefItem(_)
+                | TypeAliasItem(_)
                 | OpaqueTyItem(_)
                 | StaticItem(_)
                 | ConstantItem(_)
@@ -2230,7 +2230,7 @@ pub(crate) struct PathSegment {
 }
 
 #[derive(Clone, Debug)]
-pub(crate) struct Typedef {
+pub(crate) struct TypeAlias {
     pub(crate) type_: Type,
     pub(crate) generics: Generics,
     /// `type_` can come from either the HIR or from metadata. If it comes from HIR, it may be a type
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 81fb13f4166..1ce7efdfc20 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -273,6 +273,8 @@ pub(crate) struct RenderOptions {
     pub(crate) call_locations: AllCallLocations,
     /// If `true`, Context::init will not emit shared files.
     pub(crate) no_emit_shared: bool,
+    /// If `true`, HTML source code pages won't be generated.
+    pub(crate) html_no_source: bool,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -686,6 +688,7 @@ impl Options {
         let generate_link_to_definition = matches.opt_present("generate-link-to-definition");
         let extern_html_root_takes_precedence =
             matches.opt_present("extern-html-root-takes-precedence");
+        let html_no_source = matches.opt_present("html-no-source");
 
         if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) {
             diag.struct_err(
@@ -769,6 +772,7 @@ impl Options {
             generate_link_to_definition,
             call_locations,
             no_emit_shared: false,
+            html_no_source,
         };
         Ok((options, render_options))
     }
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 656aeefb01a..ceba643ed5f 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -55,7 +55,7 @@ pub(crate) trait DocFolder: Sized {
             ExternCrateItem { src: _ }
             | ImportItem(_)
             | FunctionItem(_)
-            | TypedefItem(_)
+            | TypeAliasItem(_)
             | OpaqueTyItem(_)
             | StaticItem(_)
             | ConstantItem(_)
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index d1deda0c716..9a34e7cce8a 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -389,7 +389,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
         match *item.kind {
             clean::StructItem(..)
             | clean::EnumItem(..)
-            | clean::TypedefItem(..)
+            | clean::TypeAliasItem(..)
             | clean::TraitItem(..)
             | clean::TraitAliasItem(..)
             | clean::FunctionItem(..)
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index a788935581f..fd79160ff4a 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -29,7 +29,7 @@ pub(crate) enum ItemType {
     Struct = 3,
     Enum = 4,
     Function = 5,
-    Typedef = 6,
+    TypeAlias = 6,
     Static = 7,
     Trait = 8,
     Impl = 9,
@@ -75,7 +75,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
             clean::UnionItem(..) => ItemType::Union,
             clean::EnumItem(..) => ItemType::Enum,
             clean::FunctionItem(..) => ItemType::Function,
-            clean::TypedefItem(..) => ItemType::Typedef,
+            clean::TypeAliasItem(..) => ItemType::TypeAlias,
             clean::OpaqueTyItem(..) => ItemType::OpaqueTy,
             clean::StaticItem(..) => ItemType::Static,
             clean::ConstantItem(..) => ItemType::Constant,
@@ -115,7 +115,7 @@ impl From<DefKind> for ItemType {
             DefKind::Struct => Self::Struct,
             DefKind::Union => Self::Union,
             DefKind::Trait => Self::Trait,
-            DefKind::TyAlias { .. } => Self::Typedef,
+            DefKind::TyAlias { .. } => Self::TypeAlias,
             DefKind::TraitAlias => Self::TraitAlias,
             DefKind::Macro(kind) => match kind {
                 MacroKind::Bang => ItemType::Macro,
@@ -156,7 +156,7 @@ impl ItemType {
             ItemType::Union => "union",
             ItemType::Enum => "enum",
             ItemType::Function => "fn",
-            ItemType::Typedef => "type",
+            ItemType::TypeAlias => "type",
             ItemType::Static => "static",
             ItemType::Trait => "trait",
             ItemType::Impl => "impl",
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index d7ff248a9bf..bb1c186668c 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -463,6 +463,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             generate_link_to_definition,
             call_locations,
             no_emit_shared,
+            html_no_source,
             ..
         } = options;
 
@@ -488,7 +489,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             scrape_examples_extension: !call_locations.is_empty(),
         };
         let mut issue_tracker_base_url = None;
-        let mut include_sources = true;
+        let mut include_sources = !html_no_source;
 
         // Crawl the crate attributes looking for attributes which control how we're
         // going to emit HTML
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index ac9c180a6a8..aef8f1a74fb 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -235,7 +235,7 @@ struct AllTypes {
     traits: FxHashSet<ItemEntry>,
     macros: FxHashSet<ItemEntry>,
     functions: FxHashSet<ItemEntry>,
-    typedefs: FxHashSet<ItemEntry>,
+    type_aliases: FxHashSet<ItemEntry>,
     opaque_tys: FxHashSet<ItemEntry>,
     statics: FxHashSet<ItemEntry>,
     constants: FxHashSet<ItemEntry>,
@@ -255,7 +255,7 @@ impl AllTypes {
             traits: new_set(100),
             macros: new_set(100),
             functions: new_set(100),
-            typedefs: new_set(100),
+            type_aliases: new_set(100),
             opaque_tys: new_set(100),
             statics: new_set(100),
             constants: new_set(100),
@@ -279,7 +279,7 @@ impl AllTypes {
                 ItemType::Trait => self.traits.insert(ItemEntry::new(new_url, name)),
                 ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)),
                 ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)),
-                ItemType::Typedef => self.typedefs.insert(ItemEntry::new(new_url, name)),
+                ItemType::TypeAlias => self.type_aliases.insert(ItemEntry::new(new_url, name)),
                 ItemType::OpaqueTy => self.opaque_tys.insert(ItemEntry::new(new_url, name)),
                 ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)),
                 ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
@@ -317,8 +317,8 @@ impl AllTypes {
         if !self.functions.is_empty() {
             sections.insert(ItemSection::Functions);
         }
-        if !self.typedefs.is_empty() {
-            sections.insert(ItemSection::TypeDefinitions);
+        if !self.type_aliases.is_empty() {
+            sections.insert(ItemSection::TypeAliases);
         }
         if !self.opaque_tys.is_empty() {
             sections.insert(ItemSection::OpaqueTypes);
@@ -374,7 +374,7 @@ impl AllTypes {
         print_entries(f, &self.attribute_macros, ItemSection::AttributeMacros);
         print_entries(f, &self.derive_macros, ItemSection::DeriveMacros);
         print_entries(f, &self.functions, ItemSection::Functions);
-        print_entries(f, &self.typedefs, ItemSection::TypeDefinitions);
+        print_entries(f, &self.type_aliases, ItemSection::TypeAliases);
         print_entries(f, &self.trait_aliases, ItemSection::TraitAliases);
         print_entries(f, &self.opaque_tys, ItemSection::OpaqueTypes);
         print_entries(f, &self.statics, ItemSection::Statics);
@@ -1237,7 +1237,7 @@ fn render_deref_methods(
         .iter()
         .find_map(|item| match *item.kind {
             clean::AssocTypeItem(box ref t, _) => Some(match *t {
-                clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
+                clean::TypeAlias { item_type: Some(ref type_), .. } => (type_, &t.type_),
                 _ => (&t.type_, &t.type_),
             }),
             _ => None,
@@ -2035,7 +2035,7 @@ pub(crate) enum ItemSection {
     Statics,
     Traits,
     Functions,
-    TypeDefinitions,
+    TypeAliases,
     Unions,
     Implementations,
     TypeMethods,
@@ -2067,7 +2067,7 @@ impl ItemSection {
             Statics,
             Traits,
             Functions,
-            TypeDefinitions,
+            TypeAliases,
             Unions,
             Implementations,
             TypeMethods,
@@ -2093,7 +2093,7 @@ impl ItemSection {
             Self::Unions => "unions",
             Self::Enums => "enums",
             Self::Functions => "functions",
-            Self::TypeDefinitions => "types",
+            Self::TypeAliases => "types",
             Self::Statics => "statics",
             Self::Constants => "constants",
             Self::Traits => "traits",
@@ -2123,7 +2123,7 @@ impl ItemSection {
             Self::Unions => "Unions",
             Self::Enums => "Enums",
             Self::Functions => "Functions",
-            Self::TypeDefinitions => "Type Definitions",
+            Self::TypeAliases => "Type Aliases",
             Self::Statics => "Statics",
             Self::Constants => "Constants",
             Self::Traits => "Traits",
@@ -2154,7 +2154,7 @@ fn item_ty_to_section(ty: ItemType) -> ItemSection {
         ItemType::Union => ItemSection::Unions,
         ItemType::Enum => ItemSection::Enums,
         ItemType::Function => ItemSection::Functions,
-        ItemType::Typedef => ItemSection::TypeDefinitions,
+        ItemType::TypeAlias => ItemSection::TypeAliases,
         ItemType::Static => ItemSection::Statics,
         ItemType::Constant => ItemSection::Constants,
         ItemType::Trait => ItemSection::Traits,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 6cab3498622..cb78f903462 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -198,7 +198,7 @@ pub(super) fn print_item(
         clean::StructItem(..) => "Struct ",
         clean::UnionItem(..) => "Union ",
         clean::EnumItem(..) => "Enum ",
-        clean::TypedefItem(..) => "Type Definition ",
+        clean::TypeAliasItem(..) => "Type Alias ",
         clean::MacroItem(..) => "Macro ",
         clean::ProcMacroItem(ref mac) => match mac.kind {
             MacroKind::Bang => "Macro ",
@@ -273,7 +273,7 @@ pub(super) fn print_item(
         clean::StructItem(ref s) => item_struct(buf, cx, item, s),
         clean::UnionItem(ref s) => item_union(buf, cx, item, s),
         clean::EnumItem(ref e) => item_enum(buf, cx, item, e),
-        clean::TypedefItem(ref t) => item_typedef(buf, cx, item, t),
+        clean::TypeAliasItem(ref t) => item_type_alias(buf, cx, item, t),
         clean::MacroItem(ref m) => item_macro(buf, cx, item, m),
         clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
         clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
@@ -343,7 +343,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
             ItemType::Static => 8,
             ItemType::Trait => 9,
             ItemType::Function => 10,
-            ItemType::Typedef => 12,
+            ItemType::TypeAlias => 12,
             ItemType::Union => 13,
             _ => 14 + ty as u8,
         }
@@ -1217,8 +1217,8 @@ fn item_opaque_ty(
         .unwrap();
 }
 
-fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Typedef) {
-    fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
+fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
+    fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
         wrap_item(w, |w| {
             write!(
                 w,
diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs
index f3da610565c..b96b1536156 100644
--- a/src/librustdoc/html/render/sidebar.rs
+++ b/src/librustdoc/html/render/sidebar.rs
@@ -82,7 +82,7 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
         clean::PrimitiveItem(_) => sidebar_primitive(cx, it),
         clean::UnionItem(ref u) => sidebar_union(cx, it, u),
         clean::EnumItem(ref e) => sidebar_enum(cx, it, e),
-        clean::TypedefItem(_) => sidebar_typedef(cx, it),
+        clean::TypeAliasItem(_) => sidebar_type_alias(cx, it),
         clean::ModuleItem(ref m) => vec![sidebar_module(&m.items)],
         clean::ForeignTypeItem => sidebar_foreign_type(cx, it),
         _ => vec![],
@@ -100,7 +100,7 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
         || it.is_union()
         || it.is_enum()
         || it.is_mod()
-        || it.is_typedef()
+        || it.is_type_alias()
     {
         (
             match *it.kind {
@@ -230,7 +230,7 @@ fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBl
     }
 }
 
-fn sidebar_typedef<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> {
+fn sidebar_type_alias<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> {
     let mut items = vec![];
     sidebar_assoc_items(cx, it, &mut items);
     items
@@ -334,7 +334,7 @@ fn sidebar_deref_methods<'a>(
     if let Some((target, real_target)) =
         impl_.inner_impl().items.iter().find_map(|item| match *item.kind {
             clean::AssocTypeItem(box ref t, _) => Some(match *t {
-                clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
+                clean::TypeAlias { item_type: Some(ref type_), .. } => (type_, &t.type_),
                 _ => (&t.type_, &t.type_),
             }),
             _ => None,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index b1de8c1529e..da4da50106a 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -270,7 +270,7 @@ ul ul, ol ul, ul ol, ol ol {
 	margin-bottom: .625em;
 }
 
-p {
+p, .docblock > .warning {
 	/* Paragraph spacing at least 1.5 times line spacing per Web Content Accessibility Guidelines.
 	   Line-height is 1.5rem, so line spacing is .5rem; .75em is 1.5 times that.
 	   https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html */
@@ -278,7 +278,7 @@ p {
 }
 /* For the last child of a div, the margin will be taken care of
 	by the margin-top of the next item. */
-p:last-child {
+p:last-child, .docblock > .warning:last-child {
 	margin: 0;
 }
 
@@ -1096,7 +1096,7 @@ pre.rust .doccomment {
 }
 
 .example-wrap.ignore .tooltip {
-	color:  var(--codeblock-ignore-color);
+	color: var(--codeblock-ignore-color);
 }
 
 .example-wrap.compile_fail:hover .tooltip,
@@ -1124,6 +1124,26 @@ pre.rust .doccomment {
 	font-size: 1.25rem;
 }
 
+/* This class only exists for users who want to draw attention to a particular element in their
+documentation. */
+.content .docblock .warning {
+	border-left: 2px solid var(--warning-border-color);
+	padding: 14px;
+	position: relative;
+	/* The "!important" part is required because the rule is otherwise overruled in this CSS
+	selector: ".docblock > :not(.more-examples-toggle):not(.example-wrap)" */
+	overflow-x: visible !important;
+}
+.content .docblock .warning::before {
+	color: var(--warning-border-color);
+	content: "ⓘ";
+	position: absolute;
+	left: -25px;
+	top: 5px;
+	font-weight: bold;
+	font-size: 1.25rem;
+}
+
 a.test-arrow {
 	visibility: hidden;
 	position: absolute;
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index d8dae51eb1b..c81a80eeca0 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -31,6 +31,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
 	--codeblock-ignore-color: rgba(255, 142, 0, .6);
+	--warning-border-color: rgb(255, 142, 0);
 	--type-link-color: #ffa0a5;
 	--trait-link-color: #39afd7;
 	--assoc-item-link-color: #39afd7;
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 2b302988734..0f8b1dc24a6 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -26,6 +26,7 @@
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
 	--codeblock-ignore-color: rgba(255, 142, 0, .6);
+	--warning-border-color: rgb(255, 142, 0);
 	--type-link-color: #2dbfb8;
 	--trait-link-color: #b78cf2;
 	--assoc-item-link-color: #d2991d;
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 56fd8cbef12..39ea44a1165 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -26,6 +26,7 @@
 	--codeblock-error-color: rgba(255, 0, 0, .5);
 	--codeblock-ignore-hover-color: rgb(255, 142, 0);
 	--codeblock-ignore-color: rgba(255, 142, 0, .6);
+	--warning-border-color: rgb(255, 142, 0);
 	--type-link-color: #ad378a;
 	--trait-link-color: #6e4fc9;
 	--assoc-item-link-color: #3873ad;
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 254b0d8bf5a..cb653d6b8df 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -499,7 +499,7 @@ function preLoadCss(cssUrl) {
             block("static", "static", "Statics");
             block("trait", "traits", "Traits");
             block("fn", "functions", "Functions");
-            block("type", "types", "Type Definitions");
+            block("type", "types", "Type Aliases");
             block("foreigntype", "foreign-types", "Foreign Types");
             block("keyword", "keywords", "Keywords");
             block("traitalias", "trait-aliases", "Trait Aliases");
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 8673138f649..66b5798797f 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -311,7 +311,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
         StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
         ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
         ForeignTypeItem => ItemEnum::ForeignType,
-        TypedefItem(t) => ItemEnum::Typedef(t.into_tcx(tcx)),
+        TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_tcx(tcx)),
         OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into_tcx(tcx)),
         ConstantItem(c) => ItemEnum::Constant(c.into_tcx(tcx)),
         MacroItem(m) => ItemEnum::Macro(m.source),
@@ -787,10 +787,10 @@ pub(crate) fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind
     }
 }
 
-impl FromWithTcx<Box<clean::Typedef>> for Typedef {
-    fn from_tcx(typedef: Box<clean::Typedef>, tcx: TyCtxt<'_>) -> Self {
-        let clean::Typedef { type_, generics, item_type: _ } = *typedef;
-        Typedef { type_: type_.into_tcx(tcx), generics: generics.into_tcx(tcx) }
+impl FromWithTcx<Box<clean::TypeAlias>> for TypeAlias {
+    fn from_tcx(type_alias: Box<clean::TypeAlias>, tcx: TyCtxt<'_>) -> Self {
+        let clean::TypeAlias { type_, generics, item_type: _ } = *type_alias;
+        TypeAlias { type_: type_.into_tcx(tcx), generics: generics.into_tcx(tcx) }
     }
 }
 
@@ -827,7 +827,7 @@ impl FromWithTcx<ItemType> for ItemKind {
             Union => ItemKind::Union,
             Enum => ItemKind::Enum,
             Function | TyMethod | Method => ItemKind::Function,
-            Typedef => ItemKind::Typedef,
+            TypeAlias => ItemKind::TypeAlias,
             OpaqueTy => ItemKind::OpaqueTy,
             Static => ItemKind::Static,
             Constant => ItemKind::Constant,
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index cd791ce000b..27e8a27ba2f 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -184,7 +184,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 | types::ItemEnum::Variant(_)
                 | types::ItemEnum::TraitAlias(_)
                 | types::ItemEnum::Impl(_)
-                | types::ItemEnum::Typedef(_)
+                | types::ItemEnum::TypeAlias(_)
                 | types::ItemEnum::OpaqueTy(_)
                 | types::ItemEnum::Constant(_)
                 | types::ItemEnum::Static(_)
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8220df5d4f3..92e06f3ab0f 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -656,6 +656,9 @@ fn opts() -> Vec<RustcOptGroup> {
                 "[rust]",
             )
         }),
+        unstable("html-no-source", |o| {
+            o.optflag("", "html-no-source", "Disable HTML source code pages generation")
+        }),
     ]
 }
 
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index e732a405760..96224d7c6e2 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -60,7 +60,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
                 | clean::VariantItem(_)
                 | clean::AssocConstItem(..)
                 | clean::AssocTypeItem(..)
-                | clean::TypedefItem(_)
+                | clean::TypeAliasItem(_)
                 | clean::StaticItem(_)
                 | clean::ConstantItem(_)
                 | clean::ExternCrateItem { .. }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 36872266ee1..7b0a7a90d31 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1430,20 +1430,15 @@ impl LinkCollector<'_, '_> {
         // Otherwise, check if 2 links are same, if so, skip the resolve process.
         //
         // Notice that this algorithm is passive, might possibly miss actual redudant cases.
-        let explicit_link = &explicit_link.to_string();
+        let explicit_link = explicit_link.to_string();
         let display_text = ori_link.display_text.as_ref().unwrap();
-        let display_len = display_text.len();
-        let explicit_len = explicit_link.len();
 
-        if display_len == explicit_len {
+        if display_text.len() == explicit_link.len() {
             // Whether they are same or not, skip the resolve process.
             return;
         }
 
-        if (explicit_len >= display_len
-            && &explicit_link[(explicit_len - display_len)..] == display_text)
-            || (display_len >= explicit_len
-                && &display_text[(display_len - explicit_len)..] == explicit_link)
+        if explicit_link.ends_with(&display_text[..]) || display_text.ends_with(&explicit_link[..])
         {
             self.resolve_with_disambiguator_cached(
                 display_res_info,
diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs
index ef0f8716aa8..67cd2cc9732 100644
--- a/src/librustdoc/passes/lint/redundant_explicit_links.rs
+++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs
@@ -98,13 +98,8 @@ fn check_redundant_explicit_link<'md>(
 
                 let explicit_link = dest.to_string();
                 let display_link = link_data.resolvable_link.clone()?;
-                let explicit_len = explicit_link.len();
-                let display_len = display_link.len();
 
-                if (explicit_len >= display_len
-                    && &explicit_link[(explicit_len - display_len)..] == display_link)
-                    || (display_len >= explicit_len
-                        && &display_link[(display_len - explicit_len)..] == explicit_link)
+                if explicit_link.ends_with(&display_link) || display_link.ends_with(&explicit_link)
                 {
                     match link_type {
                         LinkType::Inline | LinkType::ReferenceUnknown => {
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 64a4ace5b9f..b3561841594 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -49,7 +49,7 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
             }
             // These items can all get re-exported
             clean::OpaqueTyItem(..)
-            | clean::TypedefItem(..)
+            | clean::TypeAliasItem(..)
             | clean::StaticItem(..)
             | clean::StructItem(..)
             | clean::EnumItem(..)
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs
index 390b9436121..01e6cb4b93b 100644
--- a/src/librustdoc/visit.rs
+++ b/src/librustdoc/visit.rs
@@ -25,7 +25,7 @@ pub(crate) trait DocVisitor: Sized {
             ExternCrateItem { src: _ }
             | ImportItem(_)
             | FunctionItem(_)
-            | TypedefItem(_)
+            | TypeAliasItem(_)
             | OpaqueTyItem(_)
             | StaticItem(_)
             | ConstantItem(_)
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 1833c2be108aefcb5d25f6280cf9763b1feb800
+Subproject 50eecd007f6bf135ad60493bc62102739038d59
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index ba8eeaa6682..5d979521885 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 = 26;
+pub const FORMAT_VERSION: u32 = 27;
 
 /// 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
@@ -203,7 +203,7 @@ pub enum ItemKind {
     Enum,
     Variant,
     Function,
-    Typedef,
+    TypeAlias,
     OpaqueTy,
     Constant,
     Trait,
@@ -242,7 +242,7 @@ pub enum ItemEnum {
     TraitAlias(TraitAlias),
     Impl(Impl),
 
-    Typedef(Typedef),
+    TypeAlias(TypeAlias),
     OpaqueTy(OpaqueTy),
     Constant(Constant),
 
@@ -696,7 +696,7 @@ pub enum MacroKind {
 }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
-pub struct Typedef {
+pub struct TypeAlias {
     #[serde(rename = "type")]
     pub type_: Type,
     pub generics: Generics,
diff --git a/src/stage0.json b/src/stage0.json
index 5f54504b8ea..201f9a0c612 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -17,379 +17,381 @@
     "tool is executed."
   ],
   "compiler": {
-    "date": "2023-07-12",
+    "date": "2023-08-22",
     "version": "beta"
   },
   "rustfmt": {
-    "date": "2023-07-13",
+    "date": "2023-08-22",
     "version": "nightly"
   },
   "checksums_sha256": {
-    "dist/2023-07-12/cargo-beta-aarch64-apple-darwin.tar.gz": "2abd085e1805419ca8ae0227f7f974790beac8f4f0dcfaa6e57857f6b79a96b3",
-    "dist/2023-07-12/cargo-beta-aarch64-apple-darwin.tar.xz": "f28bfa89ae8b20a06a90fcb2a34840a8473c504986742ff111e4c0722507ce35",
-    "dist/2023-07-12/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "50206cd7b01c9f978f433660c30de8b3f8799eb19ef371e88236065719732322",
-    "dist/2023-07-12/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "6359961e60f32569af03bdddc0e6e996f0b22d124a3c21272a44c0e1cd5ce414",
-    "dist/2023-07-12/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "be5e354a88c9ca8cb696d7383670279d8933f1bf4bf1599a5c4f17d884b05707",
-    "dist/2023-07-12/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "6180ee4c1087044ba9e1c7b8ddc289b75824e34ed88dd153b63ee8674d8b3405",
-    "dist/2023-07-12/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "9632cff665c36d62eeae355e9322c3bea2bc09efd6fadf49dca603bd54545c6f",
-    "dist/2023-07-12/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "b91560ef397310ffd96179201b696b8eeb4713787174b37517aa043690740dbc",
-    "dist/2023-07-12/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "d0654b7f734262cd7d6bb8924a063f9f48f2510f8a5a58d050efba90fde40204",
-    "dist/2023-07-12/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "6271ded5e5e50697626d67f0d6faa54f0d0daa6aa61a3e98354c62a74f1bb87e",
-    "dist/2023-07-12/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "6a9b804c6217f8a76d72fc10a7b9566d00c36dff5eb9df238c56bc7d26b4f0d0",
-    "dist/2023-07-12/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "f2b67e0a7bd0b304f89e4b938c46c7551f34f40d87f0909a07363fcd903ab3b9",
-    "dist/2023-07-12/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "c0fbf9d4d7638dc4ae6cc5d136a69cbce0ec5c3c31bd8103a6e2783c27690b0d",
-    "dist/2023-07-12/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "cb67aea7aa1295d5bdfbfde784300b779a7bc350af864bc2ee8d7b268648c6e5",
-    "dist/2023-07-12/cargo-beta-i686-pc-windows-gnu.tar.gz": "4a4bfb185e226d1b6c310fc25ff5b13bab088fa4d98425b90878aa0446ee22bf",
-    "dist/2023-07-12/cargo-beta-i686-pc-windows-gnu.tar.xz": "d265ad80a372223d9c99a1d3232d379287d847ea1c3afde29f320d3950198e9b",
-    "dist/2023-07-12/cargo-beta-i686-pc-windows-msvc.tar.gz": "6c566bdb668e6ac7b068c285b7fe2e3cf7d0f4f065663165f2a9e4256b78e4cf",
-    "dist/2023-07-12/cargo-beta-i686-pc-windows-msvc.tar.xz": "c70d668d38fe9946a887ab18bb08ca74d2a8e36f6ead9d78deae55b532abef34",
-    "dist/2023-07-12/cargo-beta-i686-unknown-linux-gnu.tar.gz": "82d996b76d6ce55d64c82a33d3278c609bcbbef854c94d98cd4c5290958d542f",
-    "dist/2023-07-12/cargo-beta-i686-unknown-linux-gnu.tar.xz": "cf06a97a9e60e8936482da06a659f3eb4133d0ea3b5498e45b160fbd513e3d2e",
-    "dist/2023-07-12/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "816c8112da3efdc27e8930944a6560ae8e8597755af22d8af4b2bbe910f08a93",
-    "dist/2023-07-12/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "c59fc50e68d9d2afbc725ea420db701593bfa074abd7b97e3c7dfc676e0647b0",
-    "dist/2023-07-12/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "d7327116f5fc8ab665fdb086fda93af287de6ff91c2762e1867b0e40acda231a",
-    "dist/2023-07-12/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "24ec8fd09995c20e216b071c86405b0e3a1cd038c66700b47321188d09cb83a0",
-    "dist/2023-07-12/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "f937ff68855c59bafb3412761cf8f6a0c0d91c9729000a4ea58eed53569803b3",
-    "dist/2023-07-12/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "b51d94d00ce0af91a8abe2ea152b2331689fc1799d212c11ac4ca0fc4dca652c",
-    "dist/2023-07-12/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "5ed88bc49511d1e2496eab00ef4ea5677868113e83aac6e1e61fdb5b9f56f1b5",
-    "dist/2023-07-12/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "a5b9594e97947abba39877fb0e99bf329d5447e7a7d557dab994c24e381ced12",
-    "dist/2023-07-12/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "c269533aeec8a1cdc25e3a3057ea8c9da571d7f3617cba9f1fe0c4193ab38f70",
-    "dist/2023-07-12/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "7094f76b4f7d1d1d34a5214b531ccecca4b2ad09fb23b534d334bece2718c78c",
-    "dist/2023-07-12/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "012a515e3acab001cd72ef38144edd0372a6d813912990dc5409f340bd4856e8",
-    "dist/2023-07-12/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "fceb8dc2356b8dfa4009e60d8a0742c940553beed385a0b6ba1526fc329f36cc",
-    "dist/2023-07-12/cargo-beta-x86_64-apple-darwin.tar.gz": "5dd74b549dd46809b8f56d8ed5052303bd64b14f5583bc89379624f6a22836b4",
-    "dist/2023-07-12/cargo-beta-x86_64-apple-darwin.tar.xz": "f0b33f85cd5585e272a90736e3d188d7f53886a97a75aaae5f4d6dda85867baa",
-    "dist/2023-07-12/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "be049bb6fc3f7b079b425ecd8fcbeae3cae29c8a32a290f70d5f2a7522d67b87",
-    "dist/2023-07-12/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "b04f7c83691abcefb5fb985013ec8d98fe4ce773d0b3291127efb1b00a7ab08e",
-    "dist/2023-07-12/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "c1b853dec72570534a64c7f94e0008057a2365b0f060d17b84bdef19080b6bbb",
-    "dist/2023-07-12/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "146d305a0fc14a1b7bb6586dd3130d09b72d2497ddbc10c3e739444bded037ca",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-freebsd.tar.gz": "235948cf05dcfef80e21e66f5b08ddab18eb8f14b2ea8fcbeed22cdad8611868",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-freebsd.tar.xz": "28008794b923bb103f46a0a24bf66ce5f43a647ed5b4fefc649b8734a2f80ffb",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-illumos.tar.gz": "7d6a9f53a0e5758e7155c7cba0385c6ab7e0cee7f98a62172c108dca909a2188",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-illumos.tar.xz": "3314f50099b488cd027074241bde9fa0a12a6ca6f14afa9f0db5dd62080c318c",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "2632324d31641f783528bbfa98b6b16738d4ba59933a7919360bde5279092c5a",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "0057a55a30c38002b03c032a0f742dd326236f25b67b3c3d791661ef6f653c1b",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "03b787105749e431e1c043fe7e019984a602a6a7ec382f78e1b960a5fe7466d9",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "5ccf1875d484d41a8e6828f4c96d1915c644e99369dae73a161fd10a97937ff6",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-netbsd.tar.gz": "2df957be57157dc20ee4ec1434c5c8ef57b2f61d9ca681510f9cac397cd31f8d",
-    "dist/2023-07-12/cargo-beta-x86_64-unknown-netbsd.tar.xz": "5cecc38b971653fc6ae1f393080723350dde6e17597f2da6bb76788f23402bf4",
-    "dist/2023-07-12/rust-std-beta-aarch64-apple-darwin.tar.gz": "e6008a3c5b826be78f6dbde565c0b148339d7e37bec0adde575e91a065903955",
-    "dist/2023-07-12/rust-std-beta-aarch64-apple-darwin.tar.xz": "735118e8d1ab40d504e345e0b5d844b90d0b04689ff4f5dda9c6f141944eb9af",
-    "dist/2023-07-12/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "7b930f3a915d98be424d7ccde639f0350cdfb97422367b8a336f5688704ecf35",
-    "dist/2023-07-12/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "4dd1e2ff92a85a76108d2f90b37245f7851c214454386aed053b528a31d0f46b",
-    "dist/2023-07-12/rust-std-beta-aarch64-apple-ios.tar.gz": "8415958461754cb3f9e86e9f47f2bbd26395e89a9bbbc21dbc54572a59c72b24",
-    "dist/2023-07-12/rust-std-beta-aarch64-apple-ios.tar.xz": "e88fd506a62568b49a5be056e9aeb4a9db6833216cf68adafc24769b0942eb4a",
-    "dist/2023-07-12/rust-std-beta-aarch64-linux-android.tar.gz": "41489a5701378265ace4a15b7ea9107fc5579c0bc3967e075e4c8769d3b0ac61",
-    "dist/2023-07-12/rust-std-beta-aarch64-linux-android.tar.xz": "86bb3088f26f3fd9c83220ea6d39135fc002d36696dc15c56d754065b13105c3",
-    "dist/2023-07-12/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "621bfd6e6253f35fe78321f3f8f45cd2fb0e290502f4b659d75b9e401a5b06da",
-    "dist/2023-07-12/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "2fb251d461489dfa8721ef12ff212aa77fc9a0a6e6952c22cdb8ff36eee39fe2",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "879f1ab511497baeb614d263e6bcb105bd084c8aa190ffbdd565fd14c87c7a48",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "c40816547ad6ecac58c13c21540239c7ba87b4970a2bbc2f3d9c64aef1f22f82",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "d53b23527d184087adb14574b4a1f2a4e1fa387a271c080af2c7aa96c0ef2033",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "7122261bd5a72b8426d2325a88fda0983e24cf58882c24eea85ab9f8861fecf7",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "6b5326823ce3564f9f67db5d9193349df8001adec9849b7bdf01ea06b342f5b3",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "10a89967e1600ac7e857715c9d61991710b88dfa3da8b117fc5be2c2fac26859",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "ddd5ed0c6aa3499f40e9ce18a43627f8e1f33be3ac056d109045d2df65128cca",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "c6c61e5e2fe43ade33fb21683d382d4f101071e14dd18f4dec5b16b792b35850",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-none.tar.gz": "1cff4acc6b0889450c00a67dec433f274c6f141bd047ff530f573d46a3bcaaff",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-none.tar.xz": "1528aada81564d7359bc80f6c15e98e29d1685057ba83e57ef59952e870a1042",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-uefi.tar.gz": "e2e2fc8f4b037fda67a80024b6fe73f5b616376b4def317ccd6e78e2b4776859",
-    "dist/2023-07-12/rust-std-beta-aarch64-unknown-uefi.tar.xz": "3ecfd0f3ecbd2bb5e4bbed886d127fa33893360f898041a384afef4629693dbd",
-    "dist/2023-07-12/rust-std-beta-arm-linux-androideabi.tar.gz": "0be665812e347a20cc097918e362904088afcc8b45c741b1da29f9e991d9c3d0",
-    "dist/2023-07-12/rust-std-beta-arm-linux-androideabi.tar.xz": "9a65ff8ec3a03afd1cf5bba933eaa602e3e9f29a003be9f8835b21c2e5b8d26a",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "5e1387faf662f7c227b075cc5b860f064864a1ebd1ce85ab5840fb136f38ff69",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "4bb9dc22d45b34620120ab5f4aacd2799181f4bb006f40a83cead84b582ed669",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "d7996b74fe236e453bff636361389f6183194784f4b997d144fd456d4b55257e",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "578a99158925d329a57b74d82524d3c97fef1d9a801c39f5b03366aa60d217a6",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "a02bbe42972483d2ff5b26e1948f9d5d3c9512019f5cba0514b57a248847afc3",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "37fcc7982aabbd77c76f1886feaac1fc87fc4a1ad35edb80a5be381c88f65125",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "52622b53c8fa0d16090d59543432e7d531f7eb6812730b79aeb96a8d1c993290",
-    "dist/2023-07-12/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "a5af3735e6337c79c45a1b0d538c3627cd89ddd4d5d40d75e711d86004dbfe8b",
-    "dist/2023-07-12/rust-std-beta-armebv7r-none-eabi.tar.gz": "8fd0e463083548198255142e617a726f2b6a055665e534755e8b879e420041fc",
-    "dist/2023-07-12/rust-std-beta-armebv7r-none-eabi.tar.xz": "2b407208e51a8f3f82ede1a98ec33d12345f3c7f2ae1ddf25232dcd30aca915e",
-    "dist/2023-07-12/rust-std-beta-armebv7r-none-eabihf.tar.gz": "57ea6af7f77135d9f5d8541139caa562d8901a167e77e3de0a75b427090a60ce",
-    "dist/2023-07-12/rust-std-beta-armebv7r-none-eabihf.tar.xz": "7a14e34060161073191d858c2450b5dd69d827261c6fc5f56a003753232bec32",
-    "dist/2023-07-12/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "03d0ba0d24e07788aa7fb9c85515f82a697fb224a52a904f96970f8f329849e1",
-    "dist/2023-07-12/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "fb55245b1c7e6f074d8120d7b28e25a6882a3ef8c8afe4c7601078f385644eda",
-    "dist/2023-07-12/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "d1fb9a2001db3060ceb6d6deb0e0f35db7da5d47b0d174c2f4d5ba9a82ad22f1",
-    "dist/2023-07-12/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "8e0ec621b890b455988a931bc8eabc96840faf2fc7b311776aa06a1b55a4f554",
-    "dist/2023-07-12/rust-std-beta-armv7-linux-androideabi.tar.gz": "96d01a8dc88041d804e33fcca5d64ca10503a855a394606533aacc1e142289e1",
-    "dist/2023-07-12/rust-std-beta-armv7-linux-androideabi.tar.xz": "75c42686a8f379f19971235855e24ae7ce0b5d91768c00532857d304f45e5cef",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "a097e5fdd835551e969c4e1d6cf767633d79101709362a9a26d3056bf8ecd32c",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "f056e2c6cbb40ba34598a60901c959b828d086a84ceba03f9eaa3d7f48b7c6c6",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "1995003b8ef8ee5dbee66d46a1233d6fe0182ccb6b9c14c976cc40e5099324ef",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "08d9e6293cd3a89d6e42b0939c668a58ac010603fd4eee9775dde468a33bd0dd",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "092d13520760e9540663ffc08e17be223a815e2dd7c0899033fe6676edb74264",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "9e7d6923f8c90c779767eb40a55ef958420737679a5065e2a5ca49a6e34dacc5",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "c232cde2921c0c2d1a0f8fab64ddcae2b7dd7ed5cbf180370ece302949826a88",
-    "dist/2023-07-12/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "7681e242675bb765a1aacd3c8ebc6894eeb709ce7d85e5ff94cd63e52eb4e989",
-    "dist/2023-07-12/rust-std-beta-armv7a-none-eabi.tar.gz": "4a777b4a7e8b157d78aaab73ae4e9185821a7887dbad68612db3b5bd7428729b",
-    "dist/2023-07-12/rust-std-beta-armv7a-none-eabi.tar.xz": "d823b49c8d4b2615223b68cf6b6ac22836551aa5c1df0f68e1336c2be7ffe7ec",
-    "dist/2023-07-12/rust-std-beta-armv7r-none-eabi.tar.gz": "12e8242d480dc45108e615cb5625a07b77054a88fff72dce51c313e57a3ec8ef",
-    "dist/2023-07-12/rust-std-beta-armv7r-none-eabi.tar.xz": "0cef6562f5ee0850fdfbf0be00e18a5643a951d169df00b4e068c932fe04b048",
-    "dist/2023-07-12/rust-std-beta-armv7r-none-eabihf.tar.gz": "71818e3855455bf6cc3fc2f04b7ebbf95e32f28f636d08d9513ab1be88aece49",
-    "dist/2023-07-12/rust-std-beta-armv7r-none-eabihf.tar.xz": "b4bcb177e8fb157e50b93e07144889127b218804ede359d542ccdb0a0fc8a4a0",
-    "dist/2023-07-12/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "d16b2accc56ee37e2e527e0371a689530d30a6ff316bbb85664710419a5effca",
-    "dist/2023-07-12/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "6b828e1b7941d6a9ed085051c378227c99ebc5b4899dfd222c368b2edaa6f7fd",
-    "dist/2023-07-12/rust-std-beta-i586-pc-windows-msvc.tar.gz": "d35e870fb7cda230cebf82d6e4241f0535e534c861fed1a5158f47f8a18bb33b",
-    "dist/2023-07-12/rust-std-beta-i586-pc-windows-msvc.tar.xz": "36404cc649e16efbdf0fb6afdf2130af1ab46618ee8130c431370be618d7e182",
-    "dist/2023-07-12/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "682e74d110324cf0f53121f7b8ef0bd6e5bc355b2fd1d2eb183bee85d26a3bf0",
-    "dist/2023-07-12/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "1ea30b0d14e7a5a82aee09b8e4ba87856158b31ec6b83e77929e2e9784698d43",
-    "dist/2023-07-12/rust-std-beta-i586-unknown-linux-musl.tar.gz": "b83d3652bd440b91ab2b145cd0ea3108203ccaa9beeea099220cd76d92a7f64f",
-    "dist/2023-07-12/rust-std-beta-i586-unknown-linux-musl.tar.xz": "ab78b6ca9136606d48afe42ce32e5a96cc07d4ea61856a500a9c7dd837983288",
-    "dist/2023-07-12/rust-std-beta-i686-linux-android.tar.gz": "5522933a886774ef4c490a8d928834d35c5a31b9066a8ec3b9b80de7d121dc37",
-    "dist/2023-07-12/rust-std-beta-i686-linux-android.tar.xz": "896cf7f6b611b676d40c9c20aafed11d7746a349a55658d03a8c6d197595006d",
-    "dist/2023-07-12/rust-std-beta-i686-pc-windows-gnu.tar.gz": "bcf7eca5717e3643a4f6a1ca4412bbf0466c0ffe0075eda441a0ed9060b0aacc",
-    "dist/2023-07-12/rust-std-beta-i686-pc-windows-gnu.tar.xz": "89fe6ed9068cb187eeb8c372dc04b7a10d6c9289d2374f0c59eaf6234fbd438b",
-    "dist/2023-07-12/rust-std-beta-i686-pc-windows-msvc.tar.gz": "8d381d2b4370a454793e66828e75a006093277e890d38e7e94582f094c390539",
-    "dist/2023-07-12/rust-std-beta-i686-pc-windows-msvc.tar.xz": "25f0bb9b88de1d2f54d1b42a23569dbcab7b37885f2b8a78665739352af9fbf7",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-freebsd.tar.gz": "435e26724e1799d2330e4d5262ba2995c46d601917fa3d1e0afefe989903eebe",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-freebsd.tar.xz": "87afb9db4d7f02e23ab7531fa57c574fedbf2b6232260006b59ef40bca15e06b",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "ceb59a15be998cb908f1a59460475b569e02bedab180396713e0d8418d55c909",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "3fcb9e8f60eeeba76558976ff06cdfd5ecbf2294c603af2398e044d2e04429e8",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-linux-musl.tar.gz": "c6a77d8f3c9eb6ce6e91a7e8fad8fba84c8b13f4bce9e565a65b01f307c005ac",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-linux-musl.tar.xz": "b01833d247e906c8b1e4c0c9ca5b4c37dd4166824693cc6d4a85ab881e482854",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-uefi.tar.gz": "1ffc65c298d91782a9f2b772f82e411d8e164e0a245b1eb0e2f81382f378076d",
-    "dist/2023-07-12/rust-std-beta-i686-unknown-uefi.tar.xz": "68b511d1a3685ea45644a0d40f5b456cef34ba48719947789f7330984a027699",
-    "dist/2023-07-12/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "0cd83da690cb1870b77c918f029273cced0d03f204fa42c4eec8930e6fcea8ba",
-    "dist/2023-07-12/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "9e215a989ed9e2f1c4581c1f38c475564b46f6b90dde91b63b88290cb7866a48",
-    "dist/2023-07-12/rust-std-beta-mips-unknown-linux-musl.tar.gz": "e66d3f598c38536f2db2e42b8b231acddc04c3edbb017d37adfd77a3378bf6c3",
-    "dist/2023-07-12/rust-std-beta-mips-unknown-linux-musl.tar.xz": "f030f5412e912004239febcb88c8fc489a7d35b95c02b750ba582a7ff895b79a",
-    "dist/2023-07-12/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "903649d2da11a054ffbeb440beb5c0f668bbc4a3c8f931a47b559659aba0eacd",
-    "dist/2023-07-12/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "ef1656bf4bd5b1fb90fdd1348808b81fb4b6da470966864ba823979890a1bb31",
-    "dist/2023-07-12/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "e2f37ad36fb7ec9d15a85c467ffb1af69a14f8a073a105e0341c5bf7f2feaa13",
-    "dist/2023-07-12/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "fcd15fe90bfb887fef0a83d1371283a965edfef029924d060ea4775be83669ce",
-    "dist/2023-07-12/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "8025e30f46c2f350a028c32be6b07472b40ce0dce8b4339753eeee391ff1639e",
-    "dist/2023-07-12/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "430eba57898d01285ae9b4351e5fca4179d638501b8004a559b2aec9daeaac20",
-    "dist/2023-07-12/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "f87733ff046a233cb9e68793dc3fbdf04cf8f639d1ec8e80f78d495dd168ab9f",
-    "dist/2023-07-12/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "d5756b6d7852bfe305283ac59cff20985e94f85f03bbb1c220d8e1b28b93392f",
-    "dist/2023-07-12/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "e193958bfd05581adc4e08599940f8dd77c565724c188bb331c61a1d2a030379",
-    "dist/2023-07-12/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "497b919f34d29412406202724fb20500d22cbc838df05128bc259826b4698f6a",
-    "dist/2023-07-12/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "499a17483bc7fbfdb3bd234c683eda4cb8e5270deb43c66253ad265cb72df0a3",
-    "dist/2023-07-12/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "8d209a47b988c987c93c32066d2f80bfa522e23f172bf8ac7a9c166408e98136",
-    "dist/2023-07-12/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "1795b4a2621f718915267eda5184d417406390490946f9295f3096322d4136cd",
-    "dist/2023-07-12/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "facdc96f065df0dfe2396445b44ed640a4e9922220dfe5c79df93b650bb8c982",
-    "dist/2023-07-12/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "fe297caa7916f58c7483103ee88641f02c75955e652b262e35b0f53efe3163d0",
-    "dist/2023-07-12/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "f0c06945c158f4613e336420c869c1b4f35d1a867c11dd227f9fee2f1b5dfaf3",
-    "dist/2023-07-12/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "ef8c7b0bd6055cfbeafdf36e3569804d4513cf0bf9e49f0a621860c0f203160b",
-    "dist/2023-07-12/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "96c16adbaddc9711e51ed1d626d4cc4c41f58b7e498987697b8f5177c577c2c6",
-    "dist/2023-07-12/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "5835365c7ebf66026d5ca60aff4c161991f49b0bf7ac626d95a8bd28b04fe759",
-    "dist/2023-07-12/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "07cf34b72aba65becbed5a0465f5b0a2154427100a8520af99d9b64af2ad8483",
-    "dist/2023-07-12/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "8241523fbcfee63cd6c62c19b7198f0a6fe8038dd886eed410b05903739105c3",
-    "dist/2023-07-12/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "78006dd24bf206104c0c2b1c54e8281234f6758ceff28fdbd5a39f280bd09bd4",
-    "dist/2023-07-12/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "be35239b3c6f35d9616055f92c0cdd014d1b55d62424d4aaf8e42930b0ce9e25",
-    "dist/2023-07-12/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "8f4bad99a3eefb9e46453425a48e47e6669e8ed1e3de3de07769e6faaca5af34",
-    "dist/2023-07-12/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "2523a411d75ba8bd18aa41438039f5c27dc7eb62a0cfa8f3e625d2f50a2258ec",
-    "dist/2023-07-12/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "6fbfc96c33502a4cc6484ed8899a9c9de011cb41f4656773f2a3b19b342ba6ac",
-    "dist/2023-07-12/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "c653216ff5ad0ffd50e7dfe5682c1ca51bbfa5d3bc8194cb8144ae80e617ead7",
-    "dist/2023-07-12/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "306f4a01fe16a5cf72fdc687bcb520b14e60b1b3b3bacb4a2073a2bda0714a1c",
-    "dist/2023-07-12/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "ed071c2f96c5ef162aa7865ff4c45432c0a30bcf09311202b9a96d29102d98c7",
-    "dist/2023-07-12/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "63a2579ef0aa3342f7998803705a6e574891e135090c85c9894f767dd60b780a",
-    "dist/2023-07-12/rust-std-beta-sparcv9-sun-solaris.tar.gz": "1dbf5fac46eff7e390e2577041c3c8f462e36eb0bf71f97e5273a934d4f99d08",
-    "dist/2023-07-12/rust-std-beta-sparcv9-sun-solaris.tar.xz": "81d66825005b0a501dddd22db16d7d783a7d1114a735c6734c447b469f67f1b3",
-    "dist/2023-07-12/rust-std-beta-thumbv6m-none-eabi.tar.gz": "e8a6fcd3fd68770ac582531ed12e9b11e4aac808c9ffd6eef2e15e01737717f8",
-    "dist/2023-07-12/rust-std-beta-thumbv6m-none-eabi.tar.xz": "08d11f9af0acbb3f01e8d36cd209f4164e1e7c0b1896add89e96d09895eb81f2",
-    "dist/2023-07-12/rust-std-beta-thumbv7em-none-eabi.tar.gz": "904f54943102586198c83d779102d5d913f35b743fc5258d7a435eb8a414faaa",
-    "dist/2023-07-12/rust-std-beta-thumbv7em-none-eabi.tar.xz": "80d4be9cee0123fdecf5f92a550323e4864b00800df5be48e7a5992330b09a9d",
-    "dist/2023-07-12/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "9c887c04608167e70ac66c7ca28f2adcb5b3111cd308203cb91c1e3d54910d60",
-    "dist/2023-07-12/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "0ae9f88cca6bafbb4fd6fcfa6c17550f0f478b38c8d061b276e10e5c8dc41510",
-    "dist/2023-07-12/rust-std-beta-thumbv7m-none-eabi.tar.gz": "9a6d40873beb20ea62a5a211cbec6df52dbb886b3c30d8b46086711c9d46f9ce",
-    "dist/2023-07-12/rust-std-beta-thumbv7m-none-eabi.tar.xz": "cdea56ba84ffdb31dde025073149e79a58f245f281a8cd2584c3032b649b8489",
-    "dist/2023-07-12/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "dc7b75d01d002b0e373737b0cccd7be2d396dee45f3da5174bf7bf94ae492949",
-    "dist/2023-07-12/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "c602afb2b5d6c4b6319f90297102c9d8c192e53e1b55a047c37b1d8280ce7100",
-    "dist/2023-07-12/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "0af441e446e4f7b1dad0593eb91d0bff30698fe66b0355928f95d08044aab4f1",
-    "dist/2023-07-12/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "3119430271c51189b66b2f033db32c6969f767985165270a9012a7535a89840e",
-    "dist/2023-07-12/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "87599a0c69951178be32f649f86a14c466771657d3d065e15749372daecc255b",
-    "dist/2023-07-12/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "a3dc1e688fa5bf81a5563831bf7a50b699392566da5dcdd35f773965c63d3c76",
-    "dist/2023-07-12/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "93056ded57a786931d0727c3c22a0e18c3939591848d1781b60d4235cb9a909d",
-    "dist/2023-07-12/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "a20c785842f9edcc85f7ded87c5c15de1ff96f9e268055ed4b9bcfa79034df93",
-    "dist/2023-07-12/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "a2382c5801287d9657ef1bb1ed8032b3f43fe4d0541529ed31aba967ec93a1b9",
-    "dist/2023-07-12/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "eaf0252d5ff159b8fd6788e63077ae1b87d7d529509d4c137452771477b8ff87",
-    "dist/2023-07-12/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "d6f4ecbcfcdc8f67a2bd0fadb955d716cfc030f7d1af1d05d71a2fcc16a8fd6e",
-    "dist/2023-07-12/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "1c7a720a53ef38055b23f078212d6fbfce39d715d4f12c2254d4ebd1c1cd1f4d",
-    "dist/2023-07-12/rust-std-beta-wasm32-unknown-unknown.tar.gz": "aa3c539b1ba267233b0310e5d8f8a97ed8a75ea6db96ff93fdcb4e7416be6609",
-    "dist/2023-07-12/rust-std-beta-wasm32-unknown-unknown.tar.xz": "dc3cbf54d1d46945e192d0f8b8d88cb77211d0d64d3f11a0d85b280d46dec35d",
-    "dist/2023-07-12/rust-std-beta-wasm32-wasi.tar.gz": "5731012231903dcf24ac529dcb3b08c598dc32857e3daefb636fdfd9c8e8cb83",
-    "dist/2023-07-12/rust-std-beta-wasm32-wasi.tar.xz": "5afac33b9009665436b2f522f6b26543f1287fd1972d6d3c3c74e2de8b1ef791",
-    "dist/2023-07-12/rust-std-beta-x86_64-apple-darwin.tar.gz": "30f925d5e75433e29e9448568bf4182902c02deb8eea53cc2645e1d530b8c327",
-    "dist/2023-07-12/rust-std-beta-x86_64-apple-darwin.tar.xz": "627d5378da2c26482f7461f82ec792987e67affafea079565b57bd86792058e7",
-    "dist/2023-07-12/rust-std-beta-x86_64-apple-ios.tar.gz": "db07a73405b8cc49c95c7d19c6a51e3aa88a1d7fda722e82e883efb12a763230",
-    "dist/2023-07-12/rust-std-beta-x86_64-apple-ios.tar.xz": "6ff23b2d7d8b0df0ea8475ca26775c094857166df94688595b6f0a5d58f8bdfa",
-    "dist/2023-07-12/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "103628b332971a4ac1998ebb9dd8e258f78de85510e12b78e4d9e7c0e61e8747",
-    "dist/2023-07-12/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "ce708d121273e40785975a5bca01fc1f51caf713ca1b5144e9aadd053f153ae7",
-    "dist/2023-07-12/rust-std-beta-x86_64-linux-android.tar.gz": "f949c2945a7458d2196d59b6f7fb15236182cfb0df20b7a07b3db63cd882915e",
-    "dist/2023-07-12/rust-std-beta-x86_64-linux-android.tar.xz": "d8106d2042e18ac1401e8735229adeaf24b276a3cfd2f9e8f9b67a14c2f64dd9",
-    "dist/2023-07-12/rust-std-beta-x86_64-pc-solaris.tar.gz": "b9e46bfa7576b0af27ce97106d8d243a5536de4e195c70a49c7df959c3c51f6d",
-    "dist/2023-07-12/rust-std-beta-x86_64-pc-solaris.tar.xz": "07489a82384a92becfc5ddfa1c2154613d32bed30409e64f520b06b52219a620",
-    "dist/2023-07-12/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "44c447c64aea3a471bcde4e2908c812e4f7cac949f29273037e42b1d19deef8a",
-    "dist/2023-07-12/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "c12b7a419935c6a6fc8fff4133e6abbc51ac579085e9ac503899ca0b65918d56",
-    "dist/2023-07-12/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "ae163e45e5470117db8c363badf7bafcb54755c016d7f83d04d969f63ba219a8",
-    "dist/2023-07-12/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "b64d506318824b764a0b5cf75768d4c1ca43773863c70aa73fb2d0df654d2690",
-    "dist/2023-07-12/rust-std-beta-x86_64-sun-solaris.tar.gz": "12bed740d7c0a3a5b2e85a8ae377ca97341e7eed5eb7d0b347a5d2ad362e5d21",
-    "dist/2023-07-12/rust-std-beta-x86_64-sun-solaris.tar.xz": "887930cc08da83c766ccdcc59bc6e983fff512dffedd911eaead1d4c5611dfab",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "778967f9f2e2802970e9b24a8edefc815746a200eddca4c400c5c615b8eb98e9",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "3b24a6ec9d65b2838d9985a210e6f9d39cd880830e03a90c472f6b2b9ff18e30",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "402b86e5b082e07c214023d412773c27733ac1493e5f559c52bbce7dc56c895b",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "571cee5f07dd3b4f053ef5f4e830bbae0ce2f95004e2ff13e029d27a7956b338",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-illumos.tar.gz": "5bac95d69f03e59390023ed50084f20ee5ec2757a2890fc2486fe71cf7028d47",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-illumos.tar.xz": "0a9a8fa23076619ec7e7ec60a293a46989cd0c7e4d3ef8ac76f5521747702ef2",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "227fd782a16425da1d63b4475351764298859ddcc50a2786b4ab0126a63fe559",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "2a7a6b36b2138daf5b97e307bd7f440d1b962f5c51a6bbec61f56b0bb909365d",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "a909474b87ff6abd09f4be16deb3210eec24cb1668eeddf1ffe683a542aa64e0",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "3ec154062ae28ecdb79cb2adb06db0acb9bc2633906318f9457b9e349a249237",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "108f9407bf5f7d2360d4d007a63792f1b5c2f03bf492cb553bcd36110d4f9ac6",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "8764f19bd2ee50000789433c9d1ba4771c3ed8f5f93d478998bb329013d4c1d0",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "0c95d624aede0298da1e08e4ce65f358f34eabccc47903dda65298f70b3d08c1",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "982bb81104b7ecfe0ef5a29e2e8047ba22691fea55449651b8cb2592798b34b1",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-none.tar.gz": "023f68b3c2f26e2fe9d3bd8a176853c1ab7b82158d3c68181411bf9a3dbc02bf",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-none.tar.xz": "b5203c4036b38d9bd41d87e662212b4a0dd2098f42ce016146ef781d864d5d16",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-redox.tar.gz": "79c54bdd460dfce0be833185e27b698a18a50bc63706eed5ad6a55fd43f00cc3",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-redox.tar.xz": "994752c9b73fa13fdda515296329e1b687dc98197401a5db4e93bdd00ef1a3a6",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-uefi.tar.gz": "254008e9f38d1420d9f6c68563c0475ed26128cf7918749aae19054b658f5eea",
-    "dist/2023-07-12/rust-std-beta-x86_64-unknown-uefi.tar.xz": "63eb6b43d7c526413907af2ae261135ab6cd30ba6d82ba92fbca8c9df7dbfbb9",
-    "dist/2023-07-12/rustc-beta-aarch64-apple-darwin.tar.gz": "361629903acc59fd7b9e23381ba10adcbac9b2ac1f9fa8ac995a6b7b34c73a72",
-    "dist/2023-07-12/rustc-beta-aarch64-apple-darwin.tar.xz": "74d498d2cc984cd1dbef636b3feecb81adea0e7ba581b4b27364ec4f26a81f76",
-    "dist/2023-07-12/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "be27c9217645d381c43014133e6654cd699bc3695310fcf3669d254d03c855c1",
-    "dist/2023-07-12/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "54850fa60693e3b353ac186695eca1714d96bf4a26528bc221754a4ef41dcd13",
-    "dist/2023-07-12/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "ff73babf1ca49c0d7bc61691ebead9d88fe60475e0daa99be57fc63d80c54db1",
-    "dist/2023-07-12/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "006bc3e8ad7e08112b9bd1b217f78795f251ff5c40845263eafaa24cda564fb7",
-    "dist/2023-07-12/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "e0d2afd64d312b174f877503dec692effa0f828a14801363bc639308e964815d",
-    "dist/2023-07-12/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "2100939e2080fad8040434e0d5afb38238a583deb9d2d87983ce3509d1f34fd5",
-    "dist/2023-07-12/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "b34aebfdafa0d27ceb2bf1494de0894dff09ceee7f924f805f55bee64c9144e3",
-    "dist/2023-07-12/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "b79fdc2786057e5267b3b00b4903786f16a522aadc2f3dd8bb8456e42400862c",
-    "dist/2023-07-12/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "e2e86e88c21e02fd16e5cc78a8de023af33a52d9b5006dd6884de5d97459ca1c",
-    "dist/2023-07-12/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "9e3d480fbd3387aca0acd8c63a45d91e2148117fd5dc532885328ab39cbc9d11",
-    "dist/2023-07-12/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "b08a6627dc24f348cc6eb9c89a63099ffdc1e71d562ccce0a7906ef279b4cccf",
-    "dist/2023-07-12/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "57d4513f8dfe30a2a62886d931ac317d956fa723b4d72c458f77c4be28144ec2",
-    "dist/2023-07-12/rustc-beta-i686-pc-windows-gnu.tar.gz": "6950bca30824403a94c1a272d4bf7a5771dfe608c20a3045ea6a48a5ad789851",
-    "dist/2023-07-12/rustc-beta-i686-pc-windows-gnu.tar.xz": "7891a4ca20a622138c5008824c01c6de7b5b4306381375d95b3063518eb7883b",
-    "dist/2023-07-12/rustc-beta-i686-pc-windows-msvc.tar.gz": "cbf66d5ed4dbae45e1738c4ea3879886ec59062bc59be93b2b526c49634fabe5",
-    "dist/2023-07-12/rustc-beta-i686-pc-windows-msvc.tar.xz": "01d52825cd5d184028f6fa2b47d061254e500324c43db0c7ee4cfede9f801791",
-    "dist/2023-07-12/rustc-beta-i686-unknown-linux-gnu.tar.gz": "04f9d64cde2749214fbfa849c72df4bece1c0c9bd485933acf41e4b38bb90976",
-    "dist/2023-07-12/rustc-beta-i686-unknown-linux-gnu.tar.xz": "387b72fec91c8afbf088819248b8333198a1588ff2ef3fced9dc75a0d28152ac",
-    "dist/2023-07-12/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "d6d6d499f388395cf0234ecbc250ad8c17201388502cc0b1d4dcd145938edf59",
-    "dist/2023-07-12/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "2f83df3cd76a236ed170b9b9eece1be1297f2159226d6ca13826ed345ebc25ba",
-    "dist/2023-07-12/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "fde554a543eba35030ff0b4c3402b5c24c372a7071d1e489797106b51392caeb",
-    "dist/2023-07-12/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "7d8dae3414126ed8d34dffa577d59b236d1b04dd9aaeee8e83bf50ef3269cceb",
-    "dist/2023-07-12/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "558622fcbf845cc05114680d20edb596f243304b5d540f8df3c575d0c2c681ce",
-    "dist/2023-07-12/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "4716b40dfa7ad351e9c476742d119167b30c5c4c2b2316808d6587ff0de69c7c",
-    "dist/2023-07-12/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "c97ad88f524cda10fc59e083f543b603a84e47c4cff2af51bd6294b0c04fa52b",
-    "dist/2023-07-12/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "0cba6173edc10993176e466b2f0c353551b7f544d499eca90e143c40bd855288",
-    "dist/2023-07-12/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "0d0a9cf77521a372271e6c37b7ca9b1ea879e1f8ccbad07e88a047268fbffb02",
-    "dist/2023-07-12/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "8f5e09fb6febc5965ec762d88ab812385ec133a732f006c6a61aedd3be6a7ce1",
-    "dist/2023-07-12/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "35fdc9549f2ae6545458ca9a899a2e6ecca33864709f28c3479bf547b86bd843",
-    "dist/2023-07-12/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "4f3ef47d674787313ce445ae453661302df3cd5c36e4f135b4cbf1ebd60a1e3d",
-    "dist/2023-07-12/rustc-beta-x86_64-apple-darwin.tar.gz": "ac623b79329ffae330e76d79a9ca741962725a072e045b8b7d9b2d6fee5a57b3",
-    "dist/2023-07-12/rustc-beta-x86_64-apple-darwin.tar.xz": "439cce8c9f3d614a8eefa45bc42723a15e9dfdefa83cb48f1751ba8aaf1fccb6",
-    "dist/2023-07-12/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "4f91add8c303b2c82ff9d2c5bb0723b298e0e1f5ddca524af9c1fde490d0d346",
-    "dist/2023-07-12/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "cda1396c2eddf49e42cab04fe152b4edea0d9ef61ebe987307962a1c5dd1e55b",
-    "dist/2023-07-12/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "993f06513b965731fdd678208985a85b0edb94887df4f4518b8190f1bb9c9faa",
-    "dist/2023-07-12/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "7a41f05c27619407a4a4ae6acf5ad567f2504d4b8e7462e0fc409513b3086dc3",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-freebsd.tar.gz": "19ab69319c2c52580e447cc22471fb18a25b06849c1fe79783eb067e0f75f1c7",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-freebsd.tar.xz": "684cbc8205f08c9e7aa6de7fc72422dbc87d5e842367f0c3e40f2206f3bd1045",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-illumos.tar.gz": "af31123f89adca1858eea5e5f00e42913aeeda1dbc7572d557a7ae132928f3f7",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-illumos.tar.xz": "e4f711e5b81663ddc2d5b5f85b74488bcbd0535c8e170fb99e3fbe7d6931e937",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "6f781b40006f6552a0f4642808950ac570d6b4a17e15bcb373a385ac5f822bb3",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "af7d049238fdf1d538059b918d5ab0e3751ada2f3a339a7479a295d08b5aa963",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "bbcfa001617d591fb663b55f1c072c5bd1c5ae57a245a00d6fcbe02ab52ef4e7",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "56ecccd46000dcfda0996da364509b7b2a739132693f776d63f9b1d74fb8c546",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-netbsd.tar.gz": "181b946f424be9a5430f79d56c80324e2a72ed638e571fbfc7d1af370d4aaf11",
-    "dist/2023-07-12/rustc-beta-x86_64-unknown-netbsd.tar.xz": "2bc9406b45f14e2efb47c9475ae89a3ec9ce780c402d27f11c4a6217a5845258",
-    "dist/2023-07-13/rustc-nightly-aarch64-apple-darwin.tar.gz": "4298aa816d4a6c1004e4a480f77e0d321a47c4b5e2048ed705a5a7d632a43bcc",
-    "dist/2023-07-13/rustc-nightly-aarch64-apple-darwin.tar.xz": "0758cf22ed98bba897ad3bff5c3fc49367d3fea25185e1b39cea417941c7ce42",
-    "dist/2023-07-13/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "0db596a386aac8d2d35293e8466a710498102ca6d68a16d60ebbfffa2cc67950",
-    "dist/2023-07-13/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "6a51533a6bdf3ec705fb7d09f076e67393b4090159ce6bfc8ab9a4abbda1b421",
-    "dist/2023-07-13/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "c6dd529410c4ceb5ef851380e1f12581fe0d2240b9224bf4727f4ef0dd93f7ab",
-    "dist/2023-07-13/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "7b3d71fd596292c3989c2e8982fe2d488f90449e68114be331f7589b296b9b1d",
-    "dist/2023-07-13/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "8551f98fb1030ff712a68b97cc1c67bbb19ec51748f92ac7d149b0d1e2f08ada",
-    "dist/2023-07-13/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "853b80262a5e58dd8c831a42f0efb229e5eb8516c6d4ddafc02152e2e55b6706",
-    "dist/2023-07-13/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "d04649a98a7410594bd4ac776a638d7312838e0b15cdf53236b953406a1bcf87",
-    "dist/2023-07-13/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "6319a00b08efdac3a379d587d8c11507a79446e9ef2421f6539af9a734ec2ce5",
-    "dist/2023-07-13/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "9739f7d186d5a92d9e775bda150ad1893fa14720f2e3662d61220d125a68868e",
-    "dist/2023-07-13/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "818fc51517ad026bda8c3eefa3065d3d6d9e465f600398404987e9c8420ba933",
-    "dist/2023-07-13/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "557e197ddd49d62e271108c8c0f17618d58c6b77841aee75cf190a260de8b522",
-    "dist/2023-07-13/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "a60b73f673e80f02ff1c1151e63d883b8e390ec447cb3154b1fd4ac4b4b9af78",
-    "dist/2023-07-13/rustc-nightly-i686-pc-windows-gnu.tar.gz": "31fe306c7b547d1e595d82b7195d972a3e8dbcace6bf786557d0ff14b7f3a243",
-    "dist/2023-07-13/rustc-nightly-i686-pc-windows-gnu.tar.xz": "32dcb5830ae51effd7f8bc6c2dc8c61863952c1eb34a3f6a5e5a7ca1e632660c",
-    "dist/2023-07-13/rustc-nightly-i686-pc-windows-msvc.tar.gz": "4ecb180c07b1f1f15f51508e0d2290204052ce98be2203c8d2257f620b0a3c32",
-    "dist/2023-07-13/rustc-nightly-i686-pc-windows-msvc.tar.xz": "e9a6e85dc43561d644988e862db6d3af53b14397e8aff1b162fe6f29c65062ed",
-    "dist/2023-07-13/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "4fdb462e10993e386f03396f98379bdfe45d60c38bce2102243d566d4eb0178d",
-    "dist/2023-07-13/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "759d1c97a06baa0f7d56705a0d4b4bd954057d140b1a28e34db1d2a59c85307a",
-    "dist/2023-07-13/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "5f0ebf7b582bb3e8112e8287a33966670f33c46db6fc4569963a7aa0c1b6daf7",
-    "dist/2023-07-13/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "044f6d651b03b1c74bd5ed86139119ed0cfd4643576860770a784557c864388d",
-    "dist/2023-07-13/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "9fef5ebfd5b50d256d85e24ecfe3953da80bce799c83eb8f453e70b20424274e",
-    "dist/2023-07-13/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "8d3c75ae12ef9273279c5c715680e0ec5035bbc642ac3e6e9d5e31f718b4d625",
-    "dist/2023-07-13/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "acb5e2e805023eaf2403385d26f1bf6fa91dc505f2a030bb3ef1b1c415cd2251",
-    "dist/2023-07-13/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "7bbb565705d19c01404e519c3b15db717678995f5ec5fbb572937ae7ee2efded",
-    "dist/2023-07-13/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "9af44902fc657866446dfa52a8e5f561e69e555c49c0e6f32d739b4a6af98a59",
-    "dist/2023-07-13/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "f9e877a64286b78876f33f7506086118653d01674333c59907e8cdf71c4e95a2",
-    "dist/2023-07-13/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "c5a1fb8c5f3a69adadac4a7c0f8734cc14b8ce1e383530419a095c4db6645b11",
-    "dist/2023-07-13/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "521e7be385877a0f4069435efa9308fc5d33e4f90294270a7f8df9327ce222c1",
-    "dist/2023-07-13/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "55d9efc83614e5fcc4a7ccd0581a95a66ada4577198b25b0f4e7067ee72cdbd9",
-    "dist/2023-07-13/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "6c88031cd1d59fb6c2f971b3ca9aea2e029f8481cd41824ffdb67a085feab5f1",
-    "dist/2023-07-13/rustc-nightly-x86_64-apple-darwin.tar.gz": "b75c6defcd94b930ced62a7ee18000a68cf6bf255479ead60395ca3158f2f198",
-    "dist/2023-07-13/rustc-nightly-x86_64-apple-darwin.tar.xz": "ea1dc2985f708823719589fb029de961b179cf19bb228a4745cc26a47415a5de",
-    "dist/2023-07-13/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "c1602297eab6a276aa367b2f85d004d236d26cd4b4133e4cffb941ef3c858c74",
-    "dist/2023-07-13/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "06965d8332f0fc167886f6e9a3ff9a558aa3513711ea309bab5f30185a9afee7",
-    "dist/2023-07-13/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "80c3d27142473a89beb1969cbfdba7281ca237ec8f2a5b20c75eeb14c5e2e771",
-    "dist/2023-07-13/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "52fe4134ef2ab35ffa251669a30ca6c9aa94a3ca97238f46f9aad0b2b9dac70f",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "837f628f7775d13b661c1e7dd7a1de649264abca247aeeb6cbab05faaf7e83c2",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "732a597647702c2672f559c83a8e829c36dcb8fe92bf8abdcc1cf2526ba2d8af",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-illumos.tar.gz": "07eed9287f36cc6650838e27b7148c26d588b96b522e1b72f58ceebec4b0dd87",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-illumos.tar.xz": "70cb988d67159941502900f803e29bdb53f81057d68393965ebd63fe42e2cba4",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "adbe0dd7ba4df92f199118943bc25d3a467d6c1d3249817b74e05c7d59a76846",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "c999ab64cbbed8bc2853b717190d6d4aac871363c7182e06c5144e50d34621b5",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "1bc5368592390eee2478d48f75fbeb5e9f3f8e4fc2f6e3e6952fa08e7c8f46f6",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "15559729aefc45dcc1b28333e6166a2fe5b1e0d30521b9a1ecd80134c859ed85",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "f918703cc31c800e35d739ef146733de486a6fbb2a0c78f993352a1242352f0b",
-    "dist/2023-07-13/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "777d69d7190825ea83dc44712d0372b1a225b3e4fde66d1b9ac4ea981d54a031",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "998a5c80bfb2450869e6975aeb178104f3424df6b88fccb9c549ff95fb0a62e7",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "84f8e77132b4ce46086907bbaa3bbfbe151400d8110f075cbaa31e80616d9891",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "63a8b8302007b9052a0016200332e85b24f758960eca25ba7ffb7f8d5c6ed409",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "291d17a39390b1259d47e8b1c9495d80817e12854cb3ede2a91b50a8c7a998f4",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "c5c5d47c25fecaed410f1c0004e30abbc436b5dc85110f657f1ddc87b10933da",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "c7da897bf78cc051fa0028b93253348ad4b89c3dec9782d093db98b1814cd828",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "2be878ea50ad540b17658dd29bec4124c43654f4668c62e7a4b2c7b5ad07155b",
-    "dist/2023-07-13/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "b355c1bd4140205c613c539021e0194535fb3c94b3eba2a2dd6ae314a7bca891",
-    "dist/2023-07-13/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "84e711b5e26487bad148d9968ac7236fddddd050761a3069ce10a8e222a860a1",
-    "dist/2023-07-13/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "fff567ecf3c426558c8cd84776870d833511049dbc531ed5e71733694afe5f70",
-    "dist/2023-07-13/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "61b48838a1f0097a8060f4a01e3b5ee2acdf409ca681ee7c78c120ee59a82e1a",
-    "dist/2023-07-13/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "687576f050b1266236e986557eea10fe4354d6be3ab930c5874aac9accc19a7f",
-    "dist/2023-07-13/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "003e572ef26cc1f39449fc7c488be6ba4fc180a432512036c2035c5249b5a7ae",
-    "dist/2023-07-13/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "dad6a37c9054bad090e3fc69679ef61cf95f16063623aba72f8002a95d548020",
-    "dist/2023-07-13/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "707a6ea9565d9c65b0aa3eac205659c41c70da0f6301d04caa4291716e70aa18",
-    "dist/2023-07-13/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "0546e09197a129dbf27b93ff6e0d84d0dc1a4b40e49ec131e29cd2c3636a950c",
-    "dist/2023-07-13/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "d7a15e31b67f1897a2968d58b0578fd6489e55709cea5747b9b49f5aa2e4d62b",
-    "dist/2023-07-13/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "5b1bfa464636528d7245b7524fe471fdafc2bd088efc5d99823a5d3b31afd48f",
-    "dist/2023-07-13/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "ab7d0ac3cbf01cdfd0aba52d869208469d49193a81ba59502d08a377cea883f1",
-    "dist/2023-07-13/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "f18f262a288c55b72b434abbb0d304eb6bae7db27fccfb2bdca6eef9078c0f68",
-    "dist/2023-07-13/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "6e95d58a682e0f924b71d40827f156e3a52b5c90bf3347b4b67c275f1e372537",
-    "dist/2023-07-13/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "c68cf075f8eba37e424a1ad79c87963070b20fb38c0e140bbf9733368e45077d",
-    "dist/2023-07-13/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "f41f9f8f383b12ab0d93b63647aef8e57431475ccb41675d69071a69fdebb6fc",
-    "dist/2023-07-13/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "ce097e23de16a0f0208fd669c71c372dcc99ab3114af573cc38b1b58ed5b10d0",
-    "dist/2023-07-13/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "6fd13a4f75c4d3ce82a7d7e54051c308d7a18be89c829ab0fe313c6735c74a8d",
-    "dist/2023-07-13/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "66c363a6804f279ea8ac52db85b6ad37b3075f59a6cf2f9be213f2849a76880f",
-    "dist/2023-07-13/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "480fef935283819bfa03c8d4ccc9300bc1c6669371c4ba41af2e8e3bd547e8cb",
-    "dist/2023-07-13/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "a3eb16f78498a99dda46398befbb0d4a876e62b9db9b344e472ba072c8583846",
-    "dist/2023-07-13/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "607a0582cd382a04c8131cb03cfc48092eac953953aeafa06dbe84889553eea5",
-    "dist/2023-07-13/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "0bf682b38cef792c1514b2277c8a933c27d87197895b83c3a67684ebed134ea4",
-    "dist/2023-07-13/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "1579084ae15cfc842f587e1e208693cdf7fcfe76dd818efb3b98d01a39b1f93b",
-    "dist/2023-07-13/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "361ad2ecb131f2c0ed773c864c02f59d960264fd86cf3397e81b58bb9d0237a3",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "429150699fc23b90bb034b2b06dbc27f74f0fcd467225afc012ac7dd639228c6",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "31468dbf051c1edcd69873264c28e046d5d6e1867ba9255b8a0e97905b536fcf",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "38e8742bb196216409e474e07deaac2d2a842d1372f3b7e1ad24c039cc0fb609",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "8287a9058332bc41f7b83788d5c3af2bfdca6986301e3d97cdb583b619967c2e",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "db584715b7df3be2d97878cc45102474b551e13604e71485dd14e68dfe3706f0",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "6fd6ee9dca05b8560536c738cb0b4020aa37397acc4a1888f4fed5a89e461d8f",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "8bccffaf50ff3d3ea7197f0a5b2fa075996afe9de602821a5638ee5d7c56e610",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "0ee2812579304231d29c32d32e5b908751e369ce7776b9773a3cf89d5fdb00d0",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "9f26ef23056f20f722f3616632cad8d03428248f126c83ed682ab4f67268e7df",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "1265d7f28cf332db9f467d02f0a77ffdfa926bbf7ad5d148cb04ec888abcfc49",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "74a5d268d82c39eb2b23b5324ce978647e59591e586f7c52d9187d7843990e1e",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "4b16832cd24285705a29e3e9aaec554675852200763bffc6124005211c38f37e",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "0cd34367c1ee4a61cf7bf26591aa65de6651c0a0912afdd1f08cea60da35ea91",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "5321648a640b3ab57d329a1ec5e83f30825c2a8ca73a4135c1c003726d86b28b",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "298c887d59f8f1a7a4d02335224fa1b9b3ccdf540fe5bbf00417d083352c4149",
-    "dist/2023-07-13/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "f0e6bc108a89407273790d228d51351046183a4eefd64631879cba6fa72c60d4"
+    "dist/2023-08-22/cargo-beta-aarch64-apple-darwin.tar.gz": "3a683934876a9794ee7ddbcf7cbf5d804d111fe02b324aa0a0321ec9cdfa8cfe",
+    "dist/2023-08-22/cargo-beta-aarch64-apple-darwin.tar.xz": "6543aef16521f2d7b4b6eb9e69e003dd8adc3f35a3af7d9d35a6fe8580ccc407",
+    "dist/2023-08-22/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "c8f7ec0b5b796c5218372ffd717728b3d70b56e6ac9002e351ef165c45455f66",
+    "dist/2023-08-22/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "d6778d5c515222a53a446ced90fe249613a537538ef2cb5aa5bdd807043907ca",
+    "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "c077c1851e22ae9b13bb2cb6227602b57427916a7412a63365711c10a8c05df6",
+    "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "a33dbbc00ef63ed18e48e42328f25932d1adf62531ed614c650d5e16ba68efac",
+    "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "0a68d407c8301f5dadb99cab2583c4e036539b52f46936995fb3ece4ab009551",
+    "dist/2023-08-22/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "577bb44224b03d5e50f511176a2a28cc900fd39ca581c7ccdd8c098c1ca48e9a",
+    "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "5cfea3f60889c5ea51398427fd34166f94c57718a65556abbc942decdf23366b",
+    "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "546b0f2b40edfede8176d68ec8278f7908d606f7f22daf3837fcc5beb5a04284",
+    "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "362157d5d3d6ccfd7734f2fbc6e3af28b85c7fec7bb1ca7c82fd5cb786c877c2",
+    "dist/2023-08-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "05c51f3d4479a6f5ad562406e13e33cfd1c193a1d48190210fa2cea48da019f9",
+    "dist/2023-08-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "ead8d3d836f57d6dd02a1643446c9d8a34bf20d64e1bc402181ac8e44848c877",
+    "dist/2023-08-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "ee127cafb6411ef6a4f7cacf2ea90b69b86201f488abd9acb3e82d22fbf56dec",
+    "dist/2023-08-22/cargo-beta-i686-pc-windows-gnu.tar.gz": "141bfa0ab5bac465ff7cdd91adbc2c293e78cabe458f2d425c6c0ae9b2659d66",
+    "dist/2023-08-22/cargo-beta-i686-pc-windows-gnu.tar.xz": "dc90fcd745217c237fd570a8ada5c45773066cf58e26bcb87476d5775da32906",
+    "dist/2023-08-22/cargo-beta-i686-pc-windows-msvc.tar.gz": "07fd85b164a96ef666099fddd03add274e70b11d9343344c627adfcd5c5d4d48",
+    "dist/2023-08-22/cargo-beta-i686-pc-windows-msvc.tar.xz": "96fcc0fca2870cf3d4ee8ca167b059b9e4d09bb81c88517cccdd1a082f5aa233",
+    "dist/2023-08-22/cargo-beta-i686-unknown-linux-gnu.tar.gz": "cc9f41d9de949b08964c6604eb75fc2fb3b79d939e9134c54698aaf4fb701dc3",
+    "dist/2023-08-22/cargo-beta-i686-unknown-linux-gnu.tar.xz": "e5c557c9704ccd9d5d39d3dad5537c3ef152d0b997806f9d9ad0bb91a2ef2fd7",
+    "dist/2023-08-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "ce2082ae94f4ab525e500374ac57bc13d32f8ec1a7dd9896bcd9c9d9c5e3eaf4",
+    "dist/2023-08-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "ff18d5b23fd463be8461c27a0ee4a4662f1be1d57f69358597faf915ae42d92a",
+    "dist/2023-08-22/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "4eb7ee68f3932b4519c9c4fb55b8e79ec0a1dd0a40b17cfaf2c0685201280e74",
+    "dist/2023-08-22/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "95aebdc6896767735e6e8b5e9ec31511fae8281bd258757f25cf9b91230e2a61",
+    "dist/2023-08-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "758fd95274033cd40809988da287a72de426267a2fc399d46992a97177f08264",
+    "dist/2023-08-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "c33c0da9d12fcf19ef145d22f5e8046bcf0df344f325932d620c11620e87b880",
+    "dist/2023-08-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "71485becac68eb4c47627152a1958226a8b1815f8c5121ef8e4886109a1da559",
+    "dist/2023-08-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "c03bc6285489d415c5f520c268430edd5edff9aa2c0bd3ceecacf4e916edc4b4",
+    "dist/2023-08-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "a0f18fe47623d2c30008cf9becdc4dc781b397efe3cf163fd6c4459ae824e641",
+    "dist/2023-08-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "8b67e2d9ff285903baa094a23c1a4bd9a959ab6f99193c93a9c1695fcde6ffa8",
+    "dist/2023-08-22/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "399ecc7f0d6f0efd9ae2c4bf382ea45f0054f4baa87a415e2f4cb9998fee8f24",
+    "dist/2023-08-22/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "465b456e2c34f9066f9ecae13f8e6608cc8cebe3218036794996ed9643a20c3e",
+    "dist/2023-08-22/cargo-beta-x86_64-apple-darwin.tar.gz": "297bdd5712507eb14c39e37128a24960cacab0319a885fef205b5b31978f4100",
+    "dist/2023-08-22/cargo-beta-x86_64-apple-darwin.tar.xz": "5a4bcf28c268bdc7a863e7c89595522ad0b6a6ebb3ed3408adc57670c76b5d21",
+    "dist/2023-08-22/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "f70ce4727665a4cc5f9d7dba8ae91a50a5ab9b834b88eb525a8b213fec25624f",
+    "dist/2023-08-22/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "7349e7a7c20fd38332a27119ef72f09b8b54ac3c7bc937547f478c3f2bc619f0",
+    "dist/2023-08-22/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "de204ef0efe760c974ed2f58a3cee7532a1275bbb146f7a648360cee5548b2fb",
+    "dist/2023-08-22/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "b1f77cd3deeb33f2cb24a568c4530e3cffd6194c8f1363baad356d12f3aa6899",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-freebsd.tar.gz": "56a2770793bb768684a84b4d99d8287bb04365c4017c3c0802d36a37e33281af",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-freebsd.tar.xz": "c9ae52f1212ff635f3300befbd33e575c308e14ff13f0ac30d5d97a3797788f1",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-illumos.tar.gz": "8e5ad86ea47eb4901cc7efae579c855a1b3eeee889c7e39fa248eea4465ac6fb",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-illumos.tar.xz": "56b3d2363c98537bd70d5e54b1caa446446edfd9fbf3efafd1f1e5ed24985c02",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "61bb143b2a7969fecb28755227e258d2018d8344c5325b2709b3d3b34aeb6bd8",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "6a5ff803aa4e57e35175fb62cea3687f26a55e9ec6bb0e9066fce27c4f4df727",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "2af897d7e7a9b09d645dde71b81a1757e5ebdeaa0291d5c50ddc95d3b9fe08eb",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "41fac61a6ca64490400807dfdcb96076926e61174ec295e8c6534b41e5541e71",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-netbsd.tar.gz": "29d324fb629b1aadc67d207b9a4e3156674a762970131399b10a7d8a6de152bb",
+    "dist/2023-08-22/cargo-beta-x86_64-unknown-netbsd.tar.xz": "a1f216345774fa9b812ebe3f8adaa4e0be152d095e73f289fa70d53d04d27fda",
+    "dist/2023-08-22/rust-std-beta-aarch64-apple-darwin.tar.gz": "0b45d8fba14876a6323c8adc8368916f8581c868d63c10ab65c0e50f4c021a32",
+    "dist/2023-08-22/rust-std-beta-aarch64-apple-darwin.tar.xz": "f471a9373c16260f8ed8b467c6065847a788864289d979efb406e99976d14dc2",
+    "dist/2023-08-22/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "3c0e3226b47a8742061587050048db97843e6c96b08930ada010c07fe06c89e6",
+    "dist/2023-08-22/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "7739c05595dadb2f021881b0e38d16cfbd705b0a5d31ac395b8fabb2244c8050",
+    "dist/2023-08-22/rust-std-beta-aarch64-apple-ios.tar.gz": "261b76a4f1ba923477163a868b539781911c7d0bc8dc944530d806eeb6634cde",
+    "dist/2023-08-22/rust-std-beta-aarch64-apple-ios.tar.xz": "c16102bef9f2d4fdf3c970e2f4e8316b4b2540b43855860be7828209b63c8fb3",
+    "dist/2023-08-22/rust-std-beta-aarch64-linux-android.tar.gz": "2b6e30df92c4b0c6e464ab59a37865ac91b4c4c4863b06f2bc872d50e2799bd1",
+    "dist/2023-08-22/rust-std-beta-aarch64-linux-android.tar.xz": "dc8e6fd9d6952969c97af01358034c9ea21182fd5061dc92527aae73b4305bff",
+    "dist/2023-08-22/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "773e9b29d36ea66a79df8cbfe0ea28ec77b31b1b042563584a1830d814eec269",
+    "dist/2023-08-22/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "e40c8120fc1850818ffbd151d152b317f7d306fc27d8305bfc376cf55d7a5863",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "c61713b4a7f96a6813f96672811de1d979e732db07c177e7a031bc7a3f22781d",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "1f54408288a19041e58114766263928ec7bee7815c392d25bb1abb5ba2107b13",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "90be82b6fa985c80ee709113c6fae68c0a6055a6b3b63b84e34d98d1f192dfbd",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "a2367d58c58aab240049fd5819f7a1862365c8ccdbdbe43cb94fc74ec4b424e8",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "2525b581645aeb8c07129a7680f7ef76e87af4633fd533ac991fd4868049b72e",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "6dcca8f5b63968ebc6adc066d76a4ef53112f52dd160f135b0a029832fe25060",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "8f07966490ea30beea51e79dd158c41699cc0cc5a5b3cfe211f3452b2d1265ad",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "9cf5cceb96eb5e2bd6bf05ab663a92db637c7af3c58bb921ea75b61b9075ecab",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-none.tar.gz": "41622341bffd5352c4248535f952f721638ad9e0ebc74b5452f41dd6ee261017",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-none.tar.xz": "cd149fd111b65631e2535ae79dc0fbc4ae69d6ebd25d4f91751f76699be74f2f",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-uefi.tar.gz": "b884565f46a93bd75bbb86a5565d5c6fbba925372d00b8fbb5782f6948f1c6ed",
+    "dist/2023-08-22/rust-std-beta-aarch64-unknown-uefi.tar.xz": "24c4e88d966a7437a9008a02101c0eb333a78fade9e71113491b586b89d80bbe",
+    "dist/2023-08-22/rust-std-beta-arm-linux-androideabi.tar.gz": "9b47e40f002a9c8134fa96f3c8566a5ccb5543903804254c59d7102dcde59725",
+    "dist/2023-08-22/rust-std-beta-arm-linux-androideabi.tar.xz": "96d2b153979301ec03b04b2a35052e2be1edf67693dbef43bdd46eec258604ed",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "4f4b08d6773721b796c8a4928061647285e7b06e5a93472fa3578d7f5f96ac83",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "61b62b29fe465550e07e62eddf786086c3a38a7e98c533cc86a689b657061fd6",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "22091e84c962c9291481454825401693b757ee5cc2332a2a3d8a95c93bb8bd6b",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "48e273442bc827d22b177e8b33b1be897da20389ead5cce2de2bb4c936ebc845",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "74c06121290814a97c82a0dbb8160721d27210d58a3a4b1b5818daca8265fc01",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "e15a6a3372901716856e606b369392d270dff0b3293988e5c621b86b384f3dc1",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "e1acaa191877b3debb6b0b59c3aa47937f0113fc3084dbe193944916fd4e810f",
+    "dist/2023-08-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "e94f16fbd527f39c1b9b3f09b977d7fd07547bdcf00385a2a3a235130c82140b",
+    "dist/2023-08-22/rust-std-beta-armebv7r-none-eabi.tar.gz": "26fb63d61f57b3ae18d5c014430ed9311cad890d88b8560b1094f2d1f674a394",
+    "dist/2023-08-22/rust-std-beta-armebv7r-none-eabi.tar.xz": "ff7d3403858c5e77da1da28c7ad81085151dc0c004189a331d3e5f3d8a2d93f9",
+    "dist/2023-08-22/rust-std-beta-armebv7r-none-eabihf.tar.gz": "f7a2b8e8810a19540186d6c9677c487bdac387a94dc6268cbff778dd93ac1b3a",
+    "dist/2023-08-22/rust-std-beta-armebv7r-none-eabihf.tar.xz": "b4a7c4b6d47dd3a57b1e05afeabb381d624ba1ebf8e789aa10f00a7efc6b329a",
+    "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "ce7810ab026a6dea1732d983238df88d21ca94ef10f78a06ec2e366149a6ed76",
+    "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "b31641f975c76f63f8c43402db571edb3b335b5dbae1b95c6362d3515d5d28d1",
+    "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "75438e97bf98c48c448ea8b96fba21a5f31c919f2da8c8fe048bd54950964ffe",
+    "dist/2023-08-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "c8e1c0f109722ca0918dcba00544692abf8d04a98f86b586b513f06d77111c4f",
+    "dist/2023-08-22/rust-std-beta-armv7-linux-androideabi.tar.gz": "fdc3d9960d0ff11c03e9c7d0c997aba7a5e480b860410a422035f69359d12451",
+    "dist/2023-08-22/rust-std-beta-armv7-linux-androideabi.tar.xz": "a2acf41ea19e582b99fcbf56e37eb35e9a309bc6183553cbaf12b9dff976dab8",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "81d1d1459526343aa5ab66432eab7dc9557d0c07550cbdafbbf5e402be7eb833",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "baa369b9c1df4820f6a8593193bb5376002c79e81dc0681c2329a45ea664a87b",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "b9e06051b2705ce2680723e3209ed0099a05cf2f2c71342e1176c16e485ee66e",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "5633759d31f4b390f2f9b5f63a0dc7f027a2dbe1241fe7089c06931c360a5f46",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "141232d8b440588d181c2d550151879ad6bae9a5af7875e6428bac6e65f6d8e6",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "5a82fe0b4e9476b642134071858288e47137aa26de88bc892580ab777650094b",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "8d9821484c5bbe8c51d7d54859fb8bc475ea6cc2f863fadb29b2973daf3535e7",
+    "dist/2023-08-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "e68834499329dac318fd51c49dd23836c3a6db0eca746869f8dc38d286b5f8ec",
+    "dist/2023-08-22/rust-std-beta-armv7a-none-eabi.tar.gz": "3353d69ace1f00b7c9d6291144a0ce73edefc5e7498fcb04dcc336edcb3030f4",
+    "dist/2023-08-22/rust-std-beta-armv7a-none-eabi.tar.xz": "d783d9ab96541426a5cdb2e6e866d0b9b1492e64030011aa3503b6558a4b3acc",
+    "dist/2023-08-22/rust-std-beta-armv7r-none-eabi.tar.gz": "28b6a82549de0a84323ff7db7104da9f978d2044997681b2ecfd6fbc7e14f806",
+    "dist/2023-08-22/rust-std-beta-armv7r-none-eabi.tar.xz": "f32aa5def56e3ff083d380de063ff5239f19b2b2ff8648f1f092512a621c8291",
+    "dist/2023-08-22/rust-std-beta-armv7r-none-eabihf.tar.gz": "f7a57d763304b64e732b46dab90bcf93c712e5e0e5b558ac20033658f4b27e2f",
+    "dist/2023-08-22/rust-std-beta-armv7r-none-eabihf.tar.xz": "4b74d5e31d3317b0f5519693005ad4c2b3b5093531deae630ab210e177f5b41f",
+    "dist/2023-08-22/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "691200324336964bb254c98350f6d2c0e545a42d7c6903c76a7812b068cc18b9",
+    "dist/2023-08-22/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "c2c0ddf54f7dcb60c069117c7139c2c1f57e8f9976447651df2dc9c6507b3ef9",
+    "dist/2023-08-22/rust-std-beta-i586-pc-windows-msvc.tar.gz": "971a6f1507ac8e47a9e2435f9f0fc5a24f77393c6ae189057bae8cd1ac35d5da",
+    "dist/2023-08-22/rust-std-beta-i586-pc-windows-msvc.tar.xz": "4af5f8c029f2486073ac4b71725526cc1ef4f3861ba652190cb940273fb2ebbf",
+    "dist/2023-08-22/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "4676906af1dca83ae3dba5972444ca2b15a755223ae999ec9eb66072125b9d60",
+    "dist/2023-08-22/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "a2b556a5afe3c69e91eed6d7c6ff31971598eeb35c227b7aca46548b80eff7fa",
+    "dist/2023-08-22/rust-std-beta-i586-unknown-linux-musl.tar.gz": "e8501702dca37516dd8b567c277b74d19a2e1142ca4c97b881b3428aa3a0bdfd",
+    "dist/2023-08-22/rust-std-beta-i586-unknown-linux-musl.tar.xz": "a0fd2fcd9a0844fd4063b80189a342d77e6d0c087fb240e28ffbd1b98813ec13",
+    "dist/2023-08-22/rust-std-beta-i686-linux-android.tar.gz": "ed1445ae201aa69997b850037b98beff658e92a25e860ab525617836de366d72",
+    "dist/2023-08-22/rust-std-beta-i686-linux-android.tar.xz": "e9be5e895d4e61d3130a502ae3aae8b796028fe8334f161659e90c8feb38d8d0",
+    "dist/2023-08-22/rust-std-beta-i686-pc-windows-gnu.tar.gz": "41666fb8c03e1403f67f6fb595b1c21c522faac78ed8a9664d476f69825d15ed",
+    "dist/2023-08-22/rust-std-beta-i686-pc-windows-gnu.tar.xz": "64db89392d6aabdaf39d810f3aa8692a50ad68214db5ae08565462e8ebb1ddde",
+    "dist/2023-08-22/rust-std-beta-i686-pc-windows-msvc.tar.gz": "cf1e94aa60bd9c273216df658b9cc7c947b3f8b47f1eb4f7df63c07a328ec0a9",
+    "dist/2023-08-22/rust-std-beta-i686-pc-windows-msvc.tar.xz": "e69ca7df48d927d6fdd40b4de3e5c8d402aac9aa29e7f3cbbd45d3227a4a438d",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-freebsd.tar.gz": "ec23333c6c7af11adcd8a01c6f722a6103c92a925c197a1f2797780ae1b84c42",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-freebsd.tar.xz": "301c39d275e3b1d32076364c627cb4953ed200dcf092d4a7925ac662a165ca48",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "722ffca25c78d9a83632773ab0bc36e0b999cea66f767dfd2e15171790c14cc9",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "384ab84d4a8d6fa5429cd5e13a72591a50041e84e846f12105001c1defea08f8",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-linux-musl.tar.gz": "913a316a08a15b123f6b136335886a4886de0d0cb06f02b14f82b436e34c83f8",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-linux-musl.tar.xz": "6b440b91f3ba0319d39e73181b173d630098eec1ca76298a13afc69afd156c58",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-uefi.tar.gz": "a32f3b2e6951316af9c557bc128b95b797586881cefa0f311e6e44779d4c6bd3",
+    "dist/2023-08-22/rust-std-beta-i686-unknown-uefi.tar.xz": "7deb5fff47eb1ba074f1835f9db54afbc892fce287c0ca2a2590e8bbd6d2168d",
+    "dist/2023-08-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "1f825781e403bbfef798a8038c3c4f800b838923b306866b21314902db06701c",
+    "dist/2023-08-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "a0b341d9464a8a68c7c395ff051ae384066ce0f97e0a3c50b8adf6ef253ef6d8",
+    "dist/2023-08-22/rust-std-beta-mips-unknown-linux-musl.tar.gz": "526041c26f3854c25b60969bf45e52d5f3d9e1548f9ea06942c0673434b115bb",
+    "dist/2023-08-22/rust-std-beta-mips-unknown-linux-musl.tar.xz": "c01d689e540777f8120775d05f93631e31ffcb05bdafcea2d3f1eda8af915f9e",
+    "dist/2023-08-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "f03f3b2767b2775e8f74d190ac1614307f2576c8966eedf710663bf39cf99027",
+    "dist/2023-08-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "9df204a1c45770e72c49e334ccdc47779825b1c0ae979576f40393a6ef05de2a",
+    "dist/2023-08-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "4892c903b692ea7fbd59d9dacf3ddc886fc0eb771d817c3dc906a875238d1f91",
+    "dist/2023-08-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "47cb42fd72f3dc488d30a959447698932fcc9499f50fb78e585fd208465c64c4",
+    "dist/2023-08-22/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "9d2b04e6ca70c95f157f9e273776bf10979090871307f67b4aed4f8532dd9905",
+    "dist/2023-08-22/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "70b260a23b6dc2c43041e15167de8a8589d2e33a65feada35a1ea9c3912db93e",
+    "dist/2023-08-22/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "a5af9e233e3fd518a2976dc75e5e79555fb9722c9b532f6d6a16c2944968f660",
+    "dist/2023-08-22/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "5d83a2ae7ebe2242f6370febe19fbf606d0282d57ba2dcb08b483c4cf0fb084d",
+    "dist/2023-08-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "9160571a2ec98b1fc91a10134c842c34c8370ac9990adfcf6368e90a259a4b89",
+    "dist/2023-08-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "be22e907234b415684e90af6c0a3a5ebec114511235f223de0ff2393a929cfe8",
+    "dist/2023-08-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "c73d1e7282d6f85097f13931a7ff5b66bfc807605284b35cacf2a94f9fb4ba0a",
+    "dist/2023-08-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "75e7578497fefdf7aae1b1d0a4e20855cfb06ed2f58bcea5cfdb8e71ba224c35",
+    "dist/2023-08-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "b692e3bc1199f3a7687fd8e5d6224696e56280ea989c402d88ef3da3fad2ee2a",
+    "dist/2023-08-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "61e86b7e3a9f8004bfa1a72cef3bd62eee1ee67964c747d6387d62ab8680f237",
+    "dist/2023-08-22/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "4d5c1935405d66a7e1a7532b165ffcddd4501fab25f346a0c57d06d7d480f370",
+    "dist/2023-08-22/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "a581a2224049bbeefdf81ed556960fbabe3d762abbd9ea7765425b2d9d0403cc",
+    "dist/2023-08-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "64d1a7bdd061ac16c585ae035e7b1d2f7b4ee4c2a71f491cf4ec39d3a9cf4904",
+    "dist/2023-08-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "528bd7a62c69a53c3aab2488be12de23199fb0a3aa4b117e1b906af7b06233a9",
+    "dist/2023-08-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "6808261b20282eedf3ae11e6300379ff1dafcb4fc22c0fd7eba5fb8e31fe4a97",
+    "dist/2023-08-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "2782284032eda7797d725e8986bcc5104a28f46e13c9774d8c1b115a3e192cb8",
+    "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "2e77b3d53304eae6cc8111d627f8114e4e0b759a66a696937632a95cb213302d",
+    "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "a8592a9d233085e65f87f7d5c290fb3bd3a88f9fe3492a5bad4afd5f64def27c",
+    "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "8d753ca5922d7fe6782a8dcc366447fd0062784a21f90b210c3946e6eeeb0a0e",
+    "dist/2023-08-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "29fc30370d9b08aaf9b5b36a23c463a494f673a3cc9207dd600dce9498b0c6f5",
+    "dist/2023-08-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "587e51be642bd19528ac7942b2026be31086d12dc81dc8a324ff662328b2fb1b",
+    "dist/2023-08-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "38759bbd4ad799e02c9a3c5947ca5637a2b7b716fe51e986788ea424d3dc0310",
+    "dist/2023-08-22/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "bf702a5aaed572fc753d27d786ccc9f83664d6b66812d9a9e8b3ba63397857de",
+    "dist/2023-08-22/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "187906dad30dd2da2f608e3713b6cb2ffaaf491c8109f4d381d4ba9b92e5c82d",
+    "dist/2023-08-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "368835053411c9a9ea8a96813f12724989aa6e00b160f7e75628155b038e06a5",
+    "dist/2023-08-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "f85bf85725ab2ba21e83f5d024cc1c9bccb5fe4b90760f0d34383a0cfca000cc",
+    "dist/2023-08-22/rust-std-beta-sparcv9-sun-solaris.tar.gz": "1f5632a33b2a94354e062821b5ed5a99810ed0d88c8e8370349c08f4541095f3",
+    "dist/2023-08-22/rust-std-beta-sparcv9-sun-solaris.tar.xz": "dba0efff671c805c9fa1893bc41a9076436bff1a10f8a5bfa59f5cf01e22cfe6",
+    "dist/2023-08-22/rust-std-beta-thumbv6m-none-eabi.tar.gz": "3d88eb30d86fe6f486f45bd36d53667f1f886636235f16ac197eb1b6287d228b",
+    "dist/2023-08-22/rust-std-beta-thumbv6m-none-eabi.tar.xz": "69907d0d70f4a70ca5d28cb9ce19824c6cccc85db206b6b993516980dd469a51",
+    "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabi.tar.gz": "7bedf1b999e78505f61b409dad228877c92def1df273d58347f8379e8496c0f1",
+    "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabi.tar.xz": "125b71e59a23077ab7b5e618a48022c467d5e9c4d8e069ed101f9d9634a9e2cf",
+    "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "6e396659da4b82f5d66168569f9f8d7283b506d56423916a6e506f489557e07a",
+    "dist/2023-08-22/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "830981defa1a25be5fb9e7367126802a4f3c50f251bc5b77c80693189a02fe2c",
+    "dist/2023-08-22/rust-std-beta-thumbv7m-none-eabi.tar.gz": "7d457a6697ea4f0786036791b0769fc581ef44c748ce76717e84f93776af4de5",
+    "dist/2023-08-22/rust-std-beta-thumbv7m-none-eabi.tar.xz": "03551f2cc2ed4337db19c0b6dd9d7e155988dc7a9d8ed0914ee2fdb4a0e83f9b",
+    "dist/2023-08-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "b209802836c48d3ba7b61b31b1192e2b0eaf38333c307541004c4ff2bbc83453",
+    "dist/2023-08-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "6ec3cbe221f47c412b6f45bb8a3ceb039078462be5a64c3f226595c276aa40c1",
+    "dist/2023-08-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "ef40a875465653f636270fd610def70c2b6d1fd0f3cc5622736ea3d9fccfeb1c",
+    "dist/2023-08-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "79060f7930e9e6ffa1aedfb1f5926b96541fccd4b6e861fc2b9452ef5eca77a2",
+    "dist/2023-08-22/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "2f33509dc88e1033cbb8b3478b1f7c27065eccb12d54b65a4cdbf331be111636",
+    "dist/2023-08-22/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "2b92276477d70ea1f02befe72d7a18dc65a1c727dcc5e6ca6e13b0e6d6395648",
+    "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "d4e70b2edcbbd81bd68635b067f413de2c4fae69227f70cb78d9a3a90c0cae7d",
+    "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "c01c168943c37de7b5c76a49ae329327c45e7eedd65419f47523b26a1ab7aae6",
+    "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "7cf03fca058895f05cb583248fd25526f8d54d2607cc484aac63581312162ea0",
+    "dist/2023-08-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "18c8bcd69494f91938e51b8b9cc0dac01533be3b380e5c939096eb35ba7cbe34",
+    "dist/2023-08-22/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "550440258ce3b993180c285ce9ad363a0e604704d92f924018bff5be68a94944",
+    "dist/2023-08-22/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "0622611a929a752ecf2c15e6590b6a50ec3fdfa0c7b0fc9f927be3a641ef6fee",
+    "dist/2023-08-22/rust-std-beta-wasm32-unknown-unknown.tar.gz": "338f5bc7db5648b9b578889bf197fdb120c7c1b6be6a6c41b1e1efab2b19d87a",
+    "dist/2023-08-22/rust-std-beta-wasm32-unknown-unknown.tar.xz": "6fe28fa351a51f48051010aab7399d9a9bc43b7c60fb9ec5dc8a0323f6ebfcea",
+    "dist/2023-08-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.gz": "b2d3aeba309f689f20902e41058c400f79f28c9fd8b9b03e4bb0562d1ed9e087",
+    "dist/2023-08-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.xz": "1d1de7bec3f1744082e0805601a6058ecc39d14064456d9910640a4f1f84604a",
+    "dist/2023-08-22/rust-std-beta-wasm32-wasi.tar.gz": "45ec2a9e021e7d7b521349a69f85efbac748f8b4abda6212bb0c7273f8053d0e",
+    "dist/2023-08-22/rust-std-beta-wasm32-wasi.tar.xz": "53bb87e58a84e5afa029d66e5dfe85a6e9ca8b5987c5543af6eb039f052b428c",
+    "dist/2023-08-22/rust-std-beta-x86_64-apple-darwin.tar.gz": "7acc137790fa64ebe1ff5152abd86f42c643ad6d858f130d1b210d80e98893b5",
+    "dist/2023-08-22/rust-std-beta-x86_64-apple-darwin.tar.xz": "b9da0c71bbe58c152f39a3f3f79308a49fcbc41944211024c097c156e124a56c",
+    "dist/2023-08-22/rust-std-beta-x86_64-apple-ios.tar.gz": "915831f0eb14aac95e1416fadaff2b6e0ede3f6968fb5b941986004eb389b887",
+    "dist/2023-08-22/rust-std-beta-x86_64-apple-ios.tar.xz": "2f7df0e1c43eb73232db1f888d42a639deb4d69e6cb09d11581b23687131f6d0",
+    "dist/2023-08-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "89203b4d908fde29b0fe45d0e1665cbcee7c34d40bdfbce6d97e31b7d608136a",
+    "dist/2023-08-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "9d006df537590eb7d1ec8014348103d3a1d91bd2e627ebcc4f179e83737b4915",
+    "dist/2023-08-22/rust-std-beta-x86_64-linux-android.tar.gz": "0569509106e866b3a06cc814f928481f0a06859d498440196d5994f23591b5cb",
+    "dist/2023-08-22/rust-std-beta-x86_64-linux-android.tar.xz": "dac7a334e980f4525b126d33e9609edcc3aad12c3fb011d715a0722d68722dd1",
+    "dist/2023-08-22/rust-std-beta-x86_64-pc-solaris.tar.gz": "1a34ab28dda35646171ef49f0a7274943bdaa8bc73a15261d16decec2ecb64c9",
+    "dist/2023-08-22/rust-std-beta-x86_64-pc-solaris.tar.xz": "55a1c71616a85144950cfd92fa7f64471396d5e2c8744bc936c3fcc209bead1b",
+    "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "d60cfada9d49c518d90dc0b4040bef383f857a15c6dd9e9983b8fdbfe8b24ea6",
+    "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "1102177596d61d23b5f9c9a93ec31fe5d9e0f271d7b49edbd47bcd59f4309ed2",
+    "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "0383b7094b6c02266c144223c868ead1edaf55517bdab7e94953f8282bc4420e",
+    "dist/2023-08-22/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "b2933c0d4600cdbcafd22196b70158721c0a16e864ff292fd6b919fad05355d2",
+    "dist/2023-08-22/rust-std-beta-x86_64-sun-solaris.tar.gz": "a5b0092f5a045601bed31bdb83dd7f15a332f7579a624f073103c67e7a57af7a",
+    "dist/2023-08-22/rust-std-beta-x86_64-sun-solaris.tar.xz": "1b0111216a66e7d7ae9b7b996567e932dcf7b50e202bba9281d1dfd704e26e3e",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "cc5e94874385ae0ec2a9a8dbb3efafdb88fc5134cb2be4f378298c9e413e18b4",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "9653bf3ea33bf9502eb90b72c0696af0cc90dea54e9d6e5be97783db3e8286bc",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "6193c991d35a6fc0386b42ff1944f473ffa95012ca2fb43008200d6e5cb78d78",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "3a6c169f6f09d7bda84aaffa348a1b379cfe221b567b67ad35391b9e5e3e34ca",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-illumos.tar.gz": "6299ee2cf0aaa5da48aab83230f55effeebf47a72ccd7dd27b4649629d5f3b6b",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-illumos.tar.xz": "7fc1c33439be25983b4a02c8fa4b783e3187f94f6109e4f4deaf64cb83e124b5",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "76b1bda97f8c56213d4cc39e8d8cde59f0e6a50e9ac209b70b163dc58e346f52",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "14ef16f6c0e545badc8b49b16a9ead85cb4cc2c5e6f74105fea039866eddf111",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "df96bcc3a4f3c6c028fb7252057bbf8367b73061d6cdeb50c4e28211f96d46b0",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "2fa0fae38e0b8633065313fda983503a74c436798bf7f76e1c58ca76e8767491",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "f3ec6da0eded1e8b042e1d4d8de9161e0e1af7998618315aff462892573302a1",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "34ad894da8a3e315832adf6ae7ea7bef486219bd2c1011f849a47092cde958b4",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "3ec57e0485fa7e30ef93939fecf945a24fd47bef044eb0a91652ce6d8c8e5e50",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "02fb83bd1e43d10fc6afd3113c29fdb917e87bff0f039421ce297eff91351bde",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-none.tar.gz": "97f65c1033980d6746d894d9cdef3793029d80e4820295b9a3128df497acb4ae",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-none.tar.xz": "add0537d2ae67b696896368b7aa94f7357b0b6c313097f9eec00bd8f00395a7d",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-redox.tar.gz": "7149623b9e584e41f0f6233aeb05a5aaff57a118cf13c41306e18eaf23de5929",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-redox.tar.xz": "48be526da0d8a8dadeb4e7418a49a07396e132001034282515b859eba7c64d14",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-uefi.tar.gz": "dc14c0faec4cbfa1572102aa5cb2148a58a9c120b40fcd3f092a839f58007dfc",
+    "dist/2023-08-22/rust-std-beta-x86_64-unknown-uefi.tar.xz": "ac0f60f26c61dcc659aa061be217d161099f404d38dd158f5a6f214143c308df",
+    "dist/2023-08-22/rustc-beta-aarch64-apple-darwin.tar.gz": "15b0448e87b74a06cc5f21431beb452884b836fb12ea8ccbbaaaa571bbbcd2d1",
+    "dist/2023-08-22/rustc-beta-aarch64-apple-darwin.tar.xz": "81044b7c60f619f58e5e21da1ccab36c2ce6da364aced4d7df403718f81f4ed2",
+    "dist/2023-08-22/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "c9f89bdf460cdfd50d11817aa2096de7a25d23be63f8e2e45de460bc7a221722",
+    "dist/2023-08-22/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "a484613c8b31462985ec6db77343298111e23b9034143fa528ebeccf00bedef5",
+    "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "1de5c389e1b60a8b585d35f44228466e1a6977b34c37067f11649aa7e703e1e4",
+    "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "424d6192234aa52a21acf10ee4339a9af293bb07e94c9cede67b4f82e421374d",
+    "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "bb7ac313a0d2c02eb59061a2d17672f0a73486cb6045e3ab43fef610fe32eacb",
+    "dist/2023-08-22/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "246e61b5674c3fdd2a11d033a987ead6dcc02b20301db791cfb1f31fe2bccc67",
+    "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "5380406b9921dc72ab29afcda33bb3d7dfab593c54ae3d5b3054d7a4f526befc",
+    "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "5834f4ab2100b21dd4c1313d2a58bed761543d60a0df5cc9e9d8ce1d086638f2",
+    "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "8a9aa58e47d9463aa71952c4c8e214f230c23f7c5a8c55706da02a84e31120aa",
+    "dist/2023-08-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "f832bd965354c1f6a8b982693ce66037a0a4b5eb242a915ab84a1545e90be598",
+    "dist/2023-08-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "da4fca6be3d3df88383cbd5f10556789e5f3bd16e05b4c09543edb14dcc8ce8b",
+    "dist/2023-08-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "d499d8b50ebc3af595872b359e40a41689adfe2a9ea7c7149cf556956370a5ab",
+    "dist/2023-08-22/rustc-beta-i686-pc-windows-gnu.tar.gz": "6e841881e0393b438e33f3c16f1d24a7036781844ac4eebf79042a33499f0f3d",
+    "dist/2023-08-22/rustc-beta-i686-pc-windows-gnu.tar.xz": "fe096f5ed90a3a2cf1d5da74c6b8e081b36dd868c4a1b6ea51e4a2e13cee2794",
+    "dist/2023-08-22/rustc-beta-i686-pc-windows-msvc.tar.gz": "b2b9485f44a0e25aaa56b3d1f82f1f6f224683800688ee4482d1c4025c337d03",
+    "dist/2023-08-22/rustc-beta-i686-pc-windows-msvc.tar.xz": "2c0e8c9ed8cae5e37ef60f1c5fc55f4370a260bad70cd675fa79d78737f9ca1f",
+    "dist/2023-08-22/rustc-beta-i686-unknown-linux-gnu.tar.gz": "27ba8f3457389683db058dbbee48b6844b9be5c0fc23711c00300b28a8b4f17b",
+    "dist/2023-08-22/rustc-beta-i686-unknown-linux-gnu.tar.xz": "2b45ee2cd1cb093bda5154280d0c81573fcdf512841ac5fbc1d1edb460da7c58",
+    "dist/2023-08-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "af5f367d0b97719ef4d3606276881015f069338d002ae3af8ad5be58f0778c2c",
+    "dist/2023-08-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "a37e870c5e25e9b4c3de30922461f756306424a7f85ab22da84c88b647c56100",
+    "dist/2023-08-22/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "7df41c44859a38a2652dd3a23524e75157283b276cb621e2c4dd04185841bd61",
+    "dist/2023-08-22/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "60ece70118660eff11744f6fde293b2dc27bd18a0b7d0cfd81e22c195a13a828",
+    "dist/2023-08-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "50bb7eec6172dde937dc8f9b3d6d3fcced7f896a19eb7fc82f83685a9745e293",
+    "dist/2023-08-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "23eec58bee6d42200d88b16ff0fa3977ab0223578369fc6a69787b5a52c44c62",
+    "dist/2023-08-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "051b46807d53e72a61ee38c28466620b2a03f9b5ebadde3c1c8b6dcbb35b6b7a",
+    "dist/2023-08-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "60382fa331885257998ea7fa93e55e47dddedaab04e962b21330c90ab61f4714",
+    "dist/2023-08-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "24e89e00a5e10256f41dba5f07009c2b2ea82ffdf54b6a9c3fea6b13daa2891b",
+    "dist/2023-08-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "5468061289f37b2014fcc52699ab8979a33ebeffb1c45e23a78607ec7589b3a2",
+    "dist/2023-08-22/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "34e892a6f59b53b2c7252045de9eabe437ff9d01accb051c74ce7912ab2fddc3",
+    "dist/2023-08-22/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "9fce7533f11da73efc00b31f5728ca1201c29915673b966840b2e0228f93aa74",
+    "dist/2023-08-22/rustc-beta-x86_64-apple-darwin.tar.gz": "41602031cb330fe01bd40e17ebf19a3925875f217604bde070e4c8536e971176",
+    "dist/2023-08-22/rustc-beta-x86_64-apple-darwin.tar.xz": "f19b3fa42e68810fd70a294206fdd8387dc9364fb5cde34cf87ef1ccd6aa6234",
+    "dist/2023-08-22/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "bbe52f430c7e9fd369341bc3c2931b79d79ee02c68d6a1a91919f5c09fff4e03",
+    "dist/2023-08-22/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "3f96c6b646bafb6104ce64eab83fd9c75734bd7e8b53b0b6db143b5a44fc1cb8",
+    "dist/2023-08-22/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "0a70402149eb92027265d5ea27c08fd14b0837a488c210f8ca7386981eea8f54",
+    "dist/2023-08-22/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "614228860c1f94fce353d279ee8dcb9ad3a7daa7233341c8c8e51035d6dcaefe",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-freebsd.tar.gz": "8a28760c696bda3e79306fc68c3c9a7b05b2a8ddc5008876f27029fdcbbc91dc",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-freebsd.tar.xz": "b21b5e26ccb28c2bf8a089a6f62abc4d10d6a4aabadf694aff8273150e6e7673",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-illumos.tar.gz": "d46020acb9676fc928c50d1042c2db820f27708e8dd7d708cbbe1056f787583a",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-illumos.tar.xz": "e92ded96d7663211d513c5dbefa2367d3c2e7ec3d37ff435884c25a2dc8761b4",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "65e7494ba34014b63d43e95662440b4d70c8ba2f43e6a22ada051f31a83c3620",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "960aef4123b24c63427c6d1bd92dda8417126c589def5213d972057d011caae6",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "4cd355a18503b2a3d081f77d9ac07e6cbc4d273b6cdabf4f9f05aef398cc39d6",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "97b5013d624a203c5906f5eaa82c3a47716e1612534698270082e47a06cc13d5",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-netbsd.tar.gz": "59da6428300c6b406da96142ada02d0fa9b3f1b5938c457ded9afc8d52c73046",
+    "dist/2023-08-22/rustc-beta-x86_64-unknown-netbsd.tar.xz": "c549da0eed22ec875603d42152134780f34acc40e4ba9ddd36f4f31e78a17dfb",
+    "dist/2023-08-22/rustc-nightly-aarch64-apple-darwin.tar.gz": "e80a43c2bbadff8b7976673d94228d7326a6e871cdf12d802f663b2773c6f187",
+    "dist/2023-08-22/rustc-nightly-aarch64-apple-darwin.tar.xz": "e90eb430d5485ea4f431952a68e6ceb9de8f6b92ccb64675059970b512ba539f",
+    "dist/2023-08-22/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "b21f280c54b5b0820f48767df4c611b7554c3bc5427194a1fe7e632cab7827ac",
+    "dist/2023-08-22/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "f2812b599f99858485d91b349a570bacab343db4bc622d8134a9993ce0da7471",
+    "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "059d6f34def7e471b9970713bdedf4ed3f83fc3d9b6a6f28e510b5e28d3a9413",
+    "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "95b36f95b1e697922b6dceeaceb74da030d436340cb4ba764101c218c3bcb786",
+    "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "ffdd8605187f7f6696586b7c7ab38300bb3d119e23726205d7f8a0a0bd102e90",
+    "dist/2023-08-22/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "7e1df24c13f88a49eae939930a8dceaa6dd6a23c1dbec16e3fa4f18c4bcced15",
+    "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "1a36c109a723388c322afa3fb7b7f64c9f38423a3894b8ebcd9aced032ba1bdb",
+    "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "f689a7d295e13a14e379efdf0c9a59f6ee5b8d4ee45e21ff68c684575c26e866",
+    "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "a60de4bbe5cb6ebb6081ba19d86f586661666cc40c74102a13b54f175930e561",
+    "dist/2023-08-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "b57f05ddd91bce96f61b24a93cbf9ce61bdf82d15976c44427797a0692388cc1",
+    "dist/2023-08-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "ce3ea06a26eb6345c98b7bad9943ce70e67e145ae5dc082e4bfde2c897c1aea0",
+    "dist/2023-08-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "5021ab61e2988e3f2f3a1531609621db7a2e1fc72eeae4338e3d16b40043d769",
+    "dist/2023-08-22/rustc-nightly-i686-pc-windows-gnu.tar.gz": "3bbf47ed743a313ea3d2def98173d323a13959e1bcfc8cd2f07a86997a0c2f51",
+    "dist/2023-08-22/rustc-nightly-i686-pc-windows-gnu.tar.xz": "578b6d37a9caca822102b3d484fb6bc32338d9ac72c423f4c1479835db446ae9",
+    "dist/2023-08-22/rustc-nightly-i686-pc-windows-msvc.tar.gz": "22798dc3d624f06a14908cf18658246045fd321566f786e6f75ce7a0d762a4c1",
+    "dist/2023-08-22/rustc-nightly-i686-pc-windows-msvc.tar.xz": "0c8d2fa9cb8a5cfab2c51792644c8ca436aef7bfc9d0c1950f9976fc4480f402",
+    "dist/2023-08-22/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "52a7969782803b0f15debd0df1876e033b05e93506e1d9662a98c0aa175c043b",
+    "dist/2023-08-22/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "69a79df0344f0279848bdbea5e8158d7a45f6d8c8966ecb5a055be064750d5a3",
+    "dist/2023-08-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "2fbd751601bd1cb94f064f4ff00ea1c909db059661524aa49b9e56f5ede07a52",
+    "dist/2023-08-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "5d51a4ac70e5b34304cd8dd05333d2d5933977e03e386bbe10cf8e43eec2e5c6",
+    "dist/2023-08-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "73f57e1a2d6056ae14ce6ab5ec7068241acfe59882bc2521de60d11d2dac3ee7",
+    "dist/2023-08-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "82faa86f7d1be9f184eec46a7c135787c37c750bb667f05bd3b872f55fbe2935",
+    "dist/2023-08-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "3f5e3ea359e2f7377b1d44d3cfb8516e23725e919deb5ebb32f96e8612ab2e6c",
+    "dist/2023-08-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "e156e85b6070a5155331eabb3c3de91279a56628b892a313561ed866b9667c93",
+    "dist/2023-08-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "83a9082d158c1093a98c75fdde9f65c729b245cf40cc06d88731e473a9ec0cba",
+    "dist/2023-08-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "61bbaf76b250a6e292d99a65a95127daa6cf0075cbdedf68033cfccd221bf8bd",
+    "dist/2023-08-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "6574e5cfac1a56cc3ec20352eebe6c6bb0825a1060df48893866909fb7005321",
+    "dist/2023-08-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ad2240a704fca3320dccaa2bbbbe52a5b2df2556967cae4efa40334c36f66a59",
+    "dist/2023-08-22/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "c319fe1d20e9520b1d6c033cfd04f91286d68637caea7d2e43e335f9d9397527",
+    "dist/2023-08-22/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "1c52cb26303f89969190c06580206d1f5d511c91c63fccde78e515930f9da4dc",
+    "dist/2023-08-22/rustc-nightly-x86_64-apple-darwin.tar.gz": "db6e355efddd7aa18f3fec72d87df4b91794c8b8c07236d6d9454d5912c9994b",
+    "dist/2023-08-22/rustc-nightly-x86_64-apple-darwin.tar.xz": "afbfca7d7c7f8a94575269098f6166729bfb441b657ea77f7de6621e0a9a3f87",
+    "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "7bfcbbbfe4adab954e9c70b8ea6bfb9d52116782dcdeb9b5be147430c4f242e0",
+    "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "05e7e901fa944075ea20d65d81f80986c51699c2ac5c5a2cfa2e5a07c16f4b0d",
+    "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "74d07b4289dd2f382c7ef5881ed24a1f99c44b9805857d15a8d45d0c7fea623e",
+    "dist/2023-08-22/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "25bb5590a8107f6525c4987291f8f46360ffdf67dd47f7087a2c9e441e20296f",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "727fcc6ee093e8b105560b6f9644451aa5fb5f88e12e883a270a094ee47aa3bf",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "c33d57fc3783bead4c54352ccfa4b4f129e34e16970efdd872b562fe99e1652d",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-illumos.tar.gz": "c1f4fd00eea1e5fcd64e0eecbf7daec3a39d72822b4792c12c3885bb7d34048d",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-illumos.tar.xz": "ba3783813d65a4be685c3720c865365f03b9124938e02be790c438d212fa1bb1",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "7a0365317617af7b18f535f39e2a8da23cd8f1b7ff95be9af1de9b6d4ae461de",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "bdd970bee618fc6299249ec162ab7e38efdf52c77cd431ad9268f327a6f0905d",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "43f5736c02efbc0170d23124976546b3fc03b2a30582c3685cb53f7417359692",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "3abf2518323294fcc0decc9e3f01bf610116b8f42b07fa9d34769bd438ae17f9",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "1dc5af741b22db8bf16ef7eb05821ef0d5b3e518244867a2bba484a773a03b9e",
+    "dist/2023-08-22/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "4c2e5268a6a4537c67795c89c45a414e9b001068017aff0b6ea73c1b2e9d95c2",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "606431eea9341f6ee2079ef919d34e583678f8f1e0bcd66fa73eea9175996a77",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "b122cc0367be4b5433eba7e1b2ca919ec265cd31c5b1766e4853b947d16268b5",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "094456d974c3bff34b4ea47f159a2e12dc41c0c88ab710debfb63ecba102b6f1",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "e777f86c75261bfcc3dcb2c7e91ad4052a7e6263b59dd78d6e5a50a43cb9de1b",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "82b9bd94ef7065587471716fd7848bdfbe0d0938df7832b035d78274e51598fc",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "d8453e40ca7819830e9ef8bb3c3086a4708479cd01aa3434fa878bbdb0e21cc2",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "17e913c782aef22a021c75c204f04d290f6abfc76ac3c2fc899bf3ba2b96e8e5",
+    "dist/2023-08-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "97b145924a76dc1f0e6d2c18c65725d0bd92308ee21d779ff1d1c3a857221ad6",
+    "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "aa36dea771d819ba1f4f2997fb8e38fc02d57da7417bba9354e499c15ab56c6b",
+    "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "c5b3ab26ec79e479de1bc93ab60e48c95e6a24931bdaf8c2e9a6508fb8d8253f",
+    "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "2639378c9e51ec50ddb739bc18d12ed43e98a5dff1a1e5cfd154c0b91f233000",
+    "dist/2023-08-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "c189e78bae3474c17f693401c9f7e13f064370ecf709e69b62a140e94c772e82",
+    "dist/2023-08-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "b7e175569f174d7422756bc3c312a1dcde78b8563cc96330772b2b7ca6458685",
+    "dist/2023-08-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "0fad29a56dea92b2083d46e9a93d186f32d162461da897e2aca1b94cf8ad259a",
+    "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "35ba679d27b08bdbb381a7517b189743e1aaaccc0f0ad33fa6397d53005f1bd6",
+    "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "37cfd4697506172d2826b1a047cd1d78e24ad32e1334fd89602a6b2dd45fecc3",
+    "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "e6dbb37669c307e235b610aa292691e2f767bafc7c90dca5f9c3db70a782914f",
+    "dist/2023-08-22/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "1df368db6dcf9bc06ef68e5c56e1961f6fef57c07b2edbdb537c5eeccc315d5b",
+    "dist/2023-08-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "bd3694c1b40d86c5729bdafa5516a827da2d741a04a3f91f955f2d1165177324",
+    "dist/2023-08-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "0ffa91610757b4c8fce43cef6d76b0f47a442dea14dc893581134e8a0237b32b",
+    "dist/2023-08-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "92ec1025ed12fabd541530124b08498abf54ad14c22a11a6cd9be54fa330b0f7",
+    "dist/2023-08-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "850ab1756cf50b9e56dab7b2dbbbdd0dab9146fa792ce3bd59af0ec5a0c1a4fd",
+    "dist/2023-08-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "02cd3b78627002f26007ece8e64808a58c80bd4362333c1150b4901c73ae6b8c",
+    "dist/2023-08-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "f453e12fad664f6a3c76de94e34ecd4a668cc26bdec982079dc8c57c9fa85c7f",
+    "dist/2023-08-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "92d7336a7e4a6a9e06f72e72b8402af0fe60bc6da7616bcee11e810a5217ec8a",
+    "dist/2023-08-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "08a96d8600357882f7b278c7e65c8be95ec153bd7059c14847b47abb4e27a28e",
+    "dist/2023-08-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "7d80dfaaa65c1237813ca8cc8c52a878d5e4dfb99b6e5051cd679bd31ce3a4ae",
+    "dist/2023-08-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "a76b23cbad7fd5838a6297b9234a5a09cf6adf0cb377910180d30caa6de2696e",
+    "dist/2023-08-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "4f74e990e6d6e2eb80c503794e55f80e554dd2b6bfecd902ccdd19841b8e83d4",
+    "dist/2023-08-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "7323dc37bb3a0ec5979e0e0818aef876010422a539971e7fbbbb39e66bbe5a70",
+    "dist/2023-08-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "cc369508a03517983bcab4f17e391d4074b002d9f3b5ec8729375b345df6cf86",
+    "dist/2023-08-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "465d88c1ca8c5e36a579d48334c60f5ce226eb4c5a851849fe76a7d8ad803154",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "d2cb215423c824355d7d450b8d555c3f7390b08911fbf5114474869d9d8d2fb8",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "d5a4e117f8d3f1a7a88dbd1e1e71fe352fafce10770d6dc1f2644eef591bfad5",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "6601080db240890b1a9b7a2af54c576b2ab112b15b504a3475fa77b0b214b309",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "a40ed6b0fcb5bc909dcbdc93b65024f155792df980a48757b71ae391dbb427cc",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "64c4a913fd398fb49823d7687932c9defc3e4d0312967a21c90e57b5a6e2ea66",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "75e814a65ccd1b3721ff6300b83aebfcd8f402f18e02df230586604cc56efb10",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "186928533dc8dc7874c56bb0ce95930d7cd76c9838a9203509c01c3f0d1e88d7",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "4bae607aa830e898d77e20397377cad51108843480a76f6d8f076bdc27a69d7e",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "1610cd254b57537c592f5d9c8d5522d03a25405db4862c18759001ced85169d6",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "2cd850cadef23f7061e88e3aed20cdbcd772badb11792f34110facb681c9846a",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "db5b9f91e2350d337c19c07c4f30419ef1a222cb7f9ad1f95c851ad2a78993fc",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "b7abfba5b3c7c5b33bd64e5caddab8a62fc7d1298e913323a3712a2af80b01da",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "bcaa9389f053f133c1bbf96a50035de0d2c1e4132a9f8deb5edf83da9da75616",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "1e2cec2188e9dcbcb23b81a9a0f22eb70143a207438853b702d5d2d90786a92a",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "afd7e619f99ebdc2095f3a0db4a55684e1919c2cf145ff3d1e18169e6e868742",
+    "dist/2023-08-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "ee05ae0326941d38704abeb44c868a326966f6dbbc3fcc79585a8ca1f84a4b21"
   }
 }
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 80eca0e58fb2ff52c1e94fc191b55b37ed73e0e
+Subproject 2cc50bc0b63ad20da193e002ba11d391af0104b
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index fdc35cd4ddf..98441e83eb4 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -10,6 +10,7 @@ use rustc_hir::{
     GenericArgs, Guard, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
     PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
 };
+use rustc_hir::MatchSource::TryDesugar;
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::TypeckResults;
@@ -311,7 +312,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
             },
             (&ExprKind::Match(le, la, ref ls), &ExprKind::Match(re, ra, ref rs)) => {
-                ls == rs
+                (ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_)))))
                     && self.eq_expr(le, re)
                     && over(la, ra, |l, r| {
                         self.eq_pat(l.pat, r.pat)
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 43523faa236..17233058c9c 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -292,7 +292,7 @@ fn check_terminator<'tcx>(
         | TerminatorKind::Goto { .. }
         | TerminatorKind::Return
         | TerminatorKind::UnwindResume
-        | TerminatorKind::UnwindTerminate
+        | TerminatorKind::UnwindTerminate(_)
         | TerminatorKind::Unreachable => Ok(()),
         TerminatorKind::Drop { place, .. } => {
             if !is_ty_const_destruct(tcx, place.ty(&body.local_decls, tcx).ty, body) {
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.rs b/src/tools/clippy/tests/ui/if_same_then_else2.rs
index c545434efe5..0b171f21d0c 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.rs
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.rs
@@ -98,7 +98,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
     };
 
     if true {
-        // FIXME: should emit "this `if` has identical blocks"
+        //~^ ERROR: this `if` has identical blocks
         Ok("foo")?;
     } else {
         Ok("foo")?;
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.stderr b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
index 37fe787d1de..56e5f3e45b2 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
@@ -83,6 +83,25 @@ LL | |     };
    | |_____^
 
 error: this `if` has identical blocks
+  --> $DIR/if_same_then_else2.rs:100:13
+   |
+LL |       if true {
+   |  _____________^
+LL | |
+LL | |         Ok("foo")?;
+LL | |     } else {
+   | |_____^
+   |
+note: same as this
+  --> $DIR/if_same_then_else2.rs:103:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |         Ok("foo")?;
+LL | |     }
+   | |_____^
+
+error: this `if` has identical blocks
   --> $DIR/if_same_then_else2.rs:124:20
    |
 LL |       } else if true {
@@ -103,5 +122,5 @@ LL | |         return Ok(&foo[0..]);
 LL | |     }
    | |_____^
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 4ef79af3124..dd4c59fdff5 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2354,14 +2354,7 @@ impl<'test> TestCx<'test> {
                 // Hide line numbers to reduce churn
                 rustc.arg("-Zui-testing");
                 rustc.arg("-Zdeduplicate-diagnostics=no");
-                // #[cfg(not(bootstrap)] unconditionally pass flag after beta bump
-                // since `ui-fulldeps --stage=1` builds using the stage 0 compiler,
-                // which doesn't have this flag.
-                if !(self.config.stage_id.starts_with("stage1-")
-                    && self.config.suite == "ui-fulldeps")
-                {
-                    rustc.arg("-Zwrite-long-types-to-disk=no");
-                }
+                rustc.arg("-Zwrite-long-types-to-disk=no");
                 // FIXME: use this for other modes too, for perf?
                 rustc.arg("-Cstrip=debuginfo");
             }
@@ -2483,13 +2476,8 @@ impl<'test> TestCx<'test> {
             rustc.args(&["-A", "unused"]);
         }
 
-        // #[cfg(not(bootstrap)] unconditionally pass flag after beta bump
-        // since `ui-fulldeps --stage=1` builds using the stage 0 compiler,
-        // which doesn't have this lint.
-        if !(self.config.stage_id.starts_with("stage1-") && self.config.suite == "ui-fulldeps") {
-            // Allow tests to use internal features.
-            rustc.args(&["-A", "internal_features"]);
-        }
+        // Allow tests to use internal features.
+        rustc.args(&["-A", "internal_features"]);
 
         if self.props.force_host {
             self.maybe_add_external_args(&mut rustc, &self.config.host_rustcflags);
@@ -3634,26 +3622,30 @@ impl<'test> TestCx<'test> {
         let expected_stderr = self.load_expected_output(stderr_kind);
         let expected_stdout = self.load_expected_output(stdout_kind);
 
-        let normalized_stdout = match output_kind {
+        let mut normalized_stdout =
+            self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
+        match output_kind {
             TestOutput::Run if self.config.remote_test_client.is_some() => {
                 // When tests are run using the remote-test-client, the string
                 // 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"'
                 // is printed to stdout by the client and then captured in the ProcRes,
-                // so it needs to be removed when comparing the run-pass test execution output
+                // so it needs to be removed when comparing the run-pass test execution output.
                 static REMOTE_TEST_RE: Lazy<Regex> = Lazy::new(|| {
                     Regex::new(
                         "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n"
                     )
                     .unwrap()
                 });
-                REMOTE_TEST_RE
-                    .replace(
-                        &self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout),
-                        "",
-                    )
-                    .to_string()
+                normalized_stdout = REMOTE_TEST_RE.replace(&normalized_stdout, "").to_string();
+                // When there is a panic, the remote-test-client also prints "died due to signal";
+                // that needs to be removed as well.
+                static SIGNAL_DIED_RE: Lazy<Regex> =
+                    Lazy::new(|| Regex::new("^died due to signal [0-9]+\n").unwrap());
+                normalized_stdout = SIGNAL_DIED_RE.replace(&normalized_stdout, "").to_string();
+                // FIXME: it would be much nicer if we could just tell the remote-test-client to not
+                // print these things.
             }
-            _ => self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout),
+            _ => {}
         };
 
         let stderr = if explicit_format {
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index 45a9c93ee0b..9bd04e11cb3 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -12,7 +12,7 @@ pub(crate) enum Kind {
     Enum,
     Variant,
     Function,
-    Typedef,
+    TypeAlias,
     OpaqueTy,
     Constant,
     Trait,
@@ -45,7 +45,7 @@ impl Kind {
             Trait => true,
             TraitAlias => true,
             Impl => true,
-            Typedef => true,
+            TypeAlias => true,
             Constant => true,
             Static => true,
             Macro => true,
@@ -98,7 +98,7 @@ impl Kind {
             Kind::Union => false,
             Kind::Enum => false,
             Kind::Variant => false,
-            Kind::Typedef => false,
+            Kind::TypeAlias => false,
             Kind::OpaqueTy => false,
             Kind::Constant => false,
             Kind::Trait => false,
@@ -131,7 +131,7 @@ impl Kind {
         matches!(self, Kind::Trait | Kind::TraitAlias)
     }
     pub fn is_type(self) -> bool {
-        matches!(self, Kind::Struct | Kind::Enum | Kind::Union | Kind::Typedef)
+        matches!(self, Kind::Struct | Kind::Enum | Kind::Union | Kind::TypeAlias)
     }
 
     pub fn from_item(i: &Item) -> Self {
@@ -148,7 +148,7 @@ impl Kind {
             ItemEnum::Trait(_) => Trait,
             ItemEnum::TraitAlias(_) => TraitAlias,
             ItemEnum::Impl(_) => Impl,
-            ItemEnum::Typedef(_) => Typedef,
+            ItemEnum::TypeAlias(_) => TypeAlias,
             ItemEnum::OpaqueTy(_) => OpaqueTy,
             ItemEnum::Constant(_) => Constant,
             ItemEnum::Static(_) => Static,
@@ -186,7 +186,7 @@ impl Kind {
             ItemKind::StructField => StructField,
             ItemKind::Trait => Trait,
             ItemKind::TraitAlias => TraitAlias,
-            ItemKind::Typedef => Typedef,
+            ItemKind::TypeAlias => TypeAlias,
             ItemKind::Union => Union,
             ItemKind::Variant => Variant,
         }
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index bf8a64acf08..592e97310a4 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -5,7 +5,7 @@ use rustdoc_json_types::{
     Constant, Crate, DynTrait, Enum, FnDecl, Function, FunctionPointer, GenericArg, GenericArgs,
     GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, ItemSummary, Module,
     OpaqueTy, Path, Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias,
-    Type, TypeBinding, TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate,
+    Type, TypeAlias, TypeBinding, TypeBindingKind, Union, Variant, VariantKind, WherePredicate,
 };
 use serde_json::Value;
 
@@ -37,7 +37,7 @@ pub struct Validator<'a> {
 
 enum PathKind {
     Trait,
-    /// Structs, Enums, Unions and Typedefs.
+    /// Structs, Enums, Unions and TypeAliases.
     ///
     /// This doesn't include trait's because traits are not types.
     Type,
@@ -99,7 +99,7 @@ impl<'a> Validator<'a> {
                 ItemEnum::Trait(x) => self.check_trait(x, id),
                 ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
                 ItemEnum::Impl(x) => self.check_impl(x, id),
-                ItemEnum::Typedef(x) => self.check_typedef(x),
+                ItemEnum::TypeAlias(x) => self.check_type_alias(x),
                 ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
                 ItemEnum::Constant(x) => self.check_constant(x),
                 ItemEnum::Static(x) => self.check_static(x),
@@ -221,7 +221,7 @@ impl<'a> Validator<'a> {
         }
     }
 
-    fn check_typedef(&mut self, x: &'a Typedef) {
+    fn check_type_alias(&mut self, x: &'a TypeAlias) {
         self.check_generics(&x.generics);
         self.check_type(&x.type_);
     }
@@ -450,7 +450,7 @@ impl<'a> Validator<'a> {
     }
 
     fn add_type_id(&mut self, id: &'a Id) {
-        self.add_id_checked(id, Kind::is_type, "Type (Struct, Enum, Union or Typedef)");
+        self.add_id_checked(id, Kind::is_type, "Type (Struct, Enum, Union or TypeAlias)");
     }
 
     /// Add an Id that appeared in a trait
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 550c9650fb3..98f82ec9a0f 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -975,9 +975,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         ecx.start_panic_nounwind(msg)
     }
 
-    fn unwind_terminate(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
+    fn unwind_terminate(ecx: &mut InterpCx<'mir, 'tcx, Self>, reason: mir::UnwindTerminateReason) -> InterpResult<'tcx> {
         // Call the lang item.
-        let panic = ecx.tcx.lang_items().panic_cannot_unwind().unwrap();
+        let panic = ecx.tcx.lang_items().get(reason.lang_item()).unwrap();
         let panic = ty::Instance::mono(ecx.tcx.tcx, panic);
         ecx.call_function(
             panic,
@@ -1405,4 +1405,22 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         }
         res
     }
+
+    fn after_local_allocated(
+        ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        frame: usize,
+        local: mir::Local,
+        mplace: &MPlaceTy<'tcx, Provenance>
+    ) -> InterpResult<'tcx> {
+        let Some(Provenance::Concrete { alloc_id, .. }) = mplace.ptr.provenance else {
+            panic!("after_local_allocated should only be called on fresh allocations");
+        };
+        let local_decl = &ecx.active_thread_stack()[frame].body.local_decls[local];
+        let span = local_decl.source_info.span;
+        ecx.machine
+            .allocation_spans
+            .borrow_mut()
+            .insert(alloc_id, (span, None));
+        Ok(())
+    }
 }
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.rs
new file mode 100644
index 00000000000..393127341ca
--- /dev/null
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.rs
@@ -0,0 +1,13 @@
+// The interpreter tries to delay allocating locals until their address is taken.
+// This test checks that we correctly use the span associated with the local itself, not the span
+// where we take the address of the local and force it to be allocated.
+
+fn main() {
+    let ptr = {
+        let x = 0usize; // This line should appear in the helps
+        &x as *const usize // This line should NOT appear in the helps
+    };
+    unsafe {
+        dbg!(*ptr); //~ ERROR: has been freed
+    }
+}
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr
new file mode 100644
index 00000000000..bdc9c31db40
--- /dev/null
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_primitive.stderr
@@ -0,0 +1,26 @@
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
+  --> $DIR/dangling_primitive.rs:LL:CC
+   |
+LL |         dbg!(*ptr);
+   |         ^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
+   |
+   = 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
+help: ALLOC was allocated here:
+  --> $DIR/dangling_primitive.rs:LL:CC
+   |
+LL |         let x = 0usize; // This line should appear in the helps
+   |             ^
+help: ALLOC was deallocated here:
+  --> $DIR/dangling_primitive.rs:LL:CC
+   |
+LL |     };
+   |     ^
+   = note: BACKTRACE (of the first span):
+   = note: inside `main` at RUSTLIB/std/src/macros.rs:LL:CC
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr b/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr
index fe039ef3ada..92b1fcb1145 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/deref-partially-dangling.stderr
@@ -6,7 +6,12 @@ LL |     let val = unsafe { (*xptr).1 };
    |
    = 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
-   = note: BACKTRACE:
+help: ALLOC was allocated here:
+  --> $DIR/deref-partially-dangling.rs:LL:CC
+   |
+LL |     let x = (1, 13);
+   |         ^
+   = note: BACKTRACE (of the first span):
    = note: inside `main` at $DIR/deref-partially-dangling.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr
index 33aa6c84410..95a50bc8750 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.stderr
@@ -6,7 +6,12 @@ LL |     let _ptr = unsafe { &*ptr };
    |
    = 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
-   = note: BACKTRACE:
+help: ALLOC was allocated here:
+  --> $DIR/dyn_size.rs:LL:CC
+   |
+LL |     let buf = [0u32; 1];
+   |         ^^^
+   = note: BACKTRACE (of the first span):
    = note: inside `main` at $DIR/dyn_size.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr
index 500f28a3cbc..4d2dfe28aed 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr
@@ -6,7 +6,17 @@ LL |         let val = *x;
    |
    = 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
-   = note: BACKTRACE:
+help: ALLOC was allocated here:
+  --> $DIR/stack_temporary.rs:LL:CC
+   |
+LL |         let x = make_ref(&mut 0); // The temporary storing "0" is deallocated at the ";"!
+   |                               ^
+help: ALLOC was deallocated here:
+  --> $DIR/stack_temporary.rs:LL:CC
+   |
+LL |         let x = make_ref(&mut 0); // The temporary storing "0" is deallocated at the ";"!
+   |                                 ^
+   = note: BACKTRACE (of the first span):
    = note: inside `main` at $DIR/stack_temporary.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_1.stderr b/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_1.stderr
index 4422310870a..e1102a6d216 100644
--- a/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_1.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_1.stderr
@@ -6,7 +6,12 @@ LL |     let x = unsafe { x.offset(5) };
    |
    = 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
-   = note: BACKTRACE:
+help: ALLOC was allocated here:
+  --> $DIR/out_of_bounds_ptr_1.rs:LL:CC
+   |
+LL |     let v = [0i8; 4];
+   |         ^
+   = note: BACKTRACE (of the first span):
    = note: inside `main` at $DIR/out_of_bounds_ptr_1.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_3.stderr b/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_3.stderr
index 1364e0f9009..99f28b3e4f8 100644
--- a/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_3.stderr
+++ b/src/tools/miri/tests/fail/intrinsics/out_of_bounds_ptr_3.stderr
@@ -6,7 +6,12 @@ LL |     let x = unsafe { x.offset(-1) };
    |
    = 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
-   = note: BACKTRACE:
+help: ALLOC was allocated here:
+  --> $DIR/out_of_bounds_ptr_3.rs:LL:CC
+   |
+LL |     let v = [0i8; 4];
+   |         ^
+   = note: BACKTRACE (of the first span):
    = note: inside `main` at $DIR/out_of_bounds_ptr_3.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr
index 25c9a7c44bc..9efba031250 100644
--- a/src/tools/miri/tests/fail/panic/double_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/double_panic.stderr
@@ -5,7 +5,7 @@ thread 'main' panicked at $DIR/double_panic.rs:LL:CC:
 second
 stack backtrace:
 thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
-panic in a function that cannot unwind
+panic in a destructor during cleanup
 stack backtrace:
 thread caused non-unwinding panic. aborting.
 error: abnormal termination: the program aborted execution
@@ -20,7 +20,7 @@ LL |     ABORT();
    = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
    = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
-   = note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC
+   = note: inside `core::panicking::panic_in_cleanup` at RUSTLIB/core/src/panicking.rs:LL:CC
 note: inside `main`
   --> $DIR/double_panic.rs:LL:CC
    |
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index a2b263cf2d8..49e96236c51 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -999,23 +999,23 @@ checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
 
 [[package]]
 name = "lsp-server"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3711e4d6f491dc9edc0f1df80e204f38206775ac92c1241e89b79229a850bc00"
+version = "0.7.3"
 dependencies = [
  "crossbeam-channel",
  "log",
+ "lsp-types",
  "serde",
  "serde_json",
 ]
 
 [[package]]
 name = "lsp-server"
-version = "0.7.2"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72417faa455bfb4e5bf14b157d8e2ca2ed74b4e89b8cf42ea2d864825ae5c8a2"
 dependencies = [
  "crossbeam-channel",
  "log",
- "lsp-types",
  "serde",
  "serde_json",
 ]
@@ -1555,7 +1555,7 @@ dependencies = [
  "ide-ssr",
  "itertools",
  "load-cargo",
- "lsp-server 0.7.1",
+ "lsp-server 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lsp-types",
  "mbe",
  "mimalloc",
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index f6a50bfa6b2..5eb59d6db11 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -86,7 +86,7 @@ proc-macro-test = { path = "./crates/proc-macro-test" }
 # In-tree crates that are published separately and follow semver. See lib/README.md
 line-index = { version = "0.1.0-pre.1" }
 la-arena = { version = "0.3.1" }
-lsp-server = { version = "0.7.1" }
+lsp-server = { version = "0.7.3" }
 
 # non-local crates
 smallvec = { version = "1.10.0", features = [
@@ -97,7 +97,8 @@ smallvec = { version = "1.10.0", features = [
 smol_str = "0.2.0"
 nohash-hasher = "0.2.0"
 text-size = "1.1.0"
-serde = { version = "1.0.156", features = ["derive"] }
+# See https://github.com/serde-rs/serde/issues/2538#issuecomment-1684517372 for why we pin serde
+serde = { version = "1.0.156, < 1.0.172", features = ["derive"] }
 serde_json = "1.0.96"
 triomphe = { version = "0.1.8", default-features = false, features = ["std"] }
 # can't upgrade due to dashmap depending on 0.12.3 currently
diff --git a/src/tools/rust-analyzer/crates/base-db/src/fixture.rs b/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
index 323ee4260e4..aaac0fc3790 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/fixture.rs
@@ -130,6 +130,7 @@ impl ChangeFixture {
         let mut default_crate_root: Option<FileId> = None;
         let mut default_target_data_layout: Option<String> = None;
         let mut default_cfg = CfgOptions::default();
+        let mut default_env = Env::new_for_test_fixture();
 
         let mut file_set = FileSet::default();
         let mut current_source_root_kind = SourceRootKind::Local;
@@ -200,6 +201,7 @@ impl ChangeFixture {
                 assert!(default_crate_root.is_none());
                 default_crate_root = Some(file_id);
                 default_cfg = meta.cfg;
+                default_env.extend(meta.env.iter().map(|(x, y)| (x.to_owned(), y.to_owned())));
                 default_target_data_layout = meta.target_data_layout;
             }
 
@@ -220,7 +222,7 @@ impl ChangeFixture {
                 None,
                 default_cfg,
                 Default::default(),
-                Env::new_for_test_fixture(),
+                default_env,
                 false,
                 CrateOrigin::Local { repo: None, name: None },
                 default_target_data_layout
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index c47799f1320..b75c7079be7 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -686,6 +686,12 @@ impl fmt::Display for Edition {
     }
 }
 
+impl Extend<(String, String)> for Env {
+    fn extend<T: IntoIterator<Item = (String, String)>>(&mut self, iter: T) {
+        self.entries.extend(iter);
+    }
+}
+
 impl FromIterator<(String, String)> for Env {
     fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self {
         Env { entries: FromIterator::from_iter(iter) }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
index fae07111806..a5db75a91eb 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs
@@ -431,12 +431,10 @@ impl AttrsWithOwner {
                         .item_tree(db)
                         .raw_attrs(AttrOwner::ModItem(definition_tree_id.value.into()))
                         .clone(),
-                    ModuleOrigin::BlockExpr { block } => RawAttrs::from_attrs_owner(
-                        db.upcast(),
-                        InFile::new(block.file_id, block.to_node(db.upcast()))
-                            .as_ref()
-                            .map(|it| it as &dyn ast::HasAttrs),
-                    ),
+                    ModuleOrigin::BlockExpr { id, .. } => {
+                        let tree = db.block_item_tree_query(id);
+                        tree.raw_attrs(AttrOwner::TopLevel).clone()
+                    }
                 }
             }
             AttrDefId::FieldId(it) => {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
index 3853a6ab3a5..7071fcb9394 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
@@ -505,6 +505,9 @@ impl ExprCollector<'_> {
                 let mut args = Vec::new();
                 let mut arg_types = Vec::new();
                 if let Some(pl) = e.param_list() {
+                    let num_params = pl.params().count();
+                    args.reserve_exact(num_params);
+                    arg_types.reserve_exact(num_params);
                     for param in pl.params() {
                         let pat = this.collect_pat_top(param.pat());
                         let type_ref =
@@ -1100,7 +1103,9 @@ impl ExprCollector<'_> {
                 ast::Stmt::ExprStmt(es) => matches!(es.expr(), Some(ast::Expr::MacroExpr(_))),
                 _ => false,
             });
-            statement_has_item || matches!(block.tail_expr(), Some(ast::Expr::MacroExpr(_)))
+            statement_has_item
+                || matches!(block.tail_expr(), Some(ast::Expr::MacroExpr(_)))
+                || (block.may_carry_attributes() && block.attrs().next().is_some())
         };
 
         let block_id = if block_has_items {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs
index 4e015a7fbbb..44eeed9e3fb 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs
@@ -38,9 +38,9 @@ fn outer() {
 "#,
         expect![[r#"
             block scope
-            CrateStruct: t
-            PlainStruct: t v
-            SelfStruct: t
+            CrateStruct: ti
+            PlainStruct: ti vi
+            SelfStruct: ti
             Struct: v
             SuperStruct: _
 
@@ -66,7 +66,7 @@ fn outer() {
 "#,
         expect![[r#"
             block scope
-            imported: t v
+            imported: ti vi
             name: v
 
             crate
@@ -92,9 +92,9 @@ fn outer() {
 "#,
         expect![[r#"
             block scope
-            inner1: t
+            inner1: ti
             inner2: v
-            outer: v
+            outer: vi
 
             block scope
             inner: v
@@ -121,7 +121,7 @@ struct Struct {}
 "#,
         expect![[r#"
             block scope
-            Struct: t
+            Struct: ti
 
             crate
             Struct: t
@@ -153,7 +153,7 @@ fn outer() {
 "#,
         expect![[r#"
             block scope
-            ResolveMe: t
+            ResolveMe: ti
 
             block scope
             m2: t
@@ -214,7 +214,7 @@ fn f() {
 "#,
         expect![[r#"
             block scope
-            ResolveMe: t
+            ResolveMe: ti
 
             block scope
             h: v
@@ -292,7 +292,7 @@ pub mod cov_mark {
             nested: v
 
             crate
-            cov_mark: t
+            cov_mark: ti
             f: v
         "#]],
     );
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 91db68058b0..68defa3858f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -487,7 +487,7 @@ impl ExternCrateDeclData {
             db.crate_def_map(loc.container.krate())
                 .extern_prelude()
                 .find(|&(prelude_name, ..)| *prelude_name == name)
-                .map(|(_, root)| root.krate())
+                .map(|(_, (root, _))| root.krate())
         };
 
         Arc::new(Self {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index e34a6768f28..31c1a713031 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -82,6 +82,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
     #[salsa::invoke(ItemTree::file_item_tree_query)]
     fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
 
+    #[salsa::invoke(ItemTree::block_item_tree_query)]
+    fn block_item_tree_query(&self, block_id: BlockId) -> Arc<ItemTree>;
+
     #[salsa::invoke(crate_def_map_wait)]
     #[salsa::transparent]
     fn crate_def_map(&self, krate: CrateId) -> Arc<DefMap>;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
index df2af4c89b0..b60e7909105 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
@@ -11,7 +11,7 @@ use crate::{
     nameres::DefMap,
     path::{ModPath, PathKind},
     visibility::Visibility,
-    ModuleDefId, ModuleId,
+    CrateRootModuleId, ModuleDefId, ModuleId,
 };
 
 /// Find a path that can be used to refer to a certain item. This can depend on
@@ -81,7 +81,7 @@ fn find_path_inner(
     }
 
     let def_map = from.def_map(db);
-    let crate_root = def_map.crate_root().into();
+    let crate_root = def_map.crate_root();
     // - if the item is a module, jump straight to module search
     if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
         let mut visited_modules = FxHashSet::default();
@@ -149,7 +149,7 @@ fn find_path_for_module(
     db: &dyn DefDatabase,
     def_map: &DefMap,
     visited_modules: &mut FxHashSet<ModuleId>,
-    crate_root: ModuleId,
+    crate_root: CrateRootModuleId,
     from: ModuleId,
     module_id: ModuleId,
     max_len: usize,
@@ -183,7 +183,7 @@ fn find_path_for_module(
 
     // - if the item is the crate root of a dependency crate, return the name from the extern prelude
     let root_def_map = crate_root.def_map(db);
-    for (name, def_id) in root_def_map.extern_prelude() {
+    for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude() {
         if module_id == def_id {
             let name = scope_name.unwrap_or_else(|| name.clone());
 
@@ -192,7 +192,7 @@ fn find_path_for_module(
                     def_map[local_id]
                         .scope
                         .type_(&name)
-                        .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id))
+                        .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into()))
                 })
                 .is_some();
             let kind = if name_already_occupied_in_type_ns {
@@ -224,6 +224,7 @@ fn find_path_for_module(
     )
 }
 
+// FIXME: Do we still need this now that we record import origins, and hence aliases?
 fn find_in_scope(
     db: &dyn DefDatabase,
     def_map: &DefMap,
@@ -244,7 +245,7 @@ fn find_in_prelude(
     item: ItemInNs,
     from: ModuleId,
 ) -> Option<ModPath> {
-    let prelude_module = root_def_map.prelude()?;
+    let (prelude_module, _) = root_def_map.prelude()?;
     // Preludes in block DefMaps are ignored, only the crate DefMap is searched
     let prelude_def_map = prelude_module.def_map(db);
     let prelude_scope = &prelude_def_map[prelude_module.local_id].scope;
@@ -293,7 +294,7 @@ fn calculate_best_path(
     db: &dyn DefDatabase,
     def_map: &DefMap,
     visited_modules: &mut FxHashSet<ModuleId>,
-    crate_root: ModuleId,
+    crate_root: CrateRootModuleId,
     max_len: usize,
     item: ItemInNs,
     from: ModuleId,
@@ -346,6 +347,11 @@ fn calculate_best_path(
         let extern_paths = crate_graph[from.krate].dependencies.iter().filter_map(|dep| {
             let import_map = db.import_map(dep.crate_id);
             import_map.import_info_for(item).and_then(|info| {
+                if info.is_doc_hidden {
+                    // the item or import is `#[doc(hidden)]`, so skip it as it is in an external crate
+                    return None;
+                }
+
                 // Determine best path for containing module and append last segment from `info`.
                 // FIXME: we should guide this to look up the path locally, or from the same crate again?
                 let mut path = find_path_for_module(
@@ -1293,4 +1299,65 @@ pub mod prelude {
             "None",
         );
     }
+
+    #[test]
+    fn different_crate_renamed_through_dep() {
+        check_found_path(
+            r#"
+//- /main.rs crate:main deps:intermediate
+$0
+//- /intermediate.rs crate:intermediate deps:std
+pub extern crate std as std_renamed;
+//- /std.rs crate:std
+pub struct S;
+    "#,
+            "intermediate::std_renamed::S",
+            "intermediate::std_renamed::S",
+            "intermediate::std_renamed::S",
+            "intermediate::std_renamed::S",
+        );
+    }
+
+    #[test]
+    fn different_crate_doc_hidden() {
+        check_found_path(
+            r#"
+//- /main.rs crate:main deps:intermediate
+$0
+//- /intermediate.rs crate:intermediate deps:std
+#[doc(hidden)]
+pub extern crate std;
+pub extern crate std as longer;
+//- /std.rs crate:std
+pub struct S;
+    "#,
+            "intermediate::longer::S",
+            "intermediate::longer::S",
+            "intermediate::longer::S",
+            "intermediate::longer::S",
+        );
+    }
+
+    #[test]
+    fn respect_doc_hidden() {
+        check_found_path(
+            r#"
+//- /main.rs crate:main deps:std,lazy_static
+$0
+//- /lazy_static.rs crate:lazy_static deps:core
+#[doc(hidden)]
+pub use core::ops::Deref as __Deref;
+//- /std.rs crate:std deps:core
+pub use core::ops;
+//- /core.rs crate:core
+pub mod ops {
+    pub trait Deref {}
+}
+    "#,
+            "std::ops::Deref",
+            "std::ops::Deref",
+            "std::ops::Deref",
+            "std::ops::Deref",
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
index d7d44e41388..1e2535a8a99 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/generics.rs
@@ -21,10 +21,11 @@ use crate::{
     db::DefDatabase,
     dyn_map::{keys, DynMap},
     expander::Expander,
+    item_tree::{AttrOwner, ItemTree},
     lower::LowerCtx,
     nameres::{DefMap, MacroSubNs},
     src::{HasChildSource, HasSource},
-    type_ref::{LifetimeRef, TypeBound, TypeRef},
+    type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
     AdtId, ConstParamId, GenericDefId, HasModule, LifetimeParamId, LocalLifetimeParamId,
     LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
 };
@@ -48,7 +49,7 @@ pub struct LifetimeParamData {
 pub struct ConstParamData {
     pub name: Name,
     pub ty: Interned<TypeRef>,
-    pub has_default: bool,
+    pub default: Option<ConstRef>,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
@@ -75,7 +76,7 @@ impl TypeOrConstParamData {
     pub fn has_default(&self) -> bool {
         match self {
             TypeOrConstParamData::TypeParamData(it) => it.default.is_some(),
-            TypeOrConstParamData::ConstParamData(it) => it.has_default,
+            TypeOrConstParamData::ConstParamData(it) => it.default.is_some(),
         }
     }
 
@@ -154,12 +155,58 @@ impl GenericParams {
         def: GenericDefId,
     ) -> Interned<GenericParams> {
         let _p = profile::span("generic_params_query");
+
+        let krate = def.module(db).krate;
+        let cfg_options = db.crate_graph();
+        let cfg_options = &cfg_options[krate].cfg_options;
+
+        // Returns the generic parameters that are enabled under the current `#[cfg]` options
+        let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
+            let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
+
+            // In the common case, no parameters will by disabled by `#[cfg]` attributes.
+            // Therefore, make a first pass to check if all parameters are enabled and, if so,
+            // clone the `Interned<GenericParams>` instead of recreating an identical copy.
+            let all_type_or_consts_enabled =
+                params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
+            let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));
+
+            if all_type_or_consts_enabled && all_lifetimes_enabled {
+                params.clone()
+            } else {
+                Interned::new(GenericParams {
+                    type_or_consts: all_type_or_consts_enabled
+                        .then(|| params.type_or_consts.clone())
+                        .unwrap_or_else(|| {
+                            params
+                                .type_or_consts
+                                .iter()
+                                .filter_map(|(idx, param)| {
+                                    enabled(idx.into()).then(|| param.clone())
+                                })
+                                .collect()
+                        }),
+                    lifetimes: all_lifetimes_enabled
+                        .then(|| params.lifetimes.clone())
+                        .unwrap_or_else(|| {
+                            params
+                                .lifetimes
+                                .iter()
+                                .filter_map(|(idx, param)| {
+                                    enabled(idx.into()).then(|| param.clone())
+                                })
+                                .collect()
+                        }),
+                    where_predicates: params.where_predicates.clone(),
+                })
+            }
+        };
         macro_rules! id_to_generics {
             ($id:ident) => {{
                 let id = $id.lookup(db).id;
                 let tree = id.item_tree(db);
                 let item = &tree[id.value];
-                item.generic_params.clone()
+                enabled_params(&item.generic_params, &tree)
             }};
         }
 
@@ -169,7 +216,8 @@ impl GenericParams {
                 let tree = loc.id.item_tree(db);
                 let item = &tree[loc.id.value];
 
-                let mut generic_params = GenericParams::clone(&item.explicit_generic_params);
+                let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
+                let mut generic_params = GenericParams::clone(&enabled_params);
 
                 let module = loc.container.module(db);
                 let func_data = db.function_data(id);
@@ -198,9 +246,14 @@ impl GenericParams {
         }
     }
 
-    pub(crate) fn fill(&mut self, lower_ctx: &LowerCtx<'_>, node: &dyn HasGenericParams) {
+    pub(crate) fn fill(
+        &mut self,
+        lower_ctx: &LowerCtx<'_>,
+        node: &dyn HasGenericParams,
+        add_param_attrs: impl FnMut(AttrOwner, ast::GenericParam),
+    ) {
         if let Some(params) = node.generic_param_list() {
-            self.fill_params(lower_ctx, params)
+            self.fill_params(lower_ctx, params, add_param_attrs)
         }
         if let Some(where_clause) = node.where_clause() {
             self.fill_where_predicates(lower_ctx, where_clause);
@@ -218,7 +271,12 @@ impl GenericParams {
         }
     }
 
-    fn fill_params(&mut self, lower_ctx: &LowerCtx<'_>, params: ast::GenericParamList) {
+    fn fill_params(
+        &mut self,
+        lower_ctx: &LowerCtx<'_>,
+        params: ast::GenericParamList,
+        mut add_param_attrs: impl FnMut(AttrOwner, ast::GenericParam),
+    ) {
         for type_or_const_param in params.type_or_const_params() {
             match type_or_const_param {
                 ast::TypeOrConstParam::Type(type_param) => {
@@ -232,13 +290,14 @@ impl GenericParams {
                         default,
                         provenance: TypeParamProvenance::TypeParamList,
                     };
-                    self.type_or_consts.alloc(param.into());
+                    let idx = self.type_or_consts.alloc(param.into());
                     let type_ref = TypeRef::Path(name.into());
                     self.fill_bounds(
                         lower_ctx,
                         type_param.type_bound_list(),
                         Either::Left(type_ref),
                     );
+                    add_param_attrs(idx.into(), ast::GenericParam::TypeParam(type_param));
                 }
                 ast::TypeOrConstParam::Const(const_param) => {
                     let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
@@ -248,9 +307,10 @@ impl GenericParams {
                     let param = ConstParamData {
                         name,
                         ty: Interned::new(ty),
-                        has_default: const_param.default_val().is_some(),
+                        default: ConstRef::from_const_param(lower_ctx, &const_param),
                     };
-                    self.type_or_consts.alloc(param.into());
+                    let idx = self.type_or_consts.alloc(param.into());
+                    add_param_attrs(idx.into(), ast::GenericParam::ConstParam(const_param));
                 }
             }
         }
@@ -258,13 +318,14 @@ impl GenericParams {
             let name =
                 lifetime_param.lifetime().map_or_else(Name::missing, |lt| Name::new_lifetime(&lt));
             let param = LifetimeParamData { name: name.clone() };
-            self.lifetimes.alloc(param);
+            let idx = self.lifetimes.alloc(param);
             let lifetime_ref = LifetimeRef::new_name(name);
             self.fill_bounds(
                 lower_ctx,
                 lifetime_param.type_bound_list(),
                 Either::Right(lifetime_ref),
             );
+            add_param_attrs(idx.into(), ast::GenericParam::LifetimeParam(lifetime_param));
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
index 57f023ef35d..75adf21abdc 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
@@ -393,6 +393,17 @@ impl ConstRef {
         Self::Scalar(LiteralConstRef::Unknown)
     }
 
+    pub(crate) fn from_const_param(
+        lower_ctx: &LowerCtx<'_>,
+        param: &ast::ConstParam,
+    ) -> Option<Self> {
+        let default = param.default_val();
+        match default {
+            Some(_) => Some(Self::from_const_arg(lower_ctx, default)),
+            None => None,
+        }
+    }
+
     pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a {
         struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRef);
         impl fmt::Display for Display<'_> {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
index 4b2e5041a12..6038caaf8fc 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs
@@ -11,6 +11,7 @@ use itertools::Itertools;
 use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
 use triomphe::Arc;
 
+use crate::item_scope::ImportOrExternCrate;
 use crate::{
     db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, visibility::Visibility, AssocItemId,
     ModuleDefId, ModuleId, TraitId,
@@ -29,6 +30,8 @@ pub struct ImportInfo {
     pub container: ModuleId,
     /// Whether the import is a trait associated item or not.
     pub is_trait_assoc_item: bool,
+    /// Whether this item is annotated with `#[doc(hidden)]`.
+    pub is_doc_hidden: bool,
 }
 
 /// A map from publicly exported items to its name.
@@ -109,23 +112,41 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
         });
 
         for (name, per_ns) in visible_items {
-            for item in per_ns.iter_items() {
+            for (item, import) in per_ns.iter_items() {
+                // FIXME: Not yet used, but will be once we handle doc(hidden) import sources
+                let attr_id = if let Some(import) = import {
+                    match import {
+                        ImportOrExternCrate::ExternCrate(id) => Some(id.into()),
+                        ImportOrExternCrate::Import(id) => Some(id.import.into()),
+                    }
+                } else {
+                    match item {
+                        ItemInNs::Types(id) | ItemInNs::Values(id) => id.try_into().ok(),
+                        ItemInNs::Macros(id) => Some(id.into()),
+                    }
+                };
+                let is_doc_hidden =
+                    attr_id.map_or(false, |attr_id| db.attrs(attr_id).has_doc_hidden());
+
                 let import_info = ImportInfo {
                     name: name.clone(),
                     container: module,
                     is_trait_assoc_item: false,
+                    is_doc_hidden,
                 };
 
                 match depth_map.entry(item) {
-                    Entry::Vacant(entry) => {
-                        entry.insert(depth);
-                    }
+                    Entry::Vacant(entry) => _ = entry.insert((depth, is_doc_hidden)),
                     Entry::Occupied(mut entry) => {
-                        if depth < *entry.get() {
-                            entry.insert(depth);
-                        } else {
+                        let &(occ_depth, occ_is_doc_hidden) = entry.get();
+                        // Prefer the one that is not doc(hidden),
+                        // Otherwise, if both have the same doc(hidden)-ness and the new path is shorter, prefer that one.
+                        let overwrite_entry = occ_is_doc_hidden && !is_doc_hidden
+                            || occ_is_doc_hidden == is_doc_hidden && depth < occ_depth;
+                        if !overwrite_entry {
                             continue;
                         }
+                        entry.insert((depth, is_doc_hidden));
                     }
                 }
 
@@ -162,10 +183,10 @@ fn collect_trait_assoc_items(
     trait_import_info: &ImportInfo,
 ) {
     let _p = profile::span("collect_trait_assoc_items");
-    for (assoc_item_name, item) in &db.trait_data(tr).items {
+    for &(ref assoc_item_name, item) in &db.trait_data(tr).items {
         let module_def_id = match item {
-            AssocItemId::FunctionId(f) => ModuleDefId::from(*f),
-            AssocItemId::ConstId(c) => ModuleDefId::from(*c),
+            AssocItemId::FunctionId(f) => ModuleDefId::from(f),
+            AssocItemId::ConstId(c) => ModuleDefId::from(c),
             // cannot use associated type aliases directly: need a `<Struct as Trait>::TypeAlias`
             // qualifier, ergo no need to store it for imports in import_map
             AssocItemId::TypeAliasId(_) => {
@@ -183,6 +204,7 @@ fn collect_trait_assoc_items(
             container: trait_import_info.container,
             name: assoc_item_name.clone(),
             is_trait_assoc_item: true,
+            is_doc_hidden: db.attrs(item.into()).has_doc_hidden(),
         };
         map.insert(assoc_item, assoc_item_info);
     }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
index 873accafb43..7c11fb9d136 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
@@ -6,6 +6,7 @@ use std::collections::hash_map::Entry;
 use base_db::CrateId;
 use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId};
 use itertools::Itertools;
+use la_arena::Idx;
 use once_cell::sync::Lazy;
 use profile::Count;
 use rustc_hash::{FxHashMap, FxHashSet};
@@ -15,16 +16,10 @@ use syntax::ast;
 
 use crate::{
     db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ConstId,
-    ExternCrateId, HasModule, ImplId, LocalModuleId, MacroId, ModuleDefId, ModuleId, TraitId,
-    UseId,
+    ExternCrateId, HasModule, ImplId, LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId,
+    TraitId, UseId,
 };
 
-#[derive(Copy, Clone, Debug)]
-pub(crate) enum ImportType {
-    Glob,
-    Named,
-}
-
 #[derive(Debug, Default)]
 pub struct PerNsGlobImports {
     types: FxHashSet<(LocalModuleId, Name)>,
@@ -32,15 +27,50 @@ pub struct PerNsGlobImports {
     macros: FxHashSet<(LocalModuleId, Name)>,
 }
 
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum ImportOrExternCrate {
+    Import(ImportId),
+    ExternCrate(ExternCrateId),
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub(crate) enum ImportType {
+    Import(ImportId),
+    Glob(UseId),
+    ExternCrate(ExternCrateId),
+}
+
+impl ImportOrExternCrate {
+    pub fn into_import(self) -> Option<ImportId> {
+        match self {
+            ImportOrExternCrate::Import(it) => Some(it),
+            _ => None,
+        }
+    }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum ImportOrDef {
+    Import(ImportId),
+    ExternCrate(ExternCrateId),
+    Def(ModuleDefId),
+}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
+pub struct ImportId {
+    pub import: UseId,
+    pub idx: Idx<ast::UseTree>,
+}
+
 #[derive(Debug, Default, PartialEq, Eq)]
 pub struct ItemScope {
     _c: Count<Self>,
 
     /// Defs visible in this scope. This includes `declarations`, but also
-    /// imports.
-    types: FxHashMap<Name, (ModuleDefId, Visibility)>,
-    values: FxHashMap<Name, (ModuleDefId, Visibility)>,
-    macros: FxHashMap<Name, (MacroId, Visibility)>,
+    /// imports. The imports belong to this module and can be resolved by using them on
+    /// the `use_imports_*` fields.
+    types: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
+    values: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportId>)>,
+    macros: FxHashMap<Name, (MacroId, Visibility, Option<ImportId>)>,
     unresolved: FxHashSet<Name>,
 
     /// The defs declared in this scope. Each def has a single scope where it is
@@ -50,7 +80,14 @@ pub struct ItemScope {
     impls: Vec<ImplId>,
     unnamed_consts: Vec<ConstId>,
     /// Traits imported via `use Trait as _;`.
-    unnamed_trait_imports: FxHashMap<TraitId, Visibility>,
+    unnamed_trait_imports: FxHashMap<TraitId, (Visibility, Option<ImportId>)>,
+
+    // the resolutions of the imports of this scope
+    use_imports_types: FxHashMap<ImportOrExternCrate, ImportOrDef>,
+    use_imports_values: FxHashMap<ImportId, ImportOrDef>,
+    use_imports_macros: FxHashMap<ImportId, ImportOrDef>,
+
+    use_decls: Vec<UseId>,
     extern_crate_decls: Vec<ExternCrateId>,
     /// Macros visible in current module in legacy textual scope
     ///
@@ -82,7 +119,7 @@ struct DeriveMacroInvocation {
 pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
     BuiltinType::ALL
         .iter()
-        .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public)))
+        .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public, None)))
         .collect()
 });
 
@@ -105,11 +142,77 @@ impl ItemScope {
             .chain(self.values.keys())
             .chain(self.macros.keys())
             .chain(self.unresolved.iter())
-            .sorted()
             .unique()
+            .sorted()
             .map(move |name| (name, self.get(name)))
     }
 
+    pub fn imports(&self) -> impl Iterator<Item = ImportId> + '_ {
+        self.use_imports_types
+            .keys()
+            .copied()
+            .filter_map(ImportOrExternCrate::into_import)
+            .chain(self.use_imports_values.keys().copied())
+            .chain(self.use_imports_macros.keys().copied())
+            .unique()
+            .sorted()
+    }
+
+    pub fn fully_resolve_import(&self, db: &dyn DefDatabase, mut import: ImportId) -> PerNs {
+        let mut res = PerNs::none();
+
+        let mut def_map;
+        let mut scope = self;
+        while let Some(&m) = scope.use_imports_macros.get(&import) {
+            match m {
+                ImportOrDef::Import(i) => {
+                    let module_id = i.import.lookup(db).container;
+                    def_map = module_id.def_map(db);
+                    scope = &def_map[module_id.local_id].scope;
+                    import = i;
+                }
+                ImportOrDef::Def(ModuleDefId::MacroId(def)) => {
+                    res.macros = Some((def, Visibility::Public, None));
+                    break;
+                }
+                _ => break,
+            }
+        }
+        let mut scope = self;
+        while let Some(&m) = scope.use_imports_types.get(&ImportOrExternCrate::Import(import)) {
+            match m {
+                ImportOrDef::Import(i) => {
+                    let module_id = i.import.lookup(db).container;
+                    def_map = module_id.def_map(db);
+                    scope = &def_map[module_id.local_id].scope;
+                    import = i;
+                }
+                ImportOrDef::Def(def) => {
+                    res.types = Some((def, Visibility::Public, None));
+                    break;
+                }
+                _ => break,
+            }
+        }
+        let mut scope = self;
+        while let Some(&m) = scope.use_imports_values.get(&import) {
+            match m {
+                ImportOrDef::Import(i) => {
+                    let module_id = i.import.lookup(db).container;
+                    def_map = module_id.def_map(db);
+                    scope = &def_map[module_id.local_id].scope;
+                    import = i;
+                }
+                ImportOrDef::Def(def) => {
+                    res.values = Some((def, Visibility::Public, None));
+                    break;
+                }
+                _ => break,
+            }
+        }
+        res
+    }
+
     pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
         self.declarations.iter().copied()
     }
@@ -121,8 +224,7 @@ impl ItemScope {
     }
 
     pub fn use_decls(&self) -> impl Iterator<Item = UseId> + ExactSizeIterator + '_ {
-        // FIXME: to be implemented
-        std::iter::empty()
+        self.use_decls.iter().copied()
     }
 
     pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
@@ -132,13 +234,13 @@ impl ItemScope {
     pub fn values(
         &self,
     ) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
-        self.values.values().copied()
+        self.values.values().copied().map(|(a, b, _)| (a, b))
     }
 
-    pub fn types(
+    pub(crate) fn types(
         &self,
     ) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
-        self.types.values().copied()
+        self.types.values().copied().map(|(def, vis, _)| (def, vis))
     }
 
     pub fn unnamed_consts(&self) -> impl Iterator<Item = ConstId> + '_ {
@@ -165,33 +267,55 @@ impl ItemScope {
     }
 
     pub(crate) fn type_(&self, name: &Name) -> Option<(ModuleDefId, Visibility)> {
-        self.types.get(name).copied()
+        self.types.get(name).copied().map(|(a, b, _)| (a, b))
     }
 
     /// XXX: this is O(N) rather than O(1), try to not introduce new usages.
     pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility)> {
-        let (def, mut iter) = match item {
-            ItemInNs::Macros(def) => {
-                return self.macros.iter().find_map(|(name, &(other_def, vis))| {
-                    (other_def == def).then_some((name, vis))
-                });
-            }
-            ItemInNs::Types(def) => (def, self.types.iter()),
-            ItemInNs::Values(def) => (def, self.values.iter()),
-        };
-        iter.find_map(|(name, &(other_def, vis))| (other_def == def).then_some((name, vis)))
+        match item {
+            ItemInNs::Macros(def) => self
+                .macros
+                .iter()
+                .find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
+            ItemInNs::Types(def) => self
+                .types
+                .iter()
+                .find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
+
+            ItemInNs::Values(def) => self
+                .values
+                .iter()
+                .find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
+        }
     }
 
     pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
         self.types
             .values()
-            .filter_map(|&(def, _)| match def {
+            .filter_map(|&(def, _, _)| match def {
                 ModuleDefId::TraitId(t) => Some(t),
                 _ => None,
             })
             .chain(self.unnamed_trait_imports.keys().copied())
     }
 
+    pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
+        self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
+            self.unnamed_trait_imports.iter().map(|(tr, (vis, i))| {
+                (
+                    None,
+                    PerNs::types(
+                        ModuleDefId::TraitId(*tr),
+                        *vis,
+                        i.map(ImportOrExternCrate::Import),
+                    ),
+                )
+            }),
+        )
+    }
+}
+
+impl ItemScope {
     pub(crate) fn declare(&mut self, def: ModuleDefId) {
         self.declarations.push(def)
     }
@@ -277,12 +401,14 @@ impl ItemScope {
         })
     }
 
+    // FIXME: This is only used in collection, we should move the relevant parts of it out of ItemScope
     pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
-        self.unnamed_trait_imports.get(&tr).copied()
+        self.unnamed_trait_imports.get(&tr).copied().map(|(a, _)| a)
     }
 
     pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
-        self.unnamed_trait_imports.insert(tr, vis);
+        // FIXME: import
+        self.unnamed_trait_imports.insert(tr, (vis, None));
     }
 
     pub(crate) fn push_res_with_import(
@@ -290,51 +416,187 @@ impl ItemScope {
         glob_imports: &mut PerNsGlobImports,
         lookup: (LocalModuleId, Name),
         def: PerNs,
-        def_import_type: ImportType,
+        import: Option<ImportType>,
     ) -> bool {
         let mut changed = false;
 
-        macro_rules! check_changed {
-            (
-                $changed:ident,
-                ( $this:ident / $def:ident ) . $field:ident,
-                $glob_imports:ident [ $lookup:ident ],
-                $def_import_type:ident
-            ) => {{
-                if let Some(fld) = $def.$field {
-                    let existing = $this.$field.entry($lookup.1.clone());
-                    match existing {
-                        Entry::Vacant(entry) => {
-                            match $def_import_type {
-                                ImportType::Glob => {
-                                    $glob_imports.$field.insert($lookup.clone());
+        // FIXME: Document and simplify this
+
+        if let Some(mut fld) = def.types {
+            let existing = self.types.entry(lookup.1.clone());
+            match existing {
+                Entry::Vacant(entry) => {
+                    match import {
+                        Some(ImportType::Glob(_)) => {
+                            glob_imports.types.insert(lookup.clone());
+                        }
+                        _ => _ = glob_imports.types.remove(&lookup),
+                    }
+                    let import = match import {
+                        Some(ImportType::ExternCrate(extern_crate)) => {
+                            Some(ImportOrExternCrate::ExternCrate(extern_crate))
+                        }
+                        Some(ImportType::Import(import)) => {
+                            Some(ImportOrExternCrate::Import(import))
+                        }
+                        None | Some(ImportType::Glob(_)) => None,
+                    };
+                    let prev = std::mem::replace(&mut fld.2, import);
+                    if let Some(import) = import {
+                        self.use_imports_types.insert(
+                            import,
+                            match prev {
+                                Some(ImportOrExternCrate::Import(import)) => {
+                                    ImportOrDef::Import(import)
                                 }
-                                ImportType::Named => {
-                                    $glob_imports.$field.remove(&$lookup);
+                                Some(ImportOrExternCrate::ExternCrate(import)) => {
+                                    ImportOrDef::ExternCrate(import)
                                 }
+                                None => ImportOrDef::Def(fld.0),
+                            },
+                        );
+                    }
+                    entry.insert(fld);
+                    changed = true;
+                }
+                Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
+                    if glob_imports.types.remove(&lookup) {
+                        let import = match import {
+                            Some(ImportType::ExternCrate(extern_crate)) => {
+                                Some(ImportOrExternCrate::ExternCrate(extern_crate))
+                            }
+                            Some(ImportType::Import(import)) => {
+                                Some(ImportOrExternCrate::Import(import))
                             }
+                            None | Some(ImportType::Glob(_)) => None,
+                        };
+                        let prev = std::mem::replace(&mut fld.2, import);
+                        if let Some(import) = import {
+                            self.use_imports_types.insert(
+                                import,
+                                match prev {
+                                    Some(ImportOrExternCrate::Import(import)) => {
+                                        ImportOrDef::Import(import)
+                                    }
+                                    Some(ImportOrExternCrate::ExternCrate(import)) => {
+                                        ImportOrDef::ExternCrate(import)
+                                    }
+                                    None => ImportOrDef::Def(fld.0),
+                                },
+                            );
+                        }
+                        cov_mark::hit!(import_shadowed);
+                        entry.insert(fld);
+                        changed = true;
+                    }
+                }
+                _ => {}
+            }
+        }
 
-                            entry.insert(fld);
-                            $changed = true;
+        if let Some(mut fld) = def.values {
+            let existing = self.values.entry(lookup.1.clone());
+            match existing {
+                Entry::Vacant(entry) => {
+                    match import {
+                        Some(ImportType::Glob(_)) => {
+                            glob_imports.values.insert(lookup.clone());
                         }
-                        Entry::Occupied(mut entry)
-                            if matches!($def_import_type, ImportType::Named) =>
-                        {
-                            if $glob_imports.$field.remove(&$lookup) {
-                                cov_mark::hit!(import_shadowed);
-                                entry.insert(fld);
-                                $changed = true;
-                            }
+                        _ => _ = glob_imports.values.remove(&lookup),
+                    }
+                    let import = match import {
+                        Some(ImportType::Import(import)) => Some(import),
+                        _ => None,
+                    };
+                    let prev = std::mem::replace(&mut fld.2, import);
+                    if let Some(import) = import {
+                        self.use_imports_values.insert(
+                            import,
+                            match prev {
+                                Some(import) => ImportOrDef::Import(import),
+                                None => ImportOrDef::Def(fld.0),
+                            },
+                        );
+                    }
+                    entry.insert(fld);
+                    changed = true;
+                }
+                Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
+                    if glob_imports.values.remove(&lookup) {
+                        cov_mark::hit!(import_shadowed);
+                        let import = match import {
+                            Some(ImportType::Import(import)) => Some(import),
+                            _ => None,
+                        };
+                        let prev = std::mem::replace(&mut fld.2, import);
+                        if let Some(import) = import {
+                            self.use_imports_values.insert(
+                                import,
+                                match prev {
+                                    Some(import) => ImportOrDef::Import(import),
+                                    None => ImportOrDef::Def(fld.0),
+                                },
+                            );
                         }
-                        _ => {}
+                        entry.insert(fld);
+                        changed = true;
                     }
                 }
-            }};
+                _ => {}
+            }
         }
 
-        check_changed!(changed, (self / def).types, glob_imports[lookup], def_import_type);
-        check_changed!(changed, (self / def).values, glob_imports[lookup], def_import_type);
-        check_changed!(changed, (self / def).macros, glob_imports[lookup], def_import_type);
+        if let Some(mut fld) = def.macros {
+            let existing = self.macros.entry(lookup.1.clone());
+            match existing {
+                Entry::Vacant(entry) => {
+                    match import {
+                        Some(ImportType::Glob(_)) => {
+                            glob_imports.macros.insert(lookup.clone());
+                        }
+                        _ => _ = glob_imports.macros.remove(&lookup),
+                    }
+                    let import = match import {
+                        Some(ImportType::Import(import)) => Some(import),
+                        _ => None,
+                    };
+                    let prev = std::mem::replace(&mut fld.2, import);
+                    if let Some(import) = import {
+                        self.use_imports_macros.insert(
+                            import,
+                            match prev {
+                                Some(import) => ImportOrDef::Import(import),
+                                None => ImportOrDef::Def(fld.0.into()),
+                            },
+                        );
+                    }
+                    entry.insert(fld);
+                    changed = true;
+                }
+                Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
+                    if glob_imports.macros.remove(&lookup) {
+                        cov_mark::hit!(import_shadowed);
+                        let import = match import {
+                            Some(ImportType::Import(import)) => Some(import),
+                            _ => None,
+                        };
+                        let prev = std::mem::replace(&mut fld.2, import);
+                        if let Some(import) = import {
+                            self.use_imports_macros.insert(
+                                import,
+                                match prev {
+                                    Some(import) => ImportOrDef::Import(import),
+                                    None => ImportOrDef::Def(fld.0.into()),
+                                },
+                            );
+                        }
+                        entry.insert(fld);
+                        changed = true;
+                    }
+                }
+                _ => {}
+            }
+        }
 
         if def.is_none() && self.unresolved.insert(lookup.1) {
             changed = true;
@@ -343,27 +605,18 @@ impl ItemScope {
         changed
     }
 
-    pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
-        self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
-            self.unnamed_trait_imports
-                .iter()
-                .map(|(tr, vis)| (None, PerNs::types(ModuleDefId::TraitId(*tr), *vis))),
-        )
-    }
-
     /// Marks everything that is not a procedural macro as private to `this_module`.
     pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {
         self.types
             .values_mut()
-            .chain(self.values.values_mut())
+            .map(|(def, vis, _)| (def, vis))
+            .chain(self.values.values_mut().map(|(def, vis, _)| (def, vis)))
             .map(|(_, v)| v)
-            .chain(self.unnamed_trait_imports.values_mut())
+            .chain(self.unnamed_trait_imports.values_mut().map(|(vis, _)| vis))
             .for_each(|vis| *vis = Visibility::Module(this_module));
 
-        for (mac, vis) in self.macros.values_mut() {
-            if let MacroId::ProcMacroId(_) = mac {
-                // FIXME: Technically this is insufficient since reexports of proc macros are also
-                // forbidden. Practically nobody does that.
+        for (mac, vis, import) in self.macros.values_mut() {
+            if matches!(mac, MacroId::ProcMacroId(_) if import.is_none()) {
                 continue;
             }
 
@@ -382,14 +635,25 @@ impl ItemScope {
                 name.map_or("_".to_string(), |name| name.display(db).to_string())
             );
 
-            if def.types.is_some() {
+            if let Some((.., i)) = def.types {
                 buf.push_str(" t");
+                match i {
+                    Some(ImportOrExternCrate::Import(_)) => buf.push('i'),
+                    Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'),
+                    None => (),
+                }
             }
-            if def.values.is_some() {
+            if let Some((.., i)) = def.values {
                 buf.push_str(" v");
+                if i.is_some() {
+                    buf.push('i');
+                }
             }
-            if def.macros.is_some() {
+            if let Some((.., i)) = def.macros {
                 buf.push_str(" m");
+                if i.is_some() {
+                    buf.push('i');
+                }
             }
             if def.is_none() {
                 buf.push_str(" _");
@@ -415,10 +679,17 @@ impl ItemScope {
             attr_macros,
             derive_macros,
             extern_crate_decls,
+            use_decls,
+            use_imports_values,
+            use_imports_types,
+            use_imports_macros,
         } = self;
         types.shrink_to_fit();
         values.shrink_to_fit();
         macros.shrink_to_fit();
+        use_imports_types.shrink_to_fit();
+        use_imports_values.shrink_to_fit();
+        use_imports_macros.shrink_to_fit();
         unresolved.shrink_to_fit();
         declarations.shrink_to_fit();
         impls.shrink_to_fit();
@@ -428,32 +699,44 @@ impl ItemScope {
         attr_macros.shrink_to_fit();
         derive_macros.shrink_to_fit();
         extern_crate_decls.shrink_to_fit();
+        use_decls.shrink_to_fit();
     }
 }
 
 impl PerNs {
-    pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) -> PerNs {
+    pub(crate) fn from_def(
+        def: ModuleDefId,
+        v: Visibility,
+        has_constructor: bool,
+        import: Option<ImportOrExternCrate>,
+    ) -> PerNs {
         match def {
-            ModuleDefId::ModuleId(_) => PerNs::types(def, v),
-            ModuleDefId::FunctionId(_) => PerNs::values(def, v),
+            ModuleDefId::ModuleId(_) => PerNs::types(def, v, import),
+            ModuleDefId::FunctionId(_) => {
+                PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
+            }
             ModuleDefId::AdtId(adt) => match adt {
-                AdtId::UnionId(_) => PerNs::types(def, v),
-                AdtId::EnumId(_) => PerNs::types(def, v),
+                AdtId::UnionId(_) => PerNs::types(def, v, import),
+                AdtId::EnumId(_) => PerNs::types(def, v, import),
                 AdtId::StructId(_) => {
                     if has_constructor {
-                        PerNs::both(def, def, v)
+                        PerNs::both(def, def, v, import)
                     } else {
-                        PerNs::types(def, v)
+                        PerNs::types(def, v, import)
                     }
                 }
             },
-            ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
-            ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
-            ModuleDefId::TraitId(_) => PerNs::types(def, v),
-            ModuleDefId::TraitAliasId(_) => PerNs::types(def, v),
-            ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
-            ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
-            ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),
+            ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v, import),
+            ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => {
+                PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
+            }
+            ModuleDefId::TraitId(_) => PerNs::types(def, v, import),
+            ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import),
+            ModuleDefId::TypeAliasId(_) => PerNs::types(def, v, import),
+            ModuleDefId::BuiltinType(_) => PerNs::types(def, v, import),
+            ModuleDefId::MacroId(mac) => {
+                PerNs::macros(mac, v, import.and_then(ImportOrExternCrate::into_import))
+            }
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index c9b0f75f1a8..3e1922750b9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -64,11 +64,11 @@ use triomphe::Arc;
 use crate::{
     attr::Attrs,
     db::DefDatabase,
-    generics::GenericParams,
+    generics::{GenericParams, LifetimeParamData, TypeOrConstParamData},
     path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
     type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
     visibility::RawVisibility,
-    BlockId,
+    BlockId, Lookup,
 };
 
 #[derive(Copy, Clone, Eq, PartialEq)]
@@ -143,6 +143,16 @@ impl ItemTree {
         Arc::new(item_tree)
     }
 
+    pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
+        let loc = block.lookup(db);
+        let block = loc.ast_id.to_node(db.upcast());
+
+        let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
+        let mut item_tree = ctx.lower_block(&block);
+        item_tree.shrink_to_fit();
+        Arc::new(item_tree)
+    }
+
     /// Returns an iterator over all items located at the top level of the `HirFileId` this
     /// `ItemTree` was created from.
     pub fn top_level_items(&self) -> &[ModItem] {
@@ -178,13 +188,6 @@ impl ItemTree {
         self.data.get_or_insert_with(Box::default)
     }
 
-    fn block_item_tree(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
-        let loc = db.lookup_intern_block(block);
-        let block = loc.ast_id.to_node(db.upcast());
-        let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
-        Arc::new(ctx.lower_block(&block))
-    }
-
     fn shrink_to_fit(&mut self) {
         if let Some(data) = &mut self.data {
             let ItemTreeData {
@@ -296,10 +299,12 @@ pub enum AttrOwner {
     Variant(Idx<Variant>),
     Field(Idx<Field>),
     Param(Idx<Param>),
+    TypeOrConstParamData(Idx<TypeOrConstParamData>),
+    LifetimeParamData(Idx<LifetimeParamData>),
 }
 
 macro_rules! from_attrs {
-    ( $( $var:ident($t:ty) ),+ ) => {
+    ( $( $var:ident($t:ty) ),+ $(,)? ) => {
         $(
             impl From<$t> for AttrOwner {
                 fn from(t: $t) -> AttrOwner {
@@ -310,7 +315,14 @@ macro_rules! from_attrs {
     };
 }
 
-from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>), Param(Idx<Param>));
+from_attrs!(
+    ModItem(ModItem),
+    Variant(Idx<Variant>),
+    Field(Idx<Field>),
+    Param(Idx<Param>),
+    TypeOrConstParamData(Idx<TypeOrConstParamData>),
+    LifetimeParamData(Idx<LifetimeParamData>),
+);
 
 /// Trait implemented by all item nodes in the item tree.
 pub trait ItemTreeNode: Clone {
@@ -373,7 +385,7 @@ impl TreeId {
 
     pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
         match self.block {
-            Some(block) => ItemTree::block_item_tree(db, block),
+            Some(block) => db.block_item_tree_query(block),
             None => db.file_item_tree(self.file),
         }
     }
@@ -761,6 +773,19 @@ impl Use {
             lower::lower_use_tree(db, &hygiene, ast_use_tree).expect("failed to lower use tree");
         source_map[index].clone()
     }
+    /// Maps a `UseTree` contained in this import back to its AST node.
+    pub fn use_tree_source_map(
+        &self,
+        db: &dyn DefDatabase,
+        file_id: HirFileId,
+    ) -> Arena<ast::UseTree> {
+        // Re-lower the AST item and get the source map.
+        // Note: The AST unwraps are fine, since if they fail we should have never obtained `index`.
+        let ast = InFile::new(file_id, self.ast_id).to_node(db.upcast());
+        let ast_use_tree = ast.use_tree().expect("missing `use_tree`");
+        let hygiene = Hygiene::new(db.upcast(), file_id);
+        lower::lower_use_tree(db, &hygiene, ast_use_tree).expect("failed to lower use tree").1
+    }
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -785,7 +810,7 @@ impl UseTree {
     fn expand_impl(
         &self,
         prefix: Option<ModPath>,
-        cb: &mut dyn FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
+        cb: &mut impl FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
     ) {
         fn concat_mod_paths(
             prefix: Option<ModPath>,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
index 7b898e62dba..e4702c113b8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
@@ -77,6 +77,9 @@ impl<'a> Ctx<'a> {
     }
 
     pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree {
+        self.tree
+            .attrs
+            .insert(AttrOwner::TopLevel, RawAttrs::new(self.db.upcast(), block, self.hygiene()));
         self.tree.top_level = block
             .statements()
             .filter_map(|stmt| match stmt {
@@ -602,7 +605,21 @@ impl<'a> Ctx<'a> {
             generics.fill_bounds(&self.body_ctx, bounds, Either::Left(self_param));
         }
 
-        generics.fill(&self.body_ctx, node);
+        let add_param_attrs = |item, param| {
+            let attrs = RawAttrs::new(self.db.upcast(), &param, self.body_ctx.hygiene());
+            // This is identical to the body of `Ctx::add_attrs()` but we can't call that here
+            // because it requires `&mut self` and the call to `generics.fill()` below also
+            // references `self`.
+            match self.tree.attrs.entry(item) {
+                Entry::Occupied(mut entry) => {
+                    *entry.get_mut() = entry.get().merge(attrs);
+                }
+                Entry::Vacant(entry) => {
+                    entry.insert(attrs);
+                }
+            }
+        };
+        generics.fill(&self.body_ctx, node, add_param_attrs);
 
         generics.shrink_to_fit();
         Interned::new(generics)
@@ -763,7 +780,7 @@ impl UseTreeLowering<'_> {
     }
 }
 
-pub(super) fn lower_use_tree(
+pub(crate) fn lower_use_tree(
     db: &dyn DefDatabase,
     hygiene: &Hygiene,
     tree: ast::UseTree,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
index da30830fe45..4b852dd613e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
@@ -16,7 +16,7 @@ pub(super) fn print_item_tree(db: &dyn ExpandDatabase, tree: &ItemTree) -> Strin
     let mut p = Printer { db, tree, buf: String::new(), indent_level: 0, needs_indent: true };
 
     if let Some(attrs) = tree.attrs.get(&AttrOwner::TopLevel) {
-        p.print_attrs(attrs, true);
+        p.print_attrs(attrs, true, "\n");
     }
     p.blank();
 
@@ -84,22 +84,23 @@ impl Printer<'_> {
         }
     }
 
-    fn print_attrs(&mut self, attrs: &RawAttrs, inner: bool) {
+    fn print_attrs(&mut self, attrs: &RawAttrs, inner: bool, separated_by: &str) {
         let inner = if inner { "!" } else { "" };
         for attr in &**attrs {
-            wln!(
+            w!(
                 self,
-                "#{}[{}{}]",
+                "#{}[{}{}]{}",
                 inner,
                 attr.path.display(self.db),
                 attr.input.as_ref().map(|it| it.to_string()).unwrap_or_default(),
+                separated_by,
             );
         }
     }
 
-    fn print_attrs_of(&mut self, of: impl Into<AttrOwner>) {
+    fn print_attrs_of(&mut self, of: impl Into<AttrOwner>, separated_by: &str) {
         if let Some(attrs) = self.tree.attrs.get(&of.into()) {
-            self.print_attrs(attrs, false);
+            self.print_attrs(attrs, false, separated_by);
         }
     }
 
@@ -118,7 +119,7 @@ impl Printer<'_> {
                 self.indented(|this| {
                     for field in fields.clone() {
                         let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field];
-                        this.print_attrs_of(field);
+                        this.print_attrs_of(field, "\n");
                         this.print_visibility(*visibility);
                         w!(this, "{}: ", name.display(self.db));
                         this.print_type_ref(type_ref);
@@ -132,7 +133,7 @@ impl Printer<'_> {
                 self.indented(|this| {
                     for field in fields.clone() {
                         let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field];
-                        this.print_attrs_of(field);
+                        this.print_attrs_of(field, "\n");
                         this.print_visibility(*visibility);
                         w!(this, "{}: ", name.display(self.db));
                         this.print_type_ref(type_ref);
@@ -195,7 +196,7 @@ impl Printer<'_> {
     }
 
     fn print_mod_item(&mut self, item: ModItem) {
-        self.print_attrs_of(item);
+        self.print_attrs_of(item, "\n");
 
         match item {
             ModItem::Use(it) => {
@@ -261,7 +262,7 @@ impl Printer<'_> {
                 if !params.is_empty() {
                     self.indented(|this| {
                         for param in params.clone() {
-                            this.print_attrs_of(param);
+                            this.print_attrs_of(param, "\n");
                             match &this.tree[param] {
                                 Param::Normal(ty) => {
                                     if flags.contains(FnFlags::HAS_SELF_PARAM) {
@@ -319,7 +320,7 @@ impl Printer<'_> {
                 self.indented(|this| {
                     for variant in variants.clone() {
                         let Variant { name, fields, ast_id: _ } = &this.tree[variant];
-                        this.print_attrs_of(variant);
+                        this.print_attrs_of(variant, "\n");
                         w!(this, "{}", name.display(self.db));
                         this.print_fields(fields);
                         wln!(this, ",");
@@ -484,11 +485,12 @@ impl Printer<'_> {
 
         w!(self, "<");
         let mut first = true;
-        for (_, lt) in params.lifetimes.iter() {
+        for (idx, lt) in params.lifetimes.iter() {
             if !first {
                 w!(self, ", ");
             }
             first = false;
+            self.print_attrs_of(idx, " ");
             w!(self, "{}", lt.name.display(self.db));
         }
         for (idx, x) in params.type_or_consts.iter() {
@@ -496,6 +498,7 @@ impl Printer<'_> {
                 w!(self, ", ");
             }
             first = false;
+            self.print_attrs_of(idx, " ");
             match x {
                 TypeOrConstParamData::TypeParamData(ty) => match &ty.name {
                     Some(name) => w!(self, "{}", name.display(self.db)),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
index 5ded4b6b273..4180f817209 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
@@ -358,3 +358,15 @@ trait Tr<'a, T: 'a>: Super where Self: for<'a> Tr<'a, T> {}
         "#]],
     )
 }
+
+#[test]
+fn generics_with_attributes() {
+    check(
+        r#"
+struct S<#[cfg(never)] T>;
+        "#,
+        expect![[r#"
+            pub(self) struct S<#[cfg(never)] T>;
+        "#]],
+    )
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index 1901db8a0f9..3f87fe62b83 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -109,6 +109,17 @@ impl CrateRootModuleId {
     }
 }
 
+impl PartialEq<ModuleId> for CrateRootModuleId {
+    fn eq(&self, other: &ModuleId) -> bool {
+        other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate
+    }
+}
+impl PartialEq<CrateRootModuleId> for ModuleId {
+    fn eq(&self, other: &CrateRootModuleId) -> bool {
+        other == self
+    }
+}
+
 impl From<CrateRootModuleId> for ModuleId {
     fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
         ModuleId { krate, block: None, local_id: DefMap::ROOT }
@@ -854,14 +865,36 @@ impl_from!(
     ConstId,
     FunctionId,
     TraitId,
+    TraitAliasId,
     TypeAliasId,
     MacroId(Macro2Id, MacroRulesId, ProcMacroId),
     ImplId,
     GenericParamId,
-    ExternCrateId
+    ExternCrateId,
+    UseId
     for AttrDefId
 );
 
+impl TryFrom<ModuleDefId> for AttrDefId {
+    type Error = ();
+
+    fn try_from(value: ModuleDefId) -> Result<Self, Self::Error> {
+        match value {
+            ModuleDefId::ModuleId(it) => Ok(it.into()),
+            ModuleDefId::FunctionId(it) => Ok(it.into()),
+            ModuleDefId::AdtId(it) => Ok(it.into()),
+            ModuleDefId::EnumVariantId(it) => Ok(it.into()),
+            ModuleDefId::ConstId(it) => Ok(it.into()),
+            ModuleDefId::StaticId(it) => Ok(it.into()),
+            ModuleDefId::TraitId(it) => Ok(it.into()),
+            ModuleDefId::TypeAliasId(it) => Ok(it.into()),
+            ModuleDefId::TraitAliasId(id) => Ok(id.into()),
+            ModuleDefId::MacroId(id) => Ok(id.into()),
+            ModuleDefId::BuiltinType(_) => Err(()),
+        }
+    }
+}
+
 impl From<ItemContainerId> for AttrDefId {
     fn from(acid: ItemContainerId) -> Self {
         match acid {
@@ -872,6 +905,15 @@ impl From<ItemContainerId> for AttrDefId {
         }
     }
 }
+impl From<AssocItemId> for AttrDefId {
+    fn from(assoc: AssocItemId) -> Self {
+        match assoc {
+            AssocItemId::FunctionId(it) => AttrDefId::FunctionId(it),
+            AssocItemId::ConstId(it) => AttrDefId::ConstId(it),
+            AssocItemId::TypeAliasId(it) => AttrDefId::TypeAliasId(it),
+        }
+    }
+}
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub enum VariantId {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index 1250cbb742c..b232651db96 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -238,7 +238,7 @@ fn main() {
     /* error: expected expression */;
     /* error: expected expression, expected COMMA */;
     /* error: expected expression */::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(), ::core::fmt::Display::fmt), ]);
-    /* error: expected expression, expected expression */;
+    /* error: expected expression, expected R_PAREN */;
     ::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(5), ::core::fmt::Display::fmt), ]);
 }
 "##]],
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index d8e4a4dcc7c..97554f93f1c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -909,3 +909,68 @@ macro_rules! with_std {
 "##]],
     )
 }
+
+#[test]
+fn eager_regression_15403() {
+    check(
+        r#"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+    format_args /* +errors */ !("{}", line.1.);
+}
+
+"#,
+        expect![[r##"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+    /* error: expected field name or number *//* parse error: expected field name or number */
+::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(line.1.), ::core::fmt::Display::fmt), ]);
+}
+
+"##]],
+    );
+}
+
+#[test]
+fn eager_regression_154032() {
+    check(
+        r#"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+    format_args /* +errors */ !("{}", &[0 2]);
+}
+
+"#,
+        expect![[r##"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+    /* error: expected COMMA, expected R_BRACK, expected COMMA, expected COMMA, expected expression, expected R_PAREN *//* parse error: expected COMMA */
+/* parse error: expected R_BRACK */
+/* parse error: expected COMMA */
+/* parse error: expected COMMA */
+/* parse error: expected expression */
+/* parse error: expected R_PAREN */
+/* parse error: expected R_PAREN */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(&[0 2]), ::core::fmt::Display::fmt), ]);
+}
+
+"##]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
index 7a87e61c693..8adced4e082 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -131,7 +131,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
             .as_call_id_with_errors(&db, krate, |path| {
                 resolver
                     .resolve_path_as_macro(&db, &path, Some(MacroSubNs::Bang))
-                    .map(|it| macro_id_to_def_id(&db, it))
+                    .map(|(it, _)| macro_id_to_def_id(&db, it))
             })
             .unwrap();
         let macro_call_id = res.value.unwrap();
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
index 86818ce26dd..f2110410980 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
@@ -60,7 +60,7 @@ mod tests;
 use std::{cmp::Ord, ops::Deref};
 
 use base_db::{CrateId, Edition, FileId, ProcMacroKind};
-use hir_expand::{name::Name, HirFileId, InFile, MacroCallId, MacroDefId};
+use hir_expand::{ast_id_map::FileAstId, name::Name, HirFileId, InFile, MacroCallId, MacroDefId};
 use itertools::Itertools;
 use la_arena::Arena;
 use profile::Count;
@@ -77,8 +77,8 @@ use crate::{
     path::ModPath,
     per_ns::PerNs,
     visibility::Visibility,
-    AstId, BlockId, BlockLoc, CrateRootModuleId, FunctionId, LocalModuleId, Lookup, MacroExpander,
-    MacroId, ModuleId, ProcMacroId,
+    AstId, BlockId, BlockLoc, CrateRootModuleId, ExternCrateId, FunctionId, LocalModuleId, Lookup,
+    MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
 };
 
 /// Contains the results of (early) name resolution.
@@ -105,10 +105,11 @@ pub struct DefMap {
     /// The prelude is empty for non-block DefMaps (unless `#[prelude_import]` was used,
     /// but that attribute is nightly and when used in a block, it affects resolution globally
     /// so we aren't handling this correctly anyways).
-    prelude: Option<ModuleId>,
+    prelude: Option<(ModuleId, Option<UseId>)>,
     /// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that
     /// this contains all kinds of macro, not just `macro_rules!` macro.
-    macro_use_prelude: FxHashMap<Name, MacroId>,
+    /// ExternCrateId being None implies it being imported from the general prelude import.
+    macro_use_prelude: FxHashMap<Name, (MacroId, Option<ExternCrateId>)>,
 
     /// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
     /// attributes.
@@ -125,7 +126,7 @@ pub struct DefMap {
 #[derive(Clone, Debug, PartialEq, Eq)]
 struct DefMapCrateData {
     /// The extern prelude which contains all root modules of external crates that are in scope.
-    extern_prelude: FxHashMap<Name, CrateRootModuleId>,
+    extern_prelude: FxHashMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
 
     /// Side table for resolving derive helpers.
     exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
@@ -217,16 +218,17 @@ pub enum ModuleOrigin {
     /// Note that non-inline modules, by definition, live inside non-macro file.
     File {
         is_mod_rs: bool,
-        declaration: AstId<ast::Module>,
+        declaration: FileAstId<ast::Module>,
         declaration_tree_id: ItemTreeId<Mod>,
         definition: FileId,
     },
     Inline {
         definition_tree_id: ItemTreeId<Mod>,
-        definition: AstId<ast::Module>,
+        definition: FileAstId<ast::Module>,
     },
     /// Pseudo-module introduced by a block scope (contains only inner items).
     BlockExpr {
+        id: BlockId,
         block: AstId<ast::BlockExpr>,
     },
 }
@@ -234,8 +236,12 @@ pub enum ModuleOrigin {
 impl ModuleOrigin {
     pub fn declaration(&self) -> Option<AstId<ast::Module>> {
         match self {
-            ModuleOrigin::File { declaration: module, .. }
-            | ModuleOrigin::Inline { definition: module, .. } => Some(*module),
+            &ModuleOrigin::File { declaration, declaration_tree_id, .. } => {
+                Some(AstId::new(declaration_tree_id.file_id(), declaration))
+            }
+            &ModuleOrigin::Inline { definition, definition_tree_id } => {
+                Some(AstId::new(definition_tree_id.file_id(), definition))
+            }
             ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None,
         }
     }
@@ -260,16 +266,17 @@ impl ModuleOrigin {
     /// That is, a file or a `mod foo {}` with items.
     fn definition_source(&self, db: &dyn DefDatabase) -> InFile<ModuleSource> {
         match self {
-            ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
-                let file_id = *definition;
-                let sf = db.parse(file_id).tree();
-                InFile::new(file_id.into(), ModuleSource::SourceFile(sf))
+            &ModuleOrigin::File { definition, .. } | &ModuleOrigin::CrateRoot { definition } => {
+                let sf = db.parse(definition).tree();
+                InFile::new(definition.into(), ModuleSource::SourceFile(sf))
             }
-            ModuleOrigin::Inline { definition, .. } => InFile::new(
-                definition.file_id,
-                ModuleSource::Module(definition.to_node(db.upcast())),
+            &ModuleOrigin::Inline { definition, definition_tree_id } => InFile::new(
+                definition_tree_id.file_id(),
+                ModuleSource::Module(
+                    AstId::new(definition_tree_id.file_id(), definition).to_node(db.upcast()),
+                ),
             ),
-            ModuleOrigin::BlockExpr { block } => {
+            ModuleOrigin::BlockExpr { block, .. } => {
                 InFile::new(block.file_id, ModuleSource::BlockExpr(block.to_node(db.upcast())))
             }
         }
@@ -314,9 +321,7 @@ impl DefMap {
     }
 
     pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
-        let block: BlockLoc = db.lookup_intern_block(block_id);
-
-        let tree_id = TreeId::new(block.ast_id.file_id, Some(block_id));
+        let block: BlockLoc = block_id.lookup(db);
 
         let parent_map = block.module.def_map(db);
         let krate = block.module.krate;
@@ -325,8 +330,10 @@ impl DefMap {
         // modules declared by blocks with items. At the moment, we don't use
         // this visibility for anything outside IDE, so that's probably OK.
         let visibility = Visibility::Module(ModuleId { krate, local_id, block: None });
-        let module_data =
-            ModuleData::new(ModuleOrigin::BlockExpr { block: block.ast_id }, visibility);
+        let module_data = ModuleData::new(
+            ModuleOrigin::BlockExpr { block: block.ast_id, id: block_id },
+            visibility,
+        );
 
         let mut def_map = DefMap::empty(krate, parent_map.data.edition, module_data);
         def_map.data = parent_map.data.clone();
@@ -338,7 +345,8 @@ impl DefMap {
             },
         });
 
-        let def_map = collector::collect_defs(db, def_map, tree_id);
+        let def_map =
+            collector::collect_defs(db, def_map, TreeId::new(block.ast_id.file_id, Some(block_id)));
         Arc::new(def_map)
     }
 
@@ -427,15 +435,19 @@ impl DefMap {
         self.block.map(|block| block.block)
     }
 
-    pub(crate) fn prelude(&self) -> Option<ModuleId> {
+    pub(crate) fn prelude(&self) -> Option<(ModuleId, Option<UseId>)> {
         self.prelude
     }
 
-    pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
-        self.data.extern_prelude.iter().map(|(name, &def)| (name, def.into()))
+    pub(crate) fn extern_prelude(
+        &self,
+    ) -> impl Iterator<Item = (&Name, (CrateRootModuleId, Option<ExternCrateId>))> + '_ {
+        self.data.extern_prelude.iter().map(|(name, &def)| (name, def))
     }
 
-    pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
+    pub(crate) fn macro_use_prelude(
+        &self,
+    ) -> impl Iterator<Item = (&Name, (MacroId, Option<ExternCrateId>))> + '_ {
         self.macro_use_prelude.iter().map(|(name, &def)| (name, def))
     }
 
@@ -638,8 +650,8 @@ impl ModuleData {
             ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
                 definition.into()
             }
-            ModuleOrigin::Inline { definition, .. } => definition.file_id,
-            ModuleOrigin::BlockExpr { block } => block.file_id,
+            ModuleOrigin::Inline { definition_tree_id, .. } => definition_tree_id.file_id(),
+            ModuleOrigin::BlockExpr { block, .. } => block.file_id,
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index eef54fc492e..e9e71a8747f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -33,7 +33,7 @@ use crate::{
     attr_macro_as_call_id,
     db::DefDatabase,
     derive_macro_as_call_id,
-    item_scope::{ImportType, PerNsGlobImports},
+    item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
     item_tree::{
         self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
         MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
@@ -52,10 +52,10 @@ use crate::{
     tt,
     visibility::{RawVisibility, Visibility},
     AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
-    ExternBlockLoc, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId,
-    LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc,
-    ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc,
-    TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseLoc,
+    ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
+    ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId,
+    MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc,
+    StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
 };
 
 static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
@@ -146,8 +146,8 @@ impl PartialResolvedImport {
 
 #[derive(Clone, Debug, Eq, PartialEq)]
 enum ImportSource {
-    Use { id: ItemTreeId<item_tree::Use>, use_tree: Idx<ast::UseTree> },
-    ExternCrate(ItemTreeId<item_tree::ExternCrate>),
+    Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool, kind: ImportKind },
+    ExternCrate { id: ExternCrateId },
 }
 
 #[derive(Debug, Eq, PartialEq)]
@@ -155,54 +155,41 @@ struct Import {
     path: ModPath,
     alias: Option<ImportAlias>,
     visibility: RawVisibility,
-    kind: ImportKind,
     source: ImportSource,
-    is_prelude: bool,
-    is_macro_use: bool,
 }
 
 impl Import {
     fn from_use(
-        db: &dyn DefDatabase,
-        krate: CrateId,
         tree: &ItemTree,
-        id: ItemTreeId<item_tree::Use>,
+        item_tree_id: ItemTreeId<item_tree::Use>,
+        id: UseId,
+        is_prelude: bool,
         mut cb: impl FnMut(Self),
     ) {
-        let it = &tree[id.value];
-        let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
+        let it = &tree[item_tree_id.value];
         let visibility = &tree[it.visibility];
-        let is_prelude = attrs.by_key("prelude_import").exists();
         it.use_tree.expand(|idx, path, kind, alias| {
             cb(Self {
                 path,
                 alias,
                 visibility: visibility.clone(),
-                kind,
-                is_prelude,
-                is_macro_use: false,
-                source: ImportSource::Use { id, use_tree: idx },
+                source: ImportSource::Use { use_tree: idx, id, is_prelude, kind },
             });
         });
     }
 
     fn from_extern_crate(
-        db: &dyn DefDatabase,
-        krate: CrateId,
         tree: &ItemTree,
-        id: ItemTreeId<item_tree::ExternCrate>,
+        item_tree_id: ItemTreeId<item_tree::ExternCrate>,
+        id: ExternCrateId,
     ) -> Self {
-        let it = &tree[id.value];
-        let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
+        let it = &tree[item_tree_id.value];
         let visibility = &tree[it.visibility];
         Self {
             path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
             alias: it.alias.clone(),
             visibility: visibility.clone(),
-            kind: ImportKind::Plain,
-            is_prelude: false,
-            is_macro_use: attrs.by_key("macro_use").exists(),
-            source: ImportSource::ExternCrate(id),
+            source: ImportSource::ExternCrate { id },
         }
     }
 }
@@ -235,7 +222,7 @@ struct DefCollector<'a> {
     db: &'a dyn DefDatabase,
     def_map: DefMap,
     deps: FxHashMap<Name, Dependency>,
-    glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
+    glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>,
     unresolved_imports: Vec<ImportDirective>,
     indeterminate_imports: Vec<ImportDirective>,
     unresolved_macros: Vec<MacroDirective>,
@@ -280,7 +267,7 @@ impl DefCollector<'_> {
             if dep.is_prelude() {
                 crate_data
                     .extern_prelude
-                    .insert(name.clone(), CrateRootModuleId { krate: dep.crate_id });
+                    .insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
             }
         }
 
@@ -556,8 +543,12 @@ impl DefCollector<'_> {
             self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
 
         match per_ns.types {
-            Some((ModuleDefId::ModuleId(m), _)) => {
-                self.def_map.prelude = Some(m);
+            Some((ModuleDefId::ModuleId(m), _, import)) => {
+                // FIXME: This should specifically look for a glob import somehow and record that here
+                self.def_map.prelude = Some((
+                    m,
+                    import.and_then(ImportOrExternCrate::into_import).map(|it| it.import),
+                ));
             }
             types => {
                 tracing::debug!(
@@ -657,9 +648,9 @@ impl DefCollector<'_> {
             self.def_map.modules[module_id].scope.declare(macro_.into());
             self.update(
                 module_id,
-                &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+                &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
                 Visibility::Public,
-                ImportType::Named,
+                None,
             );
         }
     }
@@ -693,9 +684,9 @@ impl DefCollector<'_> {
         self.def_map.modules[module_id].scope.declare(macro_.into());
         self.update(
             module_id,
-            &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+            &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
             vis,
-            ImportType::Named,
+            None,
         );
     }
 
@@ -708,9 +699,9 @@ impl DefCollector<'_> {
         self.def_map.modules[module_id].scope.declare(macro_.into());
         self.update(
             module_id,
-            &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+            &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
             Visibility::Public,
-            ImportType::Named,
+            None,
         );
     }
 
@@ -720,21 +711,29 @@ impl DefCollector<'_> {
     /// Exported macros are just all macros in the root module scope.
     /// Note that it contains not only all `#[macro_export]` macros, but also all aliases
     /// created by `use` in the root module, ignoring the visibility of `use`.
-    fn import_macros_from_extern_crate(&mut self, krate: CrateId, names: Option<Vec<Name>>) {
+    fn import_macros_from_extern_crate(
+        &mut self,
+        krate: CrateId,
+        names: Option<Vec<Name>>,
+        extern_crate: Option<ExternCrateId>,
+    ) {
         let def_map = self.db.crate_def_map(krate);
         // `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
         // macros.
         let root_scope = &def_map[DefMap::ROOT].scope;
-        if let Some(names) = names {
-            for name in names {
-                // FIXME: Report diagnostic on 404.
-                if let Some(def) = root_scope.get(&name).take_macros() {
-                    self.def_map.macro_use_prelude.insert(name, def);
+        match names {
+            Some(names) => {
+                for name in names {
+                    // FIXME: Report diagnostic on 404.
+                    if let Some(def) = root_scope.get(&name).take_macros() {
+                        self.def_map.macro_use_prelude.insert(name, (def, extern_crate));
+                    }
                 }
             }
-        } else {
-            for (name, def) in root_scope.macros() {
-                self.def_map.macro_use_prelude.insert(name.clone(), def);
+            None => {
+                for (name, def) in root_scope.macros() {
+                    self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
+                }
             }
         }
     }
@@ -771,48 +770,53 @@ impl DefCollector<'_> {
         let _p = profile::span("resolve_import")
             .detail(|| format!("{}", import.path.display(self.db.upcast())));
         tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
-        if matches!(import.source, ImportSource::ExternCrate { .. }) {
-            let name = import
-                .path
-                .as_ident()
-                .expect("extern crate should have been desugared to one-element path");
-
-            let res = self.resolve_extern_crate(name);
-
-            match res {
-                Some(res) => {
-                    PartialResolvedImport::Resolved(PerNs::types(res.into(), Visibility::Public))
+        match import.source {
+            ImportSource::ExternCrate { .. } => {
+                let name = import
+                    .path
+                    .as_ident()
+                    .expect("extern crate should have been desugared to one-element path");
+
+                let res = self.resolve_extern_crate(name);
+
+                match res {
+                    Some(res) => PartialResolvedImport::Resolved(PerNs::types(
+                        res.into(),
+                        Visibility::Public,
+                        None,
+                    )),
+                    None => PartialResolvedImport::Unresolved,
                 }
-                None => PartialResolvedImport::Unresolved,
             }
-        } else {
-            let res = self.def_map.resolve_path_fp_with_macro(
-                self.db,
-                ResolveMode::Import,
-                module_id,
-                &import.path,
-                BuiltinShadowMode::Module,
-                None, // An import may resolve to any kind of macro.
-            );
+            ImportSource::Use { .. } => {
+                let res = self.def_map.resolve_path_fp_with_macro(
+                    self.db,
+                    ResolveMode::Import,
+                    module_id,
+                    &import.path,
+                    BuiltinShadowMode::Module,
+                    None, // An import may resolve to any kind of macro.
+                );
 
-            let def = res.resolved_def;
-            if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
-                return PartialResolvedImport::Unresolved;
-            }
+                let def = res.resolved_def;
+                if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
+                    return PartialResolvedImport::Unresolved;
+                }
 
-            if let Some(krate) = res.krate {
-                if krate != self.def_map.krate {
-                    return PartialResolvedImport::Resolved(
-                        def.filter_visibility(|v| matches!(v, Visibility::Public)),
-                    );
+                if let Some(krate) = res.krate {
+                    if krate != self.def_map.krate {
+                        return PartialResolvedImport::Resolved(
+                            def.filter_visibility(|v| matches!(v, Visibility::Public)),
+                        );
+                    }
                 }
-            }
 
-            // Check whether all namespaces are resolved.
-            if def.is_full() {
-                PartialResolvedImport::Resolved(def)
-            } else {
-                PartialResolvedImport::Indeterminate(def)
+                // Check whether all namespaces are resolved.
+                if def.is_full() {
+                    PartialResolvedImport::Resolved(def)
+                } else {
+                    PartialResolvedImport::Indeterminate(def)
+                }
             }
         }
     }
@@ -837,8 +841,9 @@ impl DefCollector<'_> {
             .resolve_visibility(self.db, module_id, &directive.import.visibility, false)
             .unwrap_or(Visibility::Public);
 
-        match import.kind {
-            ImportKind::Plain | ImportKind::TypeOnly => {
+        match import.source {
+            ImportSource::ExternCrate { .. }
+            | ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => {
                 let name = match &import.alias {
                     Some(ImportAlias::Alias(name)) => Some(name),
                     Some(ImportAlias::Underscore) => None,
@@ -851,40 +856,44 @@ impl DefCollector<'_> {
                     },
                 };
 
-                if import.kind == ImportKind::TypeOnly {
-                    def.values = None;
-                    def.macros = None;
-                }
-
-                tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
-
-                // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
-                if matches!(import.source, ImportSource::ExternCrate { .. })
-                    && self.def_map.block.is_none()
-                    && module_id == DefMap::ROOT
-                {
-                    if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
-                    {
-                        if let Ok(def) = def.try_into() {
-                            Arc::get_mut(&mut self.def_map.data)
-                                .unwrap()
-                                .extern_prelude
-                                .insert(name.clone(), def);
+                let imp = match import.source {
+                    // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
+                    ImportSource::ExternCrate { id, .. } => {
+                        if self.def_map.block.is_none() && module_id == DefMap::ROOT {
+                            if let (Some(ModuleDefId::ModuleId(def)), Some(name)) =
+                                (def.take_types(), name)
+                            {
+                                if let Ok(def) = def.try_into() {
+                                    Arc::get_mut(&mut self.def_map.data)
+                                        .unwrap()
+                                        .extern_prelude
+                                        .insert(name.clone(), (def, Some(id)));
+                                }
+                            }
                         }
+                        ImportType::ExternCrate(id)
                     }
-                }
+                    ImportSource::Use { kind, id, use_tree, .. } => {
+                        if kind == ImportKind::TypeOnly {
+                            def.values = None;
+                            def.macros = None;
+                        }
+                        ImportType::Import(ImportId { import: id, idx: use_tree })
+                    }
+                };
+                tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
 
-                self.update(module_id, &[(name.cloned(), def)], vis, ImportType::Named);
+                self.update(module_id, &[(name.cloned(), def)], vis, Some(imp));
             }
-            ImportKind::Glob => {
+            ImportSource::Use { kind: ImportKind::Glob, id, .. } => {
                 tracing::debug!("glob import: {:?}", import);
                 match def.take_types() {
                     Some(ModuleDefId::ModuleId(m)) => {
-                        if import.is_prelude {
+                        if let ImportSource::Use { id, is_prelude: true, .. } = import.source {
                             // Note: This dodgily overrides the injected prelude. The rustc
                             // implementation seems to work the same though.
                             cov_mark::hit!(std_prelude);
-                            self.def_map.prelude = Some(m);
+                            self.def_map.prelude = Some((m, Some(id)));
                         } else if m.krate != self.def_map.krate {
                             cov_mark::hit!(glob_across_crates);
                             // glob import from other crate => we can just import everything once
@@ -901,7 +910,7 @@ impl DefCollector<'_> {
                                 .filter(|(_, res)| !res.is_none())
                                 .collect::<Vec<_>>();
 
-                            self.update(module_id, &items, vis, ImportType::Glob);
+                            self.update(module_id, &items, vis, Some(ImportType::Glob(id)));
                         } else {
                             // glob import from same crate => we do an initial
                             // import, and then need to propagate any further
@@ -933,11 +942,11 @@ impl DefCollector<'_> {
                                 .filter(|(_, res)| !res.is_none())
                                 .collect::<Vec<_>>();
 
-                            self.update(module_id, &items, vis, ImportType::Glob);
+                            self.update(module_id, &items, vis, Some(ImportType::Glob(id)));
                             // record the glob import in case we add further items
                             let glob = self.glob_imports.entry(m.local_id).or_default();
-                            if !glob.iter().any(|(mid, _)| *mid == module_id) {
-                                glob.push((module_id, vis));
+                            if !glob.iter().any(|(mid, _, _)| *mid == module_id) {
+                                glob.push((module_id, vis, id));
                             }
                         }
                     }
@@ -959,11 +968,11 @@ impl DefCollector<'_> {
                             .map(|(local_id, variant_data)| {
                                 let name = variant_data.name.clone();
                                 let variant = EnumVariantId { parent: e, local_id };
-                                let res = PerNs::both(variant.into(), variant.into(), vis);
+                                let res = PerNs::both(variant.into(), variant.into(), vis, None);
                                 (Some(name), res)
                             })
                             .collect::<Vec<_>>();
-                        self.update(module_id, &resolutions, vis, ImportType::Glob);
+                        self.update(module_id, &resolutions, vis, Some(ImportType::Glob(id)));
                     }
                     Some(d) => {
                         tracing::debug!("glob import {:?} from non-module/enum {:?}", import, d);
@@ -983,10 +992,10 @@ impl DefCollector<'_> {
         resolutions: &[(Option<Name>, PerNs)],
         // Visibility this import will have
         vis: Visibility,
-        import_type: ImportType,
+        import: Option<ImportType>,
     ) {
         self.db.unwind_if_cancelled();
-        self.update_recursive(module_id, resolutions, vis, import_type, 0)
+        self.update_recursive(module_id, resolutions, vis, import, 0)
     }
 
     fn update_recursive(
@@ -997,7 +1006,7 @@ impl DefCollector<'_> {
         // All resolutions are imported with this visibility; the visibilities in
         // the `PerNs` values are ignored and overwritten
         vis: Visibility,
-        import_type: ImportType,
+        import: Option<ImportType>,
         depth: usize,
     ) {
         if GLOB_RECURSION_LIMIT.check(depth).is_err() {
@@ -1014,7 +1023,7 @@ impl DefCollector<'_> {
                         &mut self.from_glob_import,
                         (module_id, name.clone()),
                         res.with_visibility(vis),
-                        import_type,
+                        import,
                     );
                 }
                 None => {
@@ -1059,7 +1068,7 @@ impl DefCollector<'_> {
             .get(&module_id)
             .into_iter()
             .flatten()
-            .filter(|(glob_importing_module, _)| {
+            .filter(|(glob_importing_module, _, _)| {
                 // we know all resolutions have the same visibility (`vis`), so we
                 // just need to check that once
                 vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module)
@@ -1067,12 +1076,12 @@ impl DefCollector<'_> {
             .cloned()
             .collect::<Vec<_>>();
 
-        for (glob_importing_module, glob_import_vis) in glob_imports {
+        for (glob_importing_module, glob_import_vis, use_) in glob_imports {
             self.update_recursive(
                 glob_importing_module,
                 resolutions,
                 glob_import_vis,
-                ImportType::Glob,
+                Some(ImportType::Glob(use_)),
                 depth + 1,
             );
         }
@@ -1460,31 +1469,34 @@ impl DefCollector<'_> {
         // heuristic, but it works in practice.
         let mut diagnosed_extern_crates = FxHashSet::default();
         for directive in &self.unresolved_imports {
-            if let ImportSource::ExternCrate(krate) = directive.import.source {
-                let item_tree = krate.item_tree(self.db);
-                let extern_crate = &item_tree[krate.value];
+            if let ImportSource::ExternCrate { id } = directive.import.source {
+                let item_tree_id = id.lookup(self.db).id;
+                let item_tree = item_tree_id.item_tree(self.db);
+                let extern_crate = &item_tree[item_tree_id.value];
 
                 diagnosed_extern_crates.insert(extern_crate.name.clone());
 
                 self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate(
                     directive.module_id,
-                    InFile::new(krate.file_id(), extern_crate.ast_id),
+                    InFile::new(item_tree_id.file_id(), extern_crate.ast_id),
                 ));
             }
         }
 
         for directive in &self.unresolved_imports {
-            if let ImportSource::Use { id: import, use_tree } = directive.import.source {
+            if let ImportSource::Use { use_tree, id, is_prelude: _, kind: _ } =
+                directive.import.source
+            {
                 if matches!(
                     (directive.import.path.segments().first(), &directive.import.path.kind),
                     (Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate)
                 ) {
                     continue;
                 }
-
+                let item_tree_id = id.lookup(self.db).id;
                 self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
                     directive.module_id,
-                    import,
+                    item_tree_id,
                     use_tree,
                 ));
             }
@@ -1519,72 +1531,66 @@ impl ModCollector<'_, '_> {
         self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
 
         // Prelude module is always considered to be `#[macro_use]`.
-        if let Some(prelude_module) = self.def_collector.def_map.prelude {
+        if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude {
             if prelude_module.krate != krate && is_crate_root {
                 cov_mark::hit!(prelude_is_macro_use);
-                self.def_collector.import_macros_from_extern_crate(prelude_module.krate, None);
-            }
-        }
-
-        // This should be processed eagerly instead of deferred to resolving.
-        // `#[macro_use] extern crate` is hoisted to imports macros before collecting
-        // any other items.
-        //
-        // If we're not at the crate root, `macro_use`d extern crates are an error so let's just
-        // ignore them.
-        if is_crate_root {
-            for &item in items {
-                if let ModItem::ExternCrate(id) = item {
-                    self.process_macro_use_extern_crate(id);
-                }
+                self.def_collector.import_macros_from_extern_crate(
+                    prelude_module.krate,
+                    None,
+                    None,
+                );
             }
         }
+        let db = self.def_collector.db;
+        let module_id = self.module_id;
+        let update_def =
+            |def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| {
+                def_collector.def_map.modules[module_id].scope.declare(id);
+                def_collector.update(
+                    module_id,
+                    &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor, None))],
+                    vis,
+                    None,
+                )
+            };
+        let resolve_vis = |def_map: &DefMap, visibility| {
+            def_map
+                .resolve_visibility(db, module_id, visibility, false)
+                .unwrap_or(Visibility::Public)
+        };
 
-        for &item in items {
-            let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
+        let mut process_mod_item = |item: ModItem| {
+            let attrs = self.item_tree.attrs(db, krate, item.into());
             if let Some(cfg) = attrs.cfg() {
                 if !self.is_cfg_enabled(&cfg) {
                     self.emit_unconfigured_diagnostic(item, &cfg);
-                    continue;
+                    return;
                 }
             }
 
             if let Err(()) = self.resolve_attributes(&attrs, item, container) {
                 // Do not process the item. It has at least one non-builtin attribute, so the
                 // fixed-point algorithm is required to resolve the rest of them.
-                continue;
+                return;
             }
 
-            let db = self.def_collector.db;
-            let module = self.def_collector.def_map.module_id(self.module_id);
+            let module = self.def_collector.def_map.module_id(module_id);
             let def_map = &mut self.def_collector.def_map;
-            let update_def =
-                |def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| {
-                    def_collector.def_map.modules[self.module_id].scope.declare(id);
-                    def_collector.update(
-                        self.module_id,
-                        &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
-                        vis,
-                        ImportType::Named,
-                    )
-                };
-            let resolve_vis = |def_map: &DefMap, visibility| {
-                def_map
-                    .resolve_visibility(db, self.module_id, visibility, false)
-                    .unwrap_or(Visibility::Public)
-            };
 
             match item {
                 ModItem::Mod(m) => self.collect_module(m, &attrs),
-                ModItem::Use(import_id) => {
-                    let _import_id =
-                        UseLoc { container: module, id: ItemTreeId::new(self.tree_id, import_id) }
-                            .intern(db);
+                ModItem::Use(item_tree_id) => {
+                    let id = UseLoc {
+                        container: module,
+                        id: ItemTreeId::new(self.tree_id, item_tree_id),
+                    }
+                    .intern(db);
+                    let is_prelude = attrs.by_key("prelude_import").exists();
                     Import::from_use(
-                        db,
-                        krate,
                         self.item_tree,
-                        ItemTreeId::new(self.tree_id, import_id),
+                        ItemTreeId::new(self.tree_id, item_tree_id),
+                        id,
+                        is_prelude,
                         |import| {
                             self.def_collector.unresolved_imports.push(ImportDirective {
                                 module_id: self.module_id,
@@ -1594,22 +1600,29 @@ impl ModCollector<'_, '_> {
                         },
                     )
                 }
-                ModItem::ExternCrate(import_id) => {
-                    let extern_crate_id = ExternCrateLoc {
+                ModItem::ExternCrate(item_tree_id) => {
+                    let id = ExternCrateLoc {
                         container: module,
-                        id: ItemTreeId::new(self.tree_id, import_id),
+                        id: ItemTreeId::new(self.tree_id, item_tree_id),
                     }
                     .intern(db);
+                    if is_crate_root {
+                        self.process_macro_use_extern_crate(
+                            item_tree_id,
+                            id,
+                            attrs.by_key("macro_use").attrs(),
+                        );
+                    }
+
                     self.def_collector.def_map.modules[self.module_id]
                         .scope
-                        .define_extern_crate_decl(extern_crate_id);
+                        .define_extern_crate_decl(id);
                     self.def_collector.unresolved_imports.push(ImportDirective {
                         module_id: self.module_id,
                         import: Import::from_extern_crate(
-                            db,
-                            krate,
                             self.item_tree,
-                            ItemTreeId::new(self.tree_id, import_id),
+                            ItemTreeId::new(self.tree_id, item_tree_id),
+                            id,
                         ),
                         status: PartialResolvedImport::Unresolved,
                     })
@@ -1768,21 +1781,34 @@ impl ModCollector<'_, '_> {
                     );
                 }
             }
+        };
+
+        // extern crates should be processed eagerly instead of deferred to resolving.
+        // `#[macro_use] extern crate` is hoisted to imports macros before collecting
+        // any other items.
+        if is_crate_root {
+            items
+                .iter()
+                .filter(|it| matches!(it, ModItem::ExternCrate(..)))
+                .copied()
+                .for_each(&mut process_mod_item);
+            items
+                .iter()
+                .filter(|it| !matches!(it, ModItem::ExternCrate(..)))
+                .copied()
+                .for_each(process_mod_item);
+        } else {
+            items.iter().copied().for_each(process_mod_item);
         }
     }
 
-    fn process_macro_use_extern_crate(&mut self, extern_crate: FileItemTreeId<ExternCrate>) {
+    fn process_macro_use_extern_crate<'a>(
+        &mut self,
+        extern_crate: FileItemTreeId<ExternCrate>,
+        extern_crate_id: ExternCrateId,
+        macro_use_attrs: impl Iterator<Item = &'a Attr>,
+    ) {
         let db = self.def_collector.db;
-        let attrs = self.item_tree.attrs(
-            db,
-            self.def_collector.def_map.krate,
-            ModItem::from(extern_crate).into(),
-        );
-        if let Some(cfg) = attrs.cfg() {
-            if !self.is_cfg_enabled(&cfg) {
-                return;
-            }
-        }
 
         let target_crate =
             match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) {
@@ -1798,11 +1824,11 @@ impl ModCollector<'_, '_> {
 
         let mut single_imports = Vec::new();
         let hygiene = Hygiene::new_unhygienic();
-        for attr in attrs.by_key("macro_use").attrs() {
+        for attr in macro_use_attrs {
             let Some(paths) = attr.parse_path_comma_token_tree(db.upcast(), &hygiene) else {
                 // `#[macro_use]` (without any paths) found, forget collected names and just import
                 // all visible macros.
-                self.def_collector.import_macros_from_extern_crate(target_crate, None);
+                self.def_collector.import_macros_from_extern_crate(target_crate, None, Some(extern_crate_id));
                 return;
             };
             for path in paths {
@@ -1812,7 +1838,11 @@ impl ModCollector<'_, '_> {
             }
         }
 
-        self.def_collector.import_macros_from_extern_crate(target_crate, Some(single_imports));
+        self.def_collector.import_macros_from_extern_crate(
+            target_crate,
+            Some(single_imports),
+            Some(extern_crate_id),
+        );
     }
 
     fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) {
@@ -1824,7 +1854,7 @@ impl ModCollector<'_, '_> {
             ModKind::Inline { items } => {
                 let module_id = self.push_child_module(
                     module.name.clone(),
-                    AstId::new(self.file_id(), module.ast_id),
+                    module.ast_id,
                     None,
                     &self.item_tree[module.visibility],
                     module_id,
@@ -1862,7 +1892,7 @@ impl ModCollector<'_, '_> {
                         if is_enabled {
                             let module_id = self.push_child_module(
                                 module.name.clone(),
-                                ast_id,
+                                ast_id.value,
                                 Some((file_id, is_mod_rs)),
                                 &self.item_tree[module.visibility],
                                 module_id,
@@ -1889,7 +1919,7 @@ impl ModCollector<'_, '_> {
                     Err(candidates) => {
                         self.push_child_module(
                             module.name.clone(),
-                            ast_id,
+                            ast_id.value,
                             None,
                             &self.item_tree[module.visibility],
                             module_id,
@@ -1906,7 +1936,7 @@ impl ModCollector<'_, '_> {
     fn push_child_module(
         &mut self,
         name: Name,
-        declaration: AstId<ast::Module>,
+        declaration: FileAstId<ast::Module>,
         definition: Option<(FileId, bool)>,
         visibility: &crate::visibility::RawVisibility,
         mod_tree_id: FileItemTreeId<Mod>,
@@ -1948,9 +1978,9 @@ impl ModCollector<'_, '_> {
         def_map.modules[self.module_id].scope.declare(def);
         self.def_collector.update(
             self.module_id,
-            &[(Some(name), PerNs::from_def(def, vis, false))],
+            &[(Some(name), PerNs::from_def(def, vis, false, None))],
             vis,
-            ImportType::Named,
+            None,
         );
         res
     }
@@ -2198,7 +2228,7 @@ impl ModCollector<'_, '_> {
                             map[module].scope.get_legacy_macro(name)?.last().copied()
                         })
                         .or_else(|| def_map[self.module_id].scope.get(name).take_macros())
-                        .or_else(|| def_map.macro_use_prelude.get(name).copied())
+                        .or_else(|| Some(def_map.macro_use_prelude.get(name).copied()?.0))
                         .filter(|&id| {
                             sub_namespace_match(
                                 Some(MacroSubNs::from_id(db, id)),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
index de22ea10146..460a908b6db 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
@@ -15,8 +15,9 @@ use hir_expand::name::Name;
 use triomphe::Arc;
 
 use crate::{
+    data::adt::VariantData,
     db::DefDatabase,
-    item_scope::BUILTIN_SCOPE,
+    item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
     nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
     path::{ModPath, PathKind},
     per_ns::PerNs,
@@ -65,7 +66,7 @@ impl PerNs {
         db: &dyn DefDatabase,
         expected: Option<MacroSubNs>,
     ) -> Self {
-        self.macros = self.macros.filter(|&(id, _)| {
+        self.macros = self.macros.filter(|&(id, _, _)| {
             let this = MacroSubNs::from_id(db, id);
             sub_namespace_match(Some(this), expected)
         });
@@ -196,15 +197,15 @@ impl DefMap {
             PathKind::DollarCrate(krate) => {
                 if krate == self.krate {
                     cov_mark::hit!(macro_dollar_crate_self);
-                    PerNs::types(self.crate_root().into(), Visibility::Public)
+                    PerNs::types(self.crate_root().into(), Visibility::Public, None)
                 } else {
                     let def_map = db.crate_def_map(krate);
                     let module = def_map.module_id(Self::ROOT);
                     cov_mark::hit!(macro_dollar_crate_other);
-                    PerNs::types(module.into(), Visibility::Public)
+                    PerNs::types(module.into(), Visibility::Public, None)
                 }
             }
-            PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public),
+            PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public, None),
             // plain import or absolute path in 2015: crate-relative with
             // fallback to extern prelude (with the simplification in
             // rust-lang/rust#57745)
@@ -291,7 +292,7 @@ impl DefMap {
                     );
                 }
 
-                PerNs::types(module.into(), Visibility::Public)
+                PerNs::types(module.into(), Visibility::Public, None)
             }
             PathKind::Abs => {
                 // 2018-style absolute path -- only extern prelude
@@ -299,9 +300,13 @@ impl DefMap {
                     Some((_, segment)) => segment,
                     None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
                 };
-                if let Some(&def) = self.data.extern_prelude.get(segment) {
+                if let Some(&(def, extern_crate)) = self.data.extern_prelude.get(segment) {
                     tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
-                    PerNs::types(def.into(), Visibility::Public)
+                    PerNs::types(
+                        def.into(),
+                        Visibility::Public,
+                        extern_crate.map(ImportOrExternCrate::ExternCrate),
+                    )
                 } else {
                     return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
                 }
@@ -309,7 +314,7 @@ impl DefMap {
         };
 
         for (i, segment) in segments {
-            let (curr, vis) = match curr_per_ns.take_types_vis() {
+            let (curr, vis, imp) = match curr_per_ns.take_types_full() {
                 Some(r) => r,
                 None => {
                     // we still have path segments left, but the path so far
@@ -364,18 +369,20 @@ impl DefMap {
                         Some(local_id) => {
                             let variant = EnumVariantId { parent: e, local_id };
                             match &*enum_data.variants[local_id].variant_data {
-                                crate::data::adt::VariantData::Record(_) => {
-                                    PerNs::types(variant.into(), Visibility::Public)
-                                }
-                                crate::data::adt::VariantData::Tuple(_)
-                                | crate::data::adt::VariantData::Unit => {
-                                    PerNs::both(variant.into(), variant.into(), Visibility::Public)
+                                VariantData::Record(_) => {
+                                    PerNs::types(variant.into(), Visibility::Public, None)
                                 }
+                                VariantData::Tuple(_) | VariantData::Unit => PerNs::both(
+                                    variant.into(),
+                                    variant.into(),
+                                    Visibility::Public,
+                                    None,
+                                ),
                             }
                         }
                         None => {
                             return ResolvePathResult::with(
-                                PerNs::types(e.into(), vis),
+                                PerNs::types(e.into(), vis, imp),
                                 ReachedFixedPoint::Yes,
                                 Some(i),
                                 Some(self.krate),
@@ -393,7 +400,7 @@ impl DefMap {
                     );
 
                     return ResolvePathResult::with(
-                        PerNs::types(s, vis),
+                        PerNs::types(s, vis, imp),
                         ReachedFixedPoint::Yes,
                         Some(i),
                         Some(self.krate),
@@ -430,7 +437,7 @@ impl DefMap {
             .filter(|&id| {
                 sub_namespace_match(Some(MacroSubNs::from_id(db, id)), expected_macro_subns)
             })
-            .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
+            .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public, None));
         let from_scope = self[module].scope.get(name).filter_macro(db, expected_macro_subns);
         let from_builtin = match self.block {
             Some(_) => {
@@ -449,18 +456,27 @@ impl DefMap {
 
         let extern_prelude = || {
             if self.block.is_some() {
-                // Don't resolve extern prelude in block `DefMap`s.
+                // Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so
+                // that blocks can properly shadow them
                 return PerNs::none();
             }
-            self.data
-                .extern_prelude
-                .get(name)
-                .map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
+            self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
+                PerNs::types(
+                    it.into(),
+                    Visibility::Public,
+                    extern_crate.map(ImportOrExternCrate::ExternCrate),
+                )
+            })
         };
         let macro_use_prelude = || {
-            self.macro_use_prelude
-                .get(name)
-                .map_or(PerNs::none(), |&it| PerNs::macros(it.into(), Visibility::Public))
+            self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
+                PerNs::macros(
+                    it.into(),
+                    Visibility::Public,
+                    // FIXME?
+                    None, // extern_crate.map(ImportOrExternCrate::ExternCrate),
+                )
+            })
         };
         let prelude = || self.resolve_in_prelude(db, name);
 
@@ -488,18 +504,23 @@ impl DefMap {
                 // Don't resolve extern prelude in block `DefMap`s.
                 return PerNs::none();
             }
-            self.data
-                .extern_prelude
-                .get(name)
-                .copied()
-                .map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public))
+            self.data.extern_prelude.get(name).copied().map_or(
+                PerNs::none(),
+                |(it, extern_crate)| {
+                    PerNs::types(
+                        it.into(),
+                        Visibility::Public,
+                        extern_crate.map(ImportOrExternCrate::ExternCrate),
+                    )
+                },
+            )
         };
 
         from_crate_root.or_else(from_extern_prelude)
     }
 
     fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
-        if let Some(prelude) = self.prelude {
+        if let Some((prelude, _use)) = self.prelude {
             let keep;
             let def_map = if prelude.krate == self.krate {
                 self
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
index dd7c3c36306..e7cc44b04da 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs
@@ -168,7 +168,7 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Foo: t v
+            Foo: ti vi
             foo: t
 
             crate::foo
@@ -194,8 +194,8 @@ pub enum Quux {};
 "#,
         expect![[r#"
             crate
-            Baz: t v
-            Quux: t
+            Baz: ti vi
+            Quux: ti
             foo: t
 
             crate::foo
@@ -225,11 +225,11 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Baz: t v
+            Baz: ti vi
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
             bar: t
 
             crate::foo::bar
@@ -274,7 +274,7 @@ use self::E::V;
         expect![[r#"
             crate
             E: t
-            V: t v
+            V: ti vi
         "#]],
     );
 }
@@ -307,7 +307,7 @@ pub struct FromLib;
 
             crate::foo
             Bar: _
-            FromLib: t v
+            FromLib: ti vi
         "#]],
     );
 }
@@ -328,7 +328,7 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Baz: t
+            Baz: ti
             foo: t
 
             crate::foo
@@ -352,7 +352,7 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Baz: t v
+            Baz: ti vi
         "#]],
     );
 }
@@ -375,13 +375,13 @@ pub struct Arc;
         expect![[r#"
             crate
             alloc: t
-            alloc_crate: t
+            alloc_crate: te
             sync: t
 
             crate::alloc
 
             crate::sync
-            Arc: t v
+            Arc: ti vi
         "#]],
     );
 }
@@ -404,13 +404,13 @@ pub struct Arc;
         expect![[r#"
             crate
             alloc: t
-            alloc_crate: t
+            alloc_crate: te
             sync: t
 
             crate::alloc
 
             crate::sync
-            Arc: t v
+            Arc: ti vi
         "#]],
     );
 }
@@ -426,7 +426,7 @@ extern crate self as bla;
 "#,
         expect![[r#"
             crate
-            bla: t
+            bla: te
         "#]],
     );
 }
@@ -447,7 +447,7 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Baz: t v
+            Baz: ti vi
         "#]],
     );
 }
@@ -465,7 +465,7 @@ pub struct Bar;
 "#,
         expect![[r#"
             crate
-            Bar: t v
+            Bar: ti vi
             foo: v
         "#]],
     );
@@ -492,9 +492,9 @@ fn no_std_prelude() {
         }
     "#,
         expect![[r#"
-        crate
-        Rust: t v
-    "#]],
+            crate
+            Rust: ti vi
+        "#]],
     );
 }
 
@@ -516,9 +516,9 @@ fn edition_specific_preludes() {
         }
     "#,
         expect![[r#"
-        crate
-        Rust2018: t v
-    "#]],
+            crate
+            Rust2018: ti vi
+        "#]],
     );
     check(
         r#"
@@ -533,9 +533,9 @@ fn edition_specific_preludes() {
         }
     "#,
         expect![[r#"
-        crate
-        Rust2021: t v
-    "#]],
+            crate
+            Rust2021: ti vi
+        "#]],
     );
 }
 
@@ -563,8 +563,8 @@ pub mod prelude {
 "#,
         expect![[r#"
             crate
-            Bar: t v
-            Foo: t v
+            Bar: ti vi
+            Foo: ti vi
         "#]],
     );
 }
@@ -590,7 +590,7 @@ pub mod prelude {
 "#,
         expect![[r#"
             crate
-            Bar: t v
+            Bar: ti vi
             Baz: _
             Foo: _
         "#]],
@@ -619,8 +619,8 @@ pub mod prelude {
         expect![[r#"
             crate
             Bar: _
-            Baz: t v
-            Foo: t v
+            Baz: ti vi
+            Foo: ti vi
         "#]],
     );
 }
@@ -643,7 +643,7 @@ mod b {
 "#,
         expect![[r#"
             crate
-            T: t v
+            T: ti vi
             a: t
             b: t
 
@@ -816,8 +816,8 @@ fn bar() {}
         expect![[r#"
             crate
             bar: v
-            baz: v
-            foo: t
+            baz: vi
+            foo: ti
         "#]],
     );
 }
@@ -836,7 +836,7 @@ use self::m::S::{self};
     "#,
         expect![[r#"
             crate
-            S: t
+            S: ti
             m: t
 
             crate::m
@@ -860,8 +860,8 @@ pub const settings: () = ();
         "#,
         expect![[r#"
             crate
-            Settings: t v
-            settings: v
+            Settings: ti vi
+            settings: vi
         "#]],
     )
 }
@@ -890,8 +890,8 @@ pub struct Struct;
         "#,
         expect![[r#"
             crate
-            Struct: t v
-            dep: t
+            Struct: ti vi
+            dep: te
         "#]],
     );
 }
@@ -917,13 +917,13 @@ use some_module::unknown_func;
             crate
             other_module: t
             some_module: t
-            unknown_func: v
+            unknown_func: vi
 
             crate::other_module
             some_submodule: t
 
             crate::other_module::some_submodule
-            unknown_func: v
+            unknown_func: vi
 
             crate::some_module
             unknown_func: v
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs
index 88a3c76393f..1ca74b5da6b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs
@@ -24,7 +24,7 @@ pub struct Baz;
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
             Foo: t v
             bar: t
 
@@ -237,9 +237,9 @@ pub mod baz { pub struct Bar; }
 "#,
         expect![[r#"
             crate
-            Bar: t v
+            Bar: ti vi
             bar: t
-            baz: t
+            baz: ti
             foo: t
 
             crate::bar
@@ -276,9 +276,9 @@ pub mod baz { pub struct Bar; }
 "#,
         expect![[r#"
             crate
-            Bar: t v
+            Bar: ti vi
             bar: t
-            baz: t
+            baz: ti
             foo: t
 
             crate::bar
@@ -323,7 +323,7 @@ mod d {
             X: t v
 
             crate::b
-            foo: t
+            foo: ti
 
             crate::c
             foo: t
@@ -332,8 +332,8 @@ mod d {
             Y: t v
 
             crate::d
-            Y: t v
-            foo: t
+            Y: ti vi
+            foo: ti
         "#]],
     );
 }
@@ -355,7 +355,7 @@ use event::Event;
         "#,
         expect![[r#"
             crate
-            Event: t
+            Event: ti
             event: t
 
             crate::event
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
index 40d3a16540d..4a86f88e57a 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
@@ -212,7 +212,7 @@ pub type Ty = ();
             }
 
             for (_, res) in module_data.scope.resolutions() {
-                match res.values.or(res.types).unwrap().0 {
+                match res.values.map(|(a, _, _)| a).or(res.types.map(|(a, _, _)| a)).unwrap() {
                     ModuleDefId::FunctionId(f) => _ = db.function_data(f),
                     ModuleDefId::AdtId(adt) => match adt {
                         AdtId::StructId(it) => _ = db.struct_data(it),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
index f4cca8d68d0..e64fa0b46f1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/macros.rs
@@ -203,8 +203,8 @@ macro_rules! bar {
         expect![[r#"
             crate
             Foo: t
-            bar: m
-            foo: m
+            bar: mi
+            foo: mi
         "#]],
     );
 }
@@ -251,7 +251,7 @@ mod priv_mod {
             Bar: t v
             Foo: t v
             bar: t
-            foo: t
+            foo: te
 
             crate::bar
             Baz: t v
@@ -318,9 +318,9 @@ macro_rules! baz3 { () => { struct OkBaz3; } }
             OkBaz1: t v
             OkBaz2: t v
             OkBaz3: t v
-            all: t
-            empty: t
-            multiple: t
+            all: te
+            empty: te
+            multiple: te
         "#]],
     );
 }
@@ -551,8 +551,8 @@ fn baz() {}
 "#,
         expect![[r#"
             crate
-            bar: t m
-            baz: t v m
+            bar: ti mi
+            baz: ti v mi
             foo: t m
         "#]],
     );
@@ -583,7 +583,7 @@ mod m {
             crate
             Alias: t v
             Direct: t v
-            foo: t
+            foo: te
         "#]],
     );
 }
@@ -628,9 +628,9 @@ mod m {
             m: t
 
             crate::m
-            alias1: m
-            alias2: m
-            alias3: m
+            alias1: mi
+            alias2: mi
+            alias3: mi
             not_found: _
         "#]],
     );
@@ -682,11 +682,11 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Bar: t v
-            Baz: t v
+            Bar: ti vi
+            Baz: ti vi
             Foo: t v
-            FooSelf: t v
-            foo: t
+            FooSelf: ti vi
+            foo: te
             m: t
 
             crate::m
@@ -725,7 +725,7 @@ pub struct bar;
 "#,
         expect![[r#"
             crate
-            bar: t v
+            bar: ti vi
         "#]],
     );
 }
@@ -1340,7 +1340,7 @@ pub mod prelude {
             crate
             Ok: t v
             bar: m
-            dep: t
+            dep: te
             foo: m
             ok: v
         "#]],
@@ -1370,13 +1370,13 @@ macro_rules! mk_foo {
 }
     "#,
         expect![[r#"
-        crate
-        a: t
-        lib: t
+            crate
+            a: t
+            lib: te
 
-        crate::a
-        Ok: t v
-    "#]],
+            crate::a
+            Ok: t v
+        "#]],
     );
 }
 
@@ -1427,8 +1427,8 @@ pub mod prelude {
         expect![[r#"
             crate
             Ok: t v
-            bar: m
-            foo: m
+            bar: mi
+            foo: mi
             ok: v
         "#]],
     );
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
index 81bc0ff91e3..1327d9aa62e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs
@@ -80,18 +80,18 @@ pub trait Iterator;
             prelude: t
 
             crate::iter
-            Iterator: t
+            Iterator: ti
             traits: t
 
             crate::iter::traits
-            Iterator: t
+            Iterator: ti
             iterator: t
 
             crate::iter::traits::iterator
             Iterator: t
 
             crate::prelude
-            Iterator: t
+            Iterator: ti
         "#]],
     );
 }
@@ -109,7 +109,7 @@ pub struct Bar;
 "#,
         expect![[r#"
             crate
-            Bar: t v
+            Bar: ti vi
             foo: t
 
             crate::foo
@@ -139,7 +139,7 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Bar: t v
+            Bar: ti vi
             r#async: t
 
             crate::r#async
@@ -176,8 +176,8 @@ pub struct Bar;
 "#,
         expect![[r#"
             crate
-            Bar: t v
-            Foo: t v
+            Bar: ti vi
+            Foo: ti vi
             r#async: t
 
             crate::r#async
@@ -207,7 +207,7 @@ pub struct Bar;
 "#,
         expect![[r#"
             crate
-            Bar: t v
+            Bar: ti vi
             foo: t
 
             crate::foo
@@ -236,7 +236,7 @@ pub struct Baz;
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
             bar: t
 
             crate::foo::bar
@@ -265,7 +265,7 @@ pub struct Baz;
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
             bar: t
 
             crate::foo::bar
@@ -292,7 +292,7 @@ use super::Baz;
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
         "#]],
     );
 }
@@ -626,7 +626,7 @@ pub struct Baz;
 "#,
         expect![[r#"
             crate
-            Baz: t v
+            Baz: ti vi
             foo: t
 
             crate::foo
@@ -660,7 +660,7 @@ pub struct Baz;
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
             bar: t
 
             crate::foo::bar
@@ -694,7 +694,7 @@ pub struct Baz;
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
             bar: t
 
             crate::foo::bar
@@ -728,7 +728,7 @@ pub struct Baz;
             foo: t
 
             crate::foo
-            Baz: t v
+            Baz: ti vi
             bar: t
 
             crate::foo::bar
@@ -868,7 +868,7 @@ pub mod hash { pub trait Hash {} }
 "#,
         expect![[r#"
             crate
-            Hash: t
+            Hash: ti
             core: t
 
             crate::core
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs
index 215e8952d90..271eb1c79b1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/primitives.rs
@@ -14,10 +14,10 @@ pub use i32 as int;
         expect![[r#"
             crate
             foo: t
-            int: t
+            int: ti
 
             crate::foo
-            int: t
+            int: ti
         "#]],
     );
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
index 2bc1f8e926e..14890364d0b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/per_ns.rs
@@ -3,13 +3,24 @@
 //!
 //! `PerNs` (per namespace) captures this.
 
-use crate::{item_scope::ItemInNs, visibility::Visibility, MacroId, ModuleDefId};
+use crate::{
+    item_scope::{ImportId, ImportOrExternCrate, ItemInNs},
+    visibility::Visibility,
+    MacroId, ModuleDefId,
+};
+
+#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
+pub enum Namespace {
+    Types,
+    Values,
+    Macros,
+}
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct PerNs {
-    pub types: Option<(ModuleDefId, Visibility)>,
-    pub values: Option<(ModuleDefId, Visibility)>,
-    pub macros: Option<(MacroId, Visibility)>,
+    pub types: Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
+    pub values: Option<(ModuleDefId, Visibility, Option<ImportId>)>,
+    pub macros: Option<(MacroId, Visibility, Option<ImportId>)>,
 }
 
 impl Default for PerNs {
@@ -23,20 +34,29 @@ impl PerNs {
         PerNs { types: None, values: None, macros: None }
     }
 
-    pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
-        PerNs { types: None, values: Some((t, v)), macros: None }
+    pub fn values(t: ModuleDefId, v: Visibility, i: Option<ImportId>) -> PerNs {
+        PerNs { types: None, values: Some((t, v, i)), macros: None }
     }
 
-    pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
-        PerNs { types: Some((t, v)), values: None, macros: None }
+    pub fn types(t: ModuleDefId, v: Visibility, i: Option<ImportOrExternCrate>) -> PerNs {
+        PerNs { types: Some((t, v, i)), values: None, macros: None }
     }
 
-    pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
-        PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
+    pub fn both(
+        types: ModuleDefId,
+        values: ModuleDefId,
+        v: Visibility,
+        i: Option<ImportOrExternCrate>,
+    ) -> PerNs {
+        PerNs {
+            types: Some((types, v, i)),
+            values: Some((values, v, i.and_then(ImportOrExternCrate::into_import))),
+            macros: None,
+        }
     }
 
-    pub fn macros(macro_: MacroId, v: Visibility) -> PerNs {
-        PerNs { types: None, values: None, macros: Some((macro_, v)) }
+    pub fn macros(macro_: MacroId, v: Visibility, i: Option<ImportId>) -> PerNs {
+        PerNs { types: None, values: None, macros: Some((macro_, v, i)) }
     }
 
     pub fn is_none(&self) -> bool {
@@ -51,7 +71,7 @@ impl PerNs {
         self.types.map(|it| it.0)
     }
 
-    pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
+    pub fn take_types_full(self) -> Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)> {
         self.types
     }
 
@@ -59,24 +79,32 @@ impl PerNs {
         self.values.map(|it| it.0)
     }
 
+    pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportId>)> {
+        self.values.map(|it| (it.0, it.2))
+    }
+
     pub fn take_macros(self) -> Option<MacroId> {
         self.macros.map(|it| it.0)
     }
 
+    pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportId>)> {
+        self.macros.map(|it| (it.0, it.2))
+    }
+
     pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
         let _p = profile::span("PerNs::filter_visibility");
         PerNs {
-            types: self.types.filter(|(_, v)| f(*v)),
-            values: self.values.filter(|(_, v)| f(*v)),
-            macros: self.macros.filter(|(_, v)| f(*v)),
+            types: self.types.filter(|&(_, v, _)| f(v)),
+            values: self.values.filter(|&(_, v, _)| f(v)),
+            macros: self.macros.filter(|&(_, v, _)| f(v)),
         }
     }
 
     pub fn with_visibility(self, vis: Visibility) -> PerNs {
         PerNs {
-            types: self.types.map(|(it, _)| (it, vis)),
-            values: self.values.map(|(it, _)| (it, vis)),
-            macros: self.macros.map(|(it, _)| (it, vis)),
+            types: self.types.map(|(it, _, c)| (it, vis, c)),
+            values: self.values.map(|(it, _, c)| (it, vis, c)),
+            macros: self.macros.map(|(it, _, import)| (it, vis, import)),
         }
     }
 
@@ -96,12 +124,20 @@ impl PerNs {
         }
     }
 
-    pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
+    pub fn iter_items(self) -> impl Iterator<Item = (ItemInNs, Option<ImportOrExternCrate>)> {
         let _p = profile::span("PerNs::iter_items");
         self.types
-            .map(|it| ItemInNs::Types(it.0))
+            .map(|it| (ItemInNs::Types(it.0), it.2))
             .into_iter()
-            .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter())
-            .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter())
+            .chain(
+                self.values
+                    .map(|it| (ItemInNs::Values(it.0), it.2.map(ImportOrExternCrate::Import)))
+                    .into_iter(),
+            )
+            .chain(
+                self.macros
+                    .map(|it| (ItemInNs::Macros(it.0), it.2.map(ImportOrExternCrate::Import)))
+                    .into_iter(),
+            )
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index b112c1070d4..2f9187009e2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -12,20 +12,21 @@ use triomphe::Arc;
 use crate::{
     body::scope::{ExprScopes, ScopeId},
     builtin_type::BuiltinType,
+    data::ExternCrateDeclData,
     db::DefDatabase,
     generics::{GenericParams, TypeOrConstParamData},
     hir::{BindingId, ExprId, LabelId},
-    item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
+    item_scope::{BuiltinShadowMode, ImportId, ImportOrExternCrate, BUILTIN_SCOPE},
     lang_item::LangItemTarget,
     nameres::{DefMap, MacroSubNs},
     path::{ModPath, Path, PathKind},
     per_ns::PerNs,
     visibility::{RawVisibility, Visibility},
-    AdtId, AssocItemId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId,
-    EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId,
-    HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId,
-    MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId,
-    TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
+    AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
+    ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
+    ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
+    ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
+    TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
 };
 
 #[derive(Debug, Clone)]
@@ -100,8 +101,8 @@ pub enum TypeNs {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum ResolveValueResult {
-    ValueNs(ValueNs),
-    Partial(TypeNs, usize),
+    ValueNs(ValueNs, Option<ImportId>),
+    Partial(TypeNs, usize, Option<ImportOrExternCrate>),
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -148,39 +149,11 @@ impl Resolver {
         self.resolve_module_path(db, path, BuiltinShadowMode::Module)
     }
 
-    // FIXME: This shouldn't exist
-    pub fn resolve_module_path_in_trait_assoc_items(
-        &self,
-        db: &dyn DefDatabase,
-        path: &ModPath,
-    ) -> Option<PerNs> {
-        let (item_map, module) = self.item_scope();
-        let (module_res, idx) =
-            item_map.resolve_path(db, module, path, BuiltinShadowMode::Module, None);
-        match module_res.take_types()? {
-            ModuleDefId::TraitId(it) => {
-                let idx = idx?;
-                let unresolved = &path.segments()[idx..];
-                let assoc = match unresolved {
-                    [it] => it,
-                    _ => return None,
-                };
-                let &(_, assoc) = db.trait_data(it).items.iter().find(|(n, _)| n == assoc)?;
-                Some(match assoc {
-                    AssocItemId::FunctionId(it) => PerNs::values(it.into(), Visibility::Public),
-                    AssocItemId::ConstId(it) => PerNs::values(it.into(), Visibility::Public),
-                    AssocItemId::TypeAliasId(it) => PerNs::types(it.into(), Visibility::Public),
-                })
-            }
-            _ => None,
-        }
-    }
-
     pub fn resolve_path_in_type_ns(
         &self,
         db: &dyn DefDatabase,
         path: &Path,
-    ) -> Option<(TypeNs, Option<usize>)> {
+    ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
         let path = match path {
             Path::Normal { mod_path, .. } => mod_path,
             Path::LangItem(l) => {
@@ -197,6 +170,7 @@ impl Resolver {
                         | LangItemTarget::Static(_) => return None,
                     },
                     None,
+                    None,
                 ))
             }
         };
@@ -213,17 +187,17 @@ impl Resolver {
                 Scope::ExprScope(_) => continue,
                 Scope::GenericParams { params, def } => {
                     if let Some(id) = params.find_type_by_name(first_name, *def) {
-                        return Some((TypeNs::GenericParam(id), remaining_idx()));
+                        return Some((TypeNs::GenericParam(id), remaining_idx(), None));
                     }
                 }
                 &Scope::ImplDefScope(impl_) => {
                     if first_name == &name![Self] {
-                        return Some((TypeNs::SelfType(impl_), remaining_idx()));
+                        return Some((TypeNs::SelfType(impl_), remaining_idx(), None));
                     }
                 }
                 &Scope::AdtScope(adt) => {
                     if first_name == &name![Self] {
-                        return Some((TypeNs::AdtSelfType(adt), remaining_idx()));
+                        return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None));
                     }
                 }
                 Scope::BlockScope(m) => {
@@ -236,12 +210,24 @@ impl Resolver {
         self.module_scope.resolve_path_in_type_ns(db, path)
     }
 
+    pub fn resolve_path_in_type_ns_fully_with_imports(
+        &self,
+        db: &dyn DefDatabase,
+        path: &Path,
+    ) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
+        let (res, unresolved, imp) = self.resolve_path_in_type_ns(db, path)?;
+        if unresolved.is_some() {
+            return None;
+        }
+        Some((res, imp))
+    }
+
     pub fn resolve_path_in_type_ns_fully(
         &self,
         db: &dyn DefDatabase,
         path: &Path,
     ) -> Option<TypeNs> {
-        let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
+        let (res, unresolved, _) = self.resolve_path_in_type_ns(db, path)?;
         if unresolved.is_some() {
             return None;
         }
@@ -263,7 +249,6 @@ impl Resolver {
             RawVisibility::Public => Some(Visibility::Public),
         }
     }
-
     pub fn resolve_path_in_value_ns(
         &self,
         db: &dyn DefDatabase,
@@ -272,17 +257,20 @@ impl Resolver {
         let path = match path {
             Path::Normal { mod_path, .. } => mod_path,
             Path::LangItem(l) => {
-                return Some(ResolveValueResult::ValueNs(match *l {
-                    LangItemTarget::Function(it) => ValueNs::FunctionId(it),
-                    LangItemTarget::Static(it) => ValueNs::StaticId(it),
-                    LangItemTarget::Struct(it) => ValueNs::StructId(it),
-                    LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
-                    LangItemTarget::Union(_)
-                    | LangItemTarget::ImplDef(_)
-                    | LangItemTarget::TypeAlias(_)
-                    | LangItemTarget::Trait(_)
-                    | LangItemTarget::EnumId(_) => return None,
-                }))
+                return Some(ResolveValueResult::ValueNs(
+                    match *l {
+                        LangItemTarget::Function(it) => ValueNs::FunctionId(it),
+                        LangItemTarget::Static(it) => ValueNs::StaticId(it),
+                        LangItemTarget::Struct(it) => ValueNs::StructId(it),
+                        LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
+                        LangItemTarget::Union(_)
+                        | LangItemTarget::ImplDef(_)
+                        | LangItemTarget::TypeAlias(_)
+                        | LangItemTarget::Trait(_)
+                        | LangItemTarget::EnumId(_) => return None,
+                    },
+                    None,
+                ))
             }
         };
         let n_segments = path.segments().len();
@@ -304,20 +292,24 @@ impl Resolver {
                             .find(|entry| entry.name() == first_name);
 
                         if let Some(e) = entry {
-                            return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(
-                                e.binding(),
-                            )));
+                            return Some(ResolveValueResult::ValueNs(
+                                ValueNs::LocalBinding(e.binding()),
+                                None,
+                            ));
                         }
                     }
                     Scope::GenericParams { params, def } => {
                         if let Some(id) = params.find_const_by_name(first_name, *def) {
                             let val = ValueNs::GenericParam(id);
-                            return Some(ResolveValueResult::ValueNs(val));
+                            return Some(ResolveValueResult::ValueNs(val, None));
                         }
                     }
                     &Scope::ImplDefScope(impl_) => {
                         if first_name == &name![Self] {
-                            return Some(ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_)));
+                            return Some(ResolveValueResult::ValueNs(
+                                ValueNs::ImplSelf(impl_),
+                                None,
+                            ));
                         }
                     }
                     // bare `Self` doesn't work in the value namespace in a struct/enum definition
@@ -336,18 +328,22 @@ impl Resolver {
                     Scope::GenericParams { params, def } => {
                         if let Some(id) = params.find_type_by_name(first_name, *def) {
                             let ty = TypeNs::GenericParam(id);
-                            return Some(ResolveValueResult::Partial(ty, 1));
+                            return Some(ResolveValueResult::Partial(ty, 1, None));
                         }
                     }
                     &Scope::ImplDefScope(impl_) => {
                         if first_name == &name![Self] {
-                            return Some(ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1));
+                            return Some(ResolveValueResult::Partial(
+                                TypeNs::SelfType(impl_),
+                                1,
+                                None,
+                            ));
                         }
                     }
                     Scope::AdtScope(adt) => {
                         if first_name == &name![Self] {
                             let ty = TypeNs::AdtSelfType(*adt);
-                            return Some(ResolveValueResult::Partial(ty, 1));
+                            return Some(ResolveValueResult::Partial(ty, 1, None));
                         }
                     }
                     Scope::BlockScope(m) => {
@@ -368,7 +364,7 @@ impl Resolver {
         // `use core::u16;`.
         if path.kind == PathKind::Plain && n_segments > 1 {
             if let Some(builtin) = BuiltinType::by_name(first_name) {
-                return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
+                return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None));
             }
         }
 
@@ -381,7 +377,7 @@ impl Resolver {
         path: &Path,
     ) -> Option<ValueNs> {
         match self.resolve_path_in_value_ns(db, path)? {
-            ResolveValueResult::ValueNs(it) => Some(it),
+            ResolveValueResult::ValueNs(it, _) => Some(it),
             ResolveValueResult::Partial(..) => None,
         }
     }
@@ -391,12 +387,12 @@ impl Resolver {
         db: &dyn DefDatabase,
         path: &ModPath,
         expected_macro_kind: Option<MacroSubNs>,
-    ) -> Option<MacroId> {
+    ) -> Option<(MacroId, Option<ImportId>)> {
         let (item_map, module) = self.item_scope();
         item_map
             .resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
             .0
-            .take_macros()
+            .take_macros_import()
     }
 
     /// Returns a set of names available in the current scope.
@@ -456,21 +452,22 @@ impl Resolver {
         def_map[module_id].scope.entries().for_each(|(name, def)| {
             res.add_per_ns(name, def);
         });
+
         def_map[module_id].scope.legacy_macros().for_each(|(name, macs)| {
             macs.iter().for_each(|&mac| {
                 res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)));
             })
         });
-        def_map.macro_use_prelude().for_each(|(name, def)| {
+        def_map.macro_use_prelude().for_each(|(name, (def, _extern_crate))| {
             res.add(name, ScopeDef::ModuleDef(def.into()));
         });
-        def_map.extern_prelude().for_each(|(name, def)| {
-            res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
+        def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
+            res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into())));
         });
         BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
             res.add_per_ns(name, def);
         });
-        if let Some(prelude) = def_map.prelude() {
+        if let Some((prelude, _use)) = def_map.prelude() {
             let prelude_def_map = prelude.def_map(db);
             for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
                 res.add_per_ns(name, def)
@@ -479,6 +476,23 @@ impl Resolver {
         res.map
     }
 
+    pub fn extern_crate_decls_in_scope<'a>(
+        &'a self,
+        db: &'a dyn DefDatabase,
+    ) -> impl Iterator<Item = Name> + 'a {
+        self.module_scope.def_map[self.module_scope.module_id]
+            .scope
+            .extern_crate_decls()
+            .map(|id| ExternCrateDeclData::extern_crate_decl_data_query(db, id).name.clone())
+    }
+
+    pub fn extern_crates_in_scope<'a>(&'a self) -> impl Iterator<Item = (Name, ModuleId)> + 'a {
+        self.module_scope
+            .def_map
+            .extern_prelude()
+            .map(|(name, module_id)| (name.clone(), module_id.0.into()))
+    }
+
     pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
         // FIXME(trait_alias): Trait alias brings aliased traits in scope! Note that supertraits of
         // aliased traits are NOT brought in scope (unless also aliased).
@@ -501,7 +515,7 @@ impl Resolver {
         }
 
         // Fill in the prelude traits
-        if let Some(prelude) = self.module_scope.def_map.prelude() {
+        if let Some((prelude, _use)) = self.module_scope.def_map.prelude() {
             let prelude_def_map = prelude.def_map(db);
             traits.extend(prelude_def_map[prelude.local_id].scope.traits());
         }
@@ -804,11 +818,12 @@ impl ModuleItemMap {
             self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
         match idx {
             None => {
-                let value = to_value_ns(module_def)?;
-                Some(ResolveValueResult::ValueNs(value))
+                let (value, import) = to_value_ns(module_def)?;
+                Some(ResolveValueResult::ValueNs(value, import))
             }
             Some(idx) => {
-                let ty = match module_def.take_types()? {
+                let (def, _, import) = module_def.take_types_full()?;
+                let ty = match def {
                     ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
                     ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
                     ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
@@ -822,7 +837,7 @@ impl ModuleItemMap {
                     | ModuleDefId::MacroId(_)
                     | ModuleDefId::StaticId(_) => return None,
                 };
-                Some(ResolveValueResult::Partial(ty, idx))
+                Some(ResolveValueResult::Partial(ty, idx, import))
             }
         }
     }
@@ -831,16 +846,17 @@ impl ModuleItemMap {
         &self,
         db: &dyn DefDatabase,
         path: &ModPath,
-    ) -> Option<(TypeNs, Option<usize>)> {
+    ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
         let (module_def, idx) =
             self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
-        let res = to_type_ns(module_def)?;
-        Some((res, idx))
+        let (res, import) = to_type_ns(module_def)?;
+        Some((res, idx, import))
     }
 }
 
-fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
-    let res = match per_ns.take_values()? {
+fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
+    let (def, import) = per_ns.take_values_import()?;
+    let res = match def {
         ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
         ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
         ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
@@ -855,11 +871,12 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
         | ModuleDefId::MacroId(_)
         | ModuleDefId::ModuleId(_) => return None,
     };
-    Some(res)
+    Some((res, import))
 }
 
-fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
-    let res = match per_ns.take_types()? {
+fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
+    let (def, _, import) = per_ns.take_types_full()?;
+    let res = match def {
         ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
         ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
 
@@ -875,7 +892,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
         | ModuleDefId::StaticId(_)
         | ModuleDefId::ModuleId(_) => return None,
     };
-    Some(res)
+    Some((res, import))
 }
 
 type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
@@ -892,13 +909,13 @@ impl ScopeNames {
         }
     }
     fn add_per_ns(&mut self, name: &Name, def: PerNs) {
-        if let &Some((ty, _)) = &def.types {
+        if let &Some((ty, _, _)) = &def.types {
             self.add(name, ScopeDef::ModuleDef(ty))
         }
-        if let &Some((def, _)) = &def.values {
+        if let &Some((def, _, _)) = &def.values {
             self.add(name, ScopeDef::ModuleDef(def))
         }
-        if let &Some((mac, _)) = &def.macros {
+        if let &Some((mac, _, _)) = &def.macros {
             self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)))
         }
         if def.is_none() {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
index 6047f770d4d..3770103cda5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
@@ -5,8 +5,8 @@ use la_arena::ArenaMap;
 use syntax::ast;
 
 use crate::{
-    db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc, Macro2Loc, MacroRulesLoc,
-    ProcMacroLoc,
+    db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc, Lookup, Macro2Loc,
+    MacroRulesLoc, ProcMacroLoc, UseId,
 };
 
 pub trait HasSource {
@@ -83,3 +83,18 @@ pub trait HasChildSource<ChildId> {
     type Value;
     fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>;
 }
+
+impl HasChildSource<la_arena::Idx<ast::UseTree>> for UseId {
+    type Value = ast::UseTree;
+    fn child_source(
+        &self,
+        db: &dyn DefDatabase,
+    ) -> InFile<ArenaMap<la_arena::Idx<ast::UseTree>, Self::Value>> {
+        let loc = &self.lookup(db);
+        let use_ = &loc.id.item_tree(db)[loc.id.value];
+        InFile::new(
+            loc.id.file_id(),
+            use_.use_tree_source_map(db, loc.id.file_id()).into_iter().collect(),
+        )
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
index 4c918e55b92..0ec2422b30c 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
@@ -342,14 +342,7 @@ fn inner_attributes(
             ast::Impl(it) => it.assoc_item_list()?.syntax().clone(),
             ast::Module(it) => it.item_list()?.syntax().clone(),
             ast::BlockExpr(it) => {
-                use syntax::SyntaxKind::{BLOCK_EXPR , EXPR_STMT};
-                // Block expressions accept outer and inner attributes, but only when they are the outer
-                // expression of an expression statement or the final expression of another block expression.
-                let may_carry_attributes = matches!(
-                    it.syntax().parent().map(|it| it.kind()),
-                     Some(BLOCK_EXPR | EXPR_STMT)
-                );
-                if !may_carry_attributes {
+                if !it.may_carry_attributes() {
                     return None
                 }
                 syntax.clone()
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index 1f1e20f49e3..4be55126b86 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -37,7 +37,7 @@ use either::Either;
 use syntax::{
     algo::{self, skip_trivia_token},
     ast::{self, AstNode, HasDocComments},
-    AstPtr, Direction, SyntaxNode, SyntaxNodePtr, SyntaxToken,
+    AstPtr, Direction, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextSize,
 };
 
 use crate::{
@@ -544,7 +544,7 @@ impl MacroCallKind {
         };
 
         let range = match kind {
-            MacroCallKind::FnLike { ast_id, .. } => ast_id.to_node(db).syntax().text_range(),
+            MacroCallKind::FnLike { ast_id, .. } => ast_id.to_ptr(db).text_range(),
             MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
                 // FIXME: should be the range of the macro name, not the whole derive
                 // FIXME: handle `cfg_attr`
@@ -642,6 +642,8 @@ impl ExpansionInfo {
         db: &dyn db::ExpandDatabase,
         item: Option<ast::Item>,
         token: InFile<&SyntaxToken>,
+        // FIXME: use this for range mapping, so that we can resolve inline format args
+        _relative_token_offset: Option<TextSize>,
     ) -> Option<impl Iterator<Item = InFile<SyntaxToken>> + '_> {
         assert_eq!(token.file_id, self.arg.file_id);
         let token_id_in_attr_input = if let Some(item) = item {
@@ -840,9 +842,6 @@ impl<N: AstIdNode> AstId<N> {
 pub type ErasedAstId = InFile<ErasedFileAstId>;
 
 impl ErasedAstId {
-    pub fn to_node(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
-        self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id))
-    }
     pub fn to_ptr(&self, db: &dyn db::ExpandDatabase) -> SyntaxNodePtr {
         db.ast_id_map(self.file_id).get_raw(self.value)
     }
@@ -1054,16 +1053,6 @@ impl InFile<SyntaxToken> {
             }
         }
     }
-
-    pub fn ancestors_with_macros(
-        self,
-        db: &dyn db::ExpandDatabase,
-    ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ {
-        self.value.parent().into_iter().flat_map({
-            let file_id = self.file_id;
-            move |parent| InFile::new(file_id, &parent).ancestors_with_macros(db)
-        })
-    }
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
index eec57ba3f80..967e028bfb1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/builder.rs
@@ -17,7 +17,8 @@ use smallvec::SmallVec;
 use crate::{
     consteval::unknown_const_as_generic, db::HirDatabase, infer::unify::InferenceTable, primitive,
     to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, BoundVar, CallableSig,
-    GenericArg, Interner, ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt, TyKind,
+    GenericArg, GenericArgData, Interner, ProjectionTy, Substitution, TraitRef, Ty, TyDefId, TyExt,
+    TyKind,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -79,9 +80,9 @@ impl<D> TyBuilder<D> {
         let expected_kind = &self.param_kinds[self.vec.len()];
 
         let arg_kind = match arg.data(Interner) {
-            chalk_ir::GenericArgData::Ty(_) => ParamKind::Type,
-            chalk_ir::GenericArgData::Lifetime(_) => panic!("Got lifetime in TyBuilder::push"),
-            chalk_ir::GenericArgData::Const(c) => {
+            GenericArgData::Ty(_) => ParamKind::Type,
+            GenericArgData::Lifetime(_) => panic!("Got lifetime in TyBuilder::push"),
+            GenericArgData::Const(c) => {
                 let c = c.data(Interner);
                 ParamKind::Const(c.ty.clone())
             }
@@ -139,8 +140,8 @@ impl<D> TyBuilder<D> {
 
     fn assert_match_kind(&self, a: &chalk_ir::GenericArg<Interner>, e: &ParamKind) {
         match (a.data(Interner), e) {
-            (chalk_ir::GenericArgData::Ty(_), ParamKind::Type)
-            | (chalk_ir::GenericArgData::Const(_), ParamKind::Const(_)) => (),
+            (GenericArgData::Ty(_), ParamKind::Type)
+            | (GenericArgData::Const(_), ParamKind::Const(_)) => (),
             _ => panic!("Mismatched kinds: {a:?}, {:?}, {:?}", self.vec, self.param_kinds),
         }
     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
index 1c0f7b08da8..0348680e5da 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -1,7 +1,7 @@
 //! Constant evaluation details
 
 use base_db::CrateId;
-use chalk_ir::{BoundVar, DebruijnIndex, GenericArgData};
+use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex};
 use hir_def::{
     hir::Expr,
     path::Path,
@@ -120,7 +120,7 @@ pub fn unknown_const(ty: Ty) -> Const {
 }
 
 pub fn unknown_const_as_generic(ty: Ty) -> GenericArg {
-    GenericArgData::Const(unknown_const(ty)).intern(Interner)
+    unknown_const(ty).cast(Interner)
 }
 
 /// Interns a constant scalar with the given type
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
index 666955fa1c3..7ad3659a4f6 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
@@ -1203,6 +1203,27 @@ fn destructing_assignment() {
         "#,
         5,
     );
+    check_number(
+        r#"
+    const GOAL: u8 = {
+        let (mut a, mut b) = (2, 5);
+        (a, b) = (b, a);
+        a * 10 + b
+    };
+        "#,
+        52,
+    );
+    check_number(
+        r#"
+    struct Point { x: i32, y: i32 }
+    const GOAL: i32 = {
+        let mut p = Point { x: 5, y: 6 };
+        (p.x, _) = (p.y, p.x);
+        p.x * 10 + p.y
+    };
+        "#,
+        66,
+    );
 }
 
 #[test]
@@ -1433,6 +1454,30 @@ fn from_trait() {
 }
 
 #[test]
+fn closure_clone() {
+    check_number(
+        r#"
+//- minicore: clone, fn
+struct S(u8);
+
+impl Clone for S(u8) {
+    fn clone(&self) -> S {
+        S(self.0 + 5)
+    }
+}
+
+const GOAL: u8 = {
+    let s = S(3);
+    let cl = move || s;
+    let cl = cl.clone();
+    cl().0
+}
+    "#,
+        8,
+    );
+}
+
+#[test]
 fn builtin_derive_macro() {
     check_number(
         r#"
@@ -2396,14 +2441,14 @@ fn const_loop() {
 fn const_transfer_memory() {
     check_number(
         r#"
-    //- minicore: slice, index, coerce_unsized
+    //- minicore: slice, index, coerce_unsized, option
     const A1: &i32 = &1;
     const A2: &i32 = &10;
     const A3: [&i32; 3] = [&1, &2, &100];
-    const A4: (i32, &i32) = (1, &1000);
-    const GOAL: i32 = *A1 + *A2 + *A3[2] + *A4.1;
+    const A4: (i32, &i32, Option<&i32>) = (1, &1000, Some(&10000));
+    const GOAL: i32 = *A1 + *A2 + *A3[2] + *A4.1 + *A4.2.unwrap_or(&5);
     "#,
-        1111,
+        11111,
     );
 }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 9f9a56ffab0..cbca0e801d4 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -75,7 +75,7 @@ fn walk_unsafe(
         Expr::Path(path) => {
             let resolver = resolver_for_expr(db.upcast(), def, current);
             let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
-            if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial {
+            if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
                 if db.static_data(id).mutable {
                     unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 1b4ee4613d6..f6d6b00d740 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -1809,6 +1809,25 @@ impl HirDisplay for Path {
             }
         }
 
+        // Convert trait's `Self` bound back to the surface syntax. Note there is no associated
+        // trait, so there can only be one path segment that `has_self_type`. The `Self` type
+        // itself can contain further qualified path through, which will be handled by recursive
+        // `hir_fmt`s.
+        //
+        // `trait_mod::Trait<Self = type_mod::Type, Args>::Assoc`
+        // =>
+        // `<type_mod::Type as trait_mod::Trait<Args>>::Assoc`
+        let trait_self_ty = self.segments().iter().find_map(|seg| {
+            let generic_args = seg.args_and_bindings?;
+            generic_args.has_self_type.then(|| &generic_args.args[0])
+        });
+        if let Some(ty) = trait_self_ty {
+            write!(f, "<")?;
+            ty.hir_fmt(f)?;
+            write!(f, " as ")?;
+            // Now format the path of the trait...
+        }
+
         for (seg_idx, segment) in self.segments().iter().enumerate() {
             if !matches!(self.kind(), PathKind::Plain) || seg_idx > 0 {
                 write!(f, "::")?;
@@ -1840,15 +1859,12 @@ impl HirDisplay for Path {
                     return Ok(());
                 }
 
-                write!(f, "<")?;
                 let mut first = true;
-                for arg in generic_args.args.iter() {
+                // Skip the `Self` bound if exists. It's handled outside the loop.
+                for arg in &generic_args.args[generic_args.has_self_type as usize..] {
                     if first {
                         first = false;
-                        if generic_args.has_self_type {
-                            // FIXME: Convert to `<Ty as Trait>` form.
-                            write!(f, "Self = ")?;
-                        }
+                        write!(f, "<")?;
                     } else {
                         write!(f, ", ")?;
                     }
@@ -1857,6 +1873,7 @@ impl HirDisplay for Path {
                 for binding in generic_args.bindings.iter() {
                     if first {
                         first = false;
+                        write!(f, "<")?;
                     } else {
                         write!(f, ", ")?;
                     }
@@ -1872,9 +1889,20 @@ impl HirDisplay for Path {
                         }
                     }
                 }
-                write!(f, ">")?;
+
+                // There may be no generic arguments to print, in case of a trait having only a
+                // single `Self` bound which is converted to `<Ty as Trait>::Assoc`.
+                if !first {
+                    write!(f, ">")?;
+                }
+
+                // Current position: `<Ty as Trait<Args>|`
+                if generic_args.has_self_type {
+                    write!(f, ">")?;
+                }
             }
         }
+
         Ok(())
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index b4915dbf0f9..0fb4934444b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -1017,7 +1017,7 @@ impl<'a> InferenceContext<'a> {
         let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
         let (resolution, unresolved) = if value_ns {
             match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
-                Some(ResolveValueResult::ValueNs(value)) => match value {
+                Some(ResolveValueResult::ValueNs(value, _)) => match value {
                     ValueNs::EnumVariantId(var) => {
                         let substs = ctx.substs_from_path(path, var.into(), true);
                         let ty = self.db.ty(var.parent.into());
@@ -1033,12 +1033,14 @@ impl<'a> InferenceContext<'a> {
                     ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
                     _ => return (self.err_ty(), None),
                 },
-                Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
+                Some(ResolveValueResult::Partial(typens, unresolved, _)) => {
+                    (typens, Some(unresolved))
+                }
                 None => return (self.err_ty(), None),
             }
         } else {
             match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
-                Some(it) => it,
+                Some((it, idx, _)) => (it, idx),
                 None => return (self.err_ty(), None),
             }
         };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
index 1781f6c58f1..23efe616f4f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
@@ -322,7 +322,7 @@ impl InferenceContext<'_> {
             Expr::Path(p) => {
                 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
                 if let Some(r) = resolver.resolve_path_in_value_ns(self.db.upcast(), p) {
-                    if let ResolveValueResult::ValueNs(v) = r {
+                    if let ResolveValueResult::ValueNs(v, _) = r {
                         if let ValueNs::LocalBinding(b) = v {
                             return Some(HirPlace { local: b, projections: vec![] });
                         }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index 8cbdae62526..8b352141084 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -5,9 +5,7 @@ use std::{
     mem,
 };
 
-use chalk_ir::{
-    cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyVariableKind,
-};
+use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex, Mutability, TyVariableKind};
 use hir_def::{
     generics::TypeOrConstParamData,
     hir::{
@@ -750,7 +748,7 @@ impl InferenceContext<'_> {
                     self.resolve_associated_type_with_params(
                         self_ty,
                         self.resolve_ops_index_output(),
-                        &[GenericArgData::Ty(index_ty).intern(Interner)],
+                        &[index_ty.cast(Interner)],
                     )
                 } else {
                     self.err_ty()
@@ -1721,16 +1719,13 @@ impl InferenceContext<'_> {
         for (id, data) in def_generics.iter().skip(substs.len()) {
             match data {
                 TypeOrConstParamData::TypeParamData(_) => {
-                    substs.push(GenericArgData::Ty(self.table.new_type_var()).intern(Interner))
-                }
-                TypeOrConstParamData::ConstParamData(_) => {
-                    substs.push(
-                        GenericArgData::Const(self.table.new_const_var(
-                            self.db.const_param_ty(ConstParamId::from_unchecked(id)),
-                        ))
-                        .intern(Interner),
-                    )
+                    substs.push(self.table.new_type_var().cast(Interner))
                 }
+                TypeOrConstParamData::ConstParamData(_) => substs.push(
+                    self.table
+                        .new_const_var(self.db.const_param_ty(ConstParamId::from_unchecked(id)))
+                        .cast(Interner),
+                ),
             }
         }
         assert_eq!(substs.len(), total_len);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
index 79d9e21e797..2a51c84db3a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
@@ -61,8 +61,8 @@ impl InferenceContext<'_> {
                 self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?;
 
             match value_or_partial {
-                ResolveValueResult::ValueNs(it) => (it, None),
-                ResolveValueResult::Partial(def, remaining_index) => self
+                ResolveValueResult::ValueNs(it, _) => (it, None),
+                ResolveValueResult::Partial(def, remaining_index, _) => self
                     .resolve_assoc_item(def, path, remaining_index, id)
                     .map(|(it, substs)| (it, Some(substs)))?,
             }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
index 0fb71135b4d..0a68a9f3b58 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -10,7 +10,6 @@ use chalk_solve::infer::ParameterEnaVariableExt;
 use either::Either;
 use ena::unify::UnifyKey;
 use hir_expand::name;
-use stdx::never;
 use triomphe::Arc;
 
 use super::{InferOk, InferResult, InferenceContext, TypeError};
@@ -92,15 +91,10 @@ pub(crate) fn unify(
     let vars = Substitution::from_iter(
         Interner,
         tys.binders.iter(Interner).map(|it| match &it.kind {
-            chalk_ir::VariableKind::Ty(_) => {
-                GenericArgData::Ty(table.new_type_var()).intern(Interner)
-            }
-            chalk_ir::VariableKind::Lifetime => {
-                GenericArgData::Ty(table.new_type_var()).intern(Interner)
-            } // FIXME: maybe wrong?
-            chalk_ir::VariableKind::Const(ty) => {
-                GenericArgData::Const(table.new_const_var(ty.clone())).intern(Interner)
-            }
+            chalk_ir::VariableKind::Ty(_) => table.new_type_var().cast(Interner),
+            // FIXME: maybe wrong?
+            chalk_ir::VariableKind::Lifetime => table.new_type_var().cast(Interner),
+            chalk_ir::VariableKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
         }),
     );
     let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
@@ -111,10 +105,10 @@ pub(crate) fn unify(
     // default any type vars that weren't unified back to their original bound vars
     // (kind of hacky)
     let find_var = |iv| {
-        vars.iter(Interner).position(|v| match v.interned() {
-            chalk_ir::GenericArgData::Ty(ty) => ty.inference_var(Interner),
-            chalk_ir::GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
-            chalk_ir::GenericArgData::Const(c) => c.inference_var(Interner),
+        vars.iter(Interner).position(|v| match v.data(Interner) {
+            GenericArgData::Ty(ty) => ty.inference_var(Interner),
+            GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
+            GenericArgData::Const(c) => c.inference_var(Interner),
         } == Some(iv))
     };
     let fallback = |iv, kind, default, binder| match kind {
@@ -149,6 +143,9 @@ pub(crate) struct InferenceTable<'a> {
     var_unification_table: ChalkInferenceTable,
     type_variable_table: Vec<TypeVariableFlags>,
     pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
+    /// Double buffer used in [`Self::resolve_obligations_as_possible`] to cut down on
+    /// temporary allocations.
+    resolve_obligations_buffer: Vec<Canonicalized<InEnvironment<Goal>>>,
 }
 
 pub(crate) struct InferenceTableSnapshot {
@@ -165,6 +162,7 @@ impl<'a> InferenceTable<'a> {
             var_unification_table: ChalkInferenceTable::new(),
             type_variable_table: Vec::new(),
             pending_obligations: Vec::new(),
+            resolve_obligations_buffer: Vec::new(),
         }
     }
 
@@ -516,10 +514,10 @@ impl<'a> InferenceTable<'a> {
     pub(crate) fn resolve_obligations_as_possible(&mut self) {
         let _span = profile::span("resolve_obligations_as_possible");
         let mut changed = true;
-        let mut obligations = Vec::new();
-        while changed {
-            changed = false;
+        let mut obligations = mem::take(&mut self.resolve_obligations_buffer);
+        while mem::take(&mut changed) {
             mem::swap(&mut self.pending_obligations, &mut obligations);
+
             for canonicalized in obligations.drain(..) {
                 if !self.check_changed(&canonicalized) {
                     self.pending_obligations.push(canonicalized);
@@ -534,6 +532,8 @@ impl<'a> InferenceTable<'a> {
                 self.register_obligation_in_env(uncanonical);
             }
         }
+        self.resolve_obligations_buffer = obligations;
+        self.resolve_obligations_buffer.clear();
     }
 
     pub(crate) fn fudge_inference<T: TypeFoldable<Interner>>(
@@ -611,9 +611,9 @@ impl<'a> InferenceTable<'a> {
     fn check_changed(&mut self, canonicalized: &Canonicalized<InEnvironment<Goal>>) -> bool {
         canonicalized.free_vars.iter().any(|var| {
             let iv = match var.data(Interner) {
-                chalk_ir::GenericArgData::Ty(ty) => ty.inference_var(Interner),
-                chalk_ir::GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
-                chalk_ir::GenericArgData::Const(c) => c.inference_var(Interner),
+                GenericArgData::Ty(ty) => ty.inference_var(Interner),
+                GenericArgData::Lifetime(lt) => lt.inference_var(Interner),
+                GenericArgData::Const(c) => c.inference_var(Interner),
             }
             .expect("free var is not inference var");
             if self.var_unification_table.probe_var(iv).is_some() {
@@ -690,14 +690,10 @@ impl<'a> InferenceTable<'a> {
             .fill(|it| {
                 let arg = match it {
                     ParamKind::Type => self.new_type_var(),
-                    ParamKind::Const(ty) => {
-                        never!("Tuple with const parameter");
-                        return GenericArgData::Const(self.new_const_var(ty.clone()))
-                            .intern(Interner);
-                    }
+                    ParamKind::Const(_) => unreachable!("Tuple with const parameter"),
                 };
                 arg_tys.push(arg.clone());
-                GenericArgData::Ty(arg).intern(Interner)
+                arg.cast(Interner)
             })
             .build();
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index b3ca2a22258..405bb001b5d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -52,12 +52,14 @@ use hir_expand::name;
 use la_arena::{Arena, Idx};
 use mir::{MirEvalError, VTableMap};
 use rustc_hash::FxHashSet;
+use syntax::ast::{make, ConstArg};
 use traits::FnTrait;
 use triomphe::Arc;
 use utils::Generics;
 
 use crate::{
-    consteval::unknown_const, db::HirDatabase, infer::unify::InferenceTable, utils::generics,
+    consteval::unknown_const, db::HirDatabase, display::HirDisplay, infer::unify::InferenceTable,
+    utils::generics,
 };
 
 pub use autoderef::autoderef;
@@ -719,3 +721,16 @@ where
     value.visit_with(&mut collector, DebruijnIndex::INNERMOST);
     collector.placeholders.into_iter().collect()
 }
+
+pub fn known_const_to_ast(konst: &Const, db: &dyn HirDatabase) -> Option<ConstArg> {
+    if let ConstValue::Concrete(c) = &konst.interned().value {
+        match c.interned {
+            ConstScalar::UnevaluatedConst(GeneralConstId::InTypeConstId(cid), _) => {
+                return Some(cid.source(db.upcast()));
+            }
+            ConstScalar::Unknown => return None,
+            _ => (),
+        }
+    }
+    Some(make::expr_const_value(konst.display(db).to_string().as_str()))
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 2837f400bce..9a61f153599 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -58,10 +58,9 @@ use crate::{
         InTypeConstIdMetadata,
     },
     AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
-    FnPointer, FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig,
-    ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait,
-    ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder,
-    TyKind, WhereClause,
+    FnPointer, FnSig, FnSubst, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
+    QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
+    Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
 };
 
 #[derive(Debug)]
@@ -213,6 +212,19 @@ impl<'a> TyLoweringContext<'a> {
         self.lower_ty_ext(type_ref).0
     }
 
+    pub fn lower_const(&self, const_ref: &ConstRef, const_type: Ty) -> Const {
+        const_or_path_to_chalk(
+            self.db,
+            self.resolver,
+            self.owner,
+            const_type,
+            const_ref,
+            self.type_param_mode,
+            || self.generics(),
+            self.in_binders,
+        )
+    }
+
     fn generics(&self) -> Generics {
         generics(
             self.db.upcast(),
@@ -242,17 +254,7 @@ impl<'a> TyLoweringContext<'a> {
             }
             TypeRef::Array(inner, len) => {
                 let inner_ty = self.lower_ty(inner);
-                let const_len = const_or_path_to_chalk(
-                    self.db,
-                    self.resolver,
-                    self.owner,
-                    TyBuilder::usize(),
-                    len,
-                    self.type_param_mode,
-                    || self.generics(),
-                    self.in_binders,
-                );
-
+                let const_len = self.lower_const(len, TyBuilder::usize());
                 TyKind::Array(inner_ty, const_len).intern(Interner)
             }
             TypeRef::Slice(inner) => {
@@ -391,11 +393,9 @@ impl<'a> TyLoweringContext<'a> {
                 let ty = {
                     let macro_call = macro_call.to_node(self.db.upcast());
                     let resolver = |path| {
-                        self.resolver.resolve_path_as_macro(
-                            self.db.upcast(),
-                            &path,
-                            Some(MacroSubNs::Bang),
-                        )
+                        self.resolver
+                            .resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
+                            .map(|(it, _)| it)
                     };
                     match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
                     {
@@ -447,7 +447,7 @@ impl<'a> TyLoweringContext<'a> {
             return None;
         }
         let resolution = match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
-            Some((it, None)) => it,
+            Some((it, None, _)) => it,
             _ => return None,
         };
         match resolution {
@@ -627,7 +627,7 @@ impl<'a> TyLoweringContext<'a> {
             return self.lower_ty_relative_path(ty, res, path.segments());
         }
 
-        let (resolution, remaining_index) =
+        let (resolution, remaining_index, _) =
             match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
                 Some(it) => it,
                 None => return (TyKind::Error.intern(Interner), None),
@@ -847,18 +847,7 @@ impl<'a> TyLoweringContext<'a> {
                         arg,
                         &mut (),
                         |_, type_ref| self.lower_ty(type_ref),
-                        |_, c, ty| {
-                            const_or_path_to_chalk(
-                                self.db,
-                                self.resolver,
-                                self.owner,
-                                ty,
-                                c,
-                                self.type_param_mode,
-                                || self.generics(),
-                                self.in_binders,
-                            )
-                        },
+                        |_, const_ref, ty| self.lower_const(const_ref, ty),
                     ) {
                         had_explicit_args = true;
                         substs.push(x);
@@ -1604,24 +1593,35 @@ pub(crate) fn generic_defaults_query(
             .iter()
             .enumerate()
             .map(|(idx, (id, p))| {
-                let p = match p {
-                    TypeOrConstParamData::TypeParamData(p) => p,
-                    TypeOrConstParamData::ConstParamData(_) => {
-                        // FIXME: implement const generic defaults
-                        let val = unknown_const_as_generic(
-                            db.const_param_ty(ConstParamId::from_unchecked(id)),
+                match p {
+                    TypeOrConstParamData::TypeParamData(p) => {
+                        let mut ty = p
+                            .default
+                            .as_ref()
+                            .map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
+                        // Each default can only refer to previous parameters.
+                        // Type variable default referring to parameter coming
+                        // after it is forbidden (FIXME: report diagnostic)
+                        ty = fallback_bound_vars(ty, idx, parent_start_idx);
+                        crate::make_binders(db, &generic_params, ty.cast(Interner))
+                    }
+                    TypeOrConstParamData::ConstParamData(p) => {
+                        let mut val = p.default.as_ref().map_or_else(
+                            || {
+                                unknown_const_as_generic(
+                                    db.const_param_ty(ConstParamId::from_unchecked(id)),
+                                )
+                            },
+                            |c| {
+                                let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
+                                c.cast(Interner)
+                            },
                         );
-                        return make_binders(db, &generic_params, val);
+                        // Each default can only refer to previous parameters, see above.
+                        val = fallback_bound_vars(val, idx, parent_start_idx);
+                        make_binders(db, &generic_params, val)
                     }
-                };
-                let mut ty =
-                    p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
-
-                // Each default can only refer to previous parameters.
-                // Type variable default referring to parameter coming
-                // after it is forbidden (FIXME: report diagnostic)
-                ty = fallback_bound_vars(ty, idx, parent_start_idx);
-                crate::make_binders(db, &generic_params, ty.cast(Interner))
+                }
             })
             // FIXME: use `Arc::from_iter` when it becomes available
             .collect::<Vec<_>>(),
@@ -1643,9 +1643,7 @@ pub(crate) fn generic_defaults_recover(
             .iter_id()
             .map(|id| {
                 let val = match id {
-                    Either::Left(_) => {
-                        GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
-                    }
+                    Either::Left(_) => TyKind::Error.intern(Interner).cast(Interner),
                     Either::Right(id) => unknown_const_as_generic(db.const_param_ty(id)),
                 };
                 crate::make_binders(db, &generic_params, val)
@@ -1991,16 +1989,9 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
         }
     };
     Some(match (arg, kind) {
-        (GenericArg::Type(type_ref), ParamKind::Type) => {
-            let ty = for_type(this, type_ref);
-            GenericArgData::Ty(ty).intern(Interner)
-        }
-        (GenericArg::Const(c), ParamKind::Const(c_ty)) => {
-            GenericArgData::Const(for_const(this, c, c_ty)).intern(Interner)
-        }
-        (GenericArg::Const(_), ParamKind::Type) => {
-            GenericArgData::Ty(TyKind::Error.intern(Interner)).intern(Interner)
-        }
+        (GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, type_ref).cast(Interner),
+        (GenericArg::Const(c), ParamKind::Const(c_ty)) => for_const(this, c, c_ty).cast(Interner),
+        (GenericArg::Const(_), ParamKind::Type) => TyKind::Error.intern(Interner).cast(Interner),
         (GenericArg::Type(t), ParamKind::Const(c_ty)) => {
             // We want to recover simple idents, which parser detects them
             // as types. Maybe here is not the best place to do it, but
@@ -2010,9 +2001,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
                 if p.kind == PathKind::Plain {
                     if let [n] = p.segments() {
                         let c = ConstRef::Path(n.clone());
-                        return Some(
-                            GenericArgData::Const(for_const(this, &c, c_ty)).intern(Interner),
-                        );
+                        return Some(for_const(this, &c, c_ty).cast(Interner));
                     }
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index 9e30eed56f3..3944feb128c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -10,7 +10,7 @@ use std::{
 };
 
 use base_db::{CrateId, FileId};
-use chalk_ir::Mutability;
+use chalk_ir::{cast::Cast, Mutability};
 use either::Either;
 use hir_def::{
     builtin_type::BuiltinType,
@@ -40,8 +40,8 @@ use crate::{
     name, static_lifetime,
     traits::FnTrait,
     utils::{detect_variant_from_bytes, ClosureSubst},
-    CallableDefId, ClosureId, Const, ConstScalar, FnDefId, GenericArgData, Interner, MemoryMap,
-    Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
+    CallableDefId, ClosureId, Const, ConstScalar, FnDefId, Interner, MemoryMap, Substitution,
+    TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
 };
 
 use super::{
@@ -2007,7 +2007,28 @@ impl Evaluator<'_> {
                     }
                 }
                 AdtId::UnionId(_) => (),
-                AdtId::EnumId(_) => (),
+                AdtId::EnumId(e) => {
+                    if let Some((variant, layout)) = detect_variant_from_bytes(
+                        &layout,
+                        self.db,
+                        self.trait_env.clone(),
+                        self.read_memory(addr, layout.size.bytes_usize())?,
+                        e,
+                    ) {
+                        let ev = EnumVariantId { parent: e, local_id: variant };
+                        for (i, (_, ty)) in self.db.field_types(ev.into()).iter().enumerate() {
+                            let offset = layout.fields.offset(i).bytes_usize();
+                            let ty = ty.clone().substitute(Interner, subst);
+                            self.patch_addresses(
+                                patch_map,
+                                old_vtable,
+                                addr.offset(offset),
+                                &ty,
+                                locals,
+                            )?;
+                        }
+                    }
+                }
             },
             TyKind::Tuple(_, subst) => {
                 for (id, ty) in subst.iter(Interner).enumerate() {
@@ -2248,7 +2269,7 @@ impl Evaluator<'_> {
                     interval: args_for_target[0].interval.slice(0..self.ptr_size()),
                     ty: ty.clone(),
                 };
-                let ty = GenericArgData::Ty(ty.clone()).intern(Interner);
+                let ty = ty.clone().cast(Interner);
                 let generics_for_target = Substitution::from_iter(
                     Interner,
                     generic_args.iter(Interner).enumerate().map(|(i, it)| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
index b2e29fd34b5..52943e97ac0 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -136,7 +136,10 @@ impl Evaluator<'_> {
                     not_supported!("wrong generic arg kind for clone");
                 };
                 // Clone has special impls for tuples and function pointers
-                if matches!(self_ty.kind(Interner), TyKind::Function(_) | TyKind::Tuple(..)) {
+                if matches!(
+                    self_ty.kind(Interner),
+                    TyKind::Function(_) | TyKind::Tuple(..) | TyKind::Closure(..)
+                ) {
                     self.exec_clone(def, args, self_ty.clone(), locals, destination, span)?;
                     return Ok(true);
                 }
@@ -167,32 +170,26 @@ impl Evaluator<'_> {
                 return destination
                     .write_from_interval(self, Interval { addr, size: destination.size });
             }
+            TyKind::Closure(id, subst) => {
+                let [arg] = args else {
+                    not_supported!("wrong arg count for clone");
+                };
+                let addr = Address::from_bytes(arg.get(self)?)?;
+                let (closure_owner, _) = self.db.lookup_intern_closure((*id).into());
+                let infer = self.db.infer(closure_owner);
+                let (captures, _) = infer.closure_info(id);
+                let layout = self.layout(&self_ty)?;
+                let ty_iter = captures.iter().map(|c| c.ty(subst));
+                self.exec_clone_for_fields(ty_iter, layout, addr, def, locals, destination, span)?;
+            }
             TyKind::Tuple(_, subst) => {
                 let [arg] = args else {
                     not_supported!("wrong arg count for clone");
                 };
                 let addr = Address::from_bytes(arg.get(self)?)?;
                 let layout = self.layout(&self_ty)?;
-                for (i, ty) in subst.iter(Interner).enumerate() {
-                    let ty = ty.assert_ty_ref(Interner);
-                    let size = self.layout(ty)?.size.bytes_usize();
-                    let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
-                    let arg = IntervalAndTy {
-                        interval: Interval { addr: tmp, size: self.ptr_size() },
-                        ty: TyKind::Ref(Mutability::Not, static_lifetime(), ty.clone())
-                            .intern(Interner),
-                    };
-                    let offset = layout.fields.offset(i).bytes_usize();
-                    self.write_memory(tmp, &addr.offset(offset).to_bytes())?;
-                    self.exec_clone(
-                        def,
-                        &[arg],
-                        ty.clone(),
-                        locals,
-                        destination.slice(offset..offset + size),
-                        span,
-                    )?;
-                }
+                let ty_iter = subst.iter(Interner).map(|ga| ga.assert_ty_ref(Interner).clone());
+                self.exec_clone_for_fields(ty_iter, layout, addr, def, locals, destination, span)?;
             }
             _ => {
                 self.exec_fn_with_args(
@@ -209,6 +206,37 @@ impl Evaluator<'_> {
         Ok(())
     }
 
+    fn exec_clone_for_fields(
+        &mut self,
+        ty_iter: impl Iterator<Item = Ty>,
+        layout: Arc<Layout>,
+        addr: Address,
+        def: FunctionId,
+        locals: &Locals,
+        destination: Interval,
+        span: MirSpan,
+    ) -> Result<()> {
+        for (i, ty) in ty_iter.enumerate() {
+            let size = self.layout(&ty)?.size.bytes_usize();
+            let tmp = self.heap_allocate(self.ptr_size(), self.ptr_size())?;
+            let arg = IntervalAndTy {
+                interval: Interval { addr: tmp, size: self.ptr_size() },
+                ty: TyKind::Ref(Mutability::Not, static_lifetime(), ty.clone()).intern(Interner),
+            };
+            let offset = layout.fields.offset(i).bytes_usize();
+            self.write_memory(tmp, &addr.offset(offset).to_bytes())?;
+            self.exec_clone(
+                def,
+                &[arg],
+                ty,
+                locals,
+                destination.slice(offset..offset + size),
+                span,
+            )?;
+        }
+        Ok(())
+    }
+
     fn exec_alloc_fn(
         &mut self,
         alloc_fn: &str,
@@ -473,6 +501,38 @@ impl Evaluator<'_> {
                 self.write_memory_using_ref(destination.addr, destination.size)?.fill(0);
                 Ok(())
             }
+            "getenv" => {
+                let [name] = args else {
+                    return Err(MirEvalError::TypeError("libc::write args are not provided"));
+                };
+                let mut name_buf = vec![];
+                let name = {
+                    let mut index = Address::from_bytes(name.get(self)?)?;
+                    loop {
+                        let byte = self.read_memory(index, 1)?[0];
+                        index = index.offset(1);
+                        if byte == 0 {
+                            break;
+                        }
+                        name_buf.push(byte);
+                    }
+                    String::from_utf8_lossy(&name_buf)
+                };
+                let value = self.db.crate_graph()[self.crate_id].env.get(&name);
+                match value {
+                    None => {
+                        // Write null as fail
+                        self.write_memory_using_ref(destination.addr, destination.size)?.fill(0);
+                    }
+                    Some(mut value) => {
+                        value.push('\0');
+                        let addr = self.heap_allocate(value.len(), 1)?;
+                        self.write_memory(addr, value.as_bytes())?;
+                        self.write_memory(destination.addr, &addr.to_bytes())?;
+                    }
+                }
+                Ok(())
+            }
             _ => not_supported!("unknown external function {as_str}"),
         }
     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
index 46165cf3d69..ff30dc6dade 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/tests.rs
@@ -730,6 +730,48 @@ fn main() {
 }
 
 #[test]
+fn posix_getenv() {
+    check_pass(
+        r#"
+//- /main.rs env:foo=bar
+
+type c_char = u8;
+
+extern "C" {
+    pub fn getenv(s: *const c_char) -> *mut c_char;
+}
+
+fn should_not_reach() {
+    _ // FIXME: replace this function with panic when that works
+}
+
+fn main() {
+    let result = getenv(b"foo\0" as *const _);
+    if *result != b'b' {
+        should_not_reach();
+    }
+    let result = (result as usize + 1) as *const c_char;
+    if *result != b'a' {
+        should_not_reach();
+    }
+    let result = (result as usize + 1) as *const c_char;
+    if *result != b'r' {
+        should_not_reach();
+    }
+    let result = (result as usize + 1) as *const c_char;
+    if *result != 0 {
+        should_not_reach();
+    }
+    let result = getenv(b"not found\0" as *const _);
+    if result as usize != 0 {
+        should_not_reach();
+    }
+}
+"#,
+    );
+}
+
+#[test]
 fn posix_tls() {
     check_pass(
         r#"
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 718df8331e2..51cf882d053 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -15,7 +15,7 @@ use hir_def::{
     path::Path,
     resolver::{resolver_for_expr, HasResolver, ResolveValueResult, ValueNs},
     AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId,
-    TraitId, TypeOrConstParamId,
+    Lookup, TraitId, TypeOrConstParamId,
 };
 use hir_expand::name::Name;
 use la_arena::ArenaMap;
@@ -372,7 +372,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
         match &self.body.exprs[expr_id] {
             Expr::Missing => {
                 if let DefWithBodyId::FunctionId(f) = self.owner {
-                    let assoc = self.db.lookup_intern_function(f);
+                    let assoc = f.lookup(self.db.upcast());
                     if let ItemContainerId::TraitId(t) = assoc.container {
                         let name = &self.db.function_data(f).name;
                         return Err(MirLowerError::TraitFunctionDefinition(t, name.clone()));
@@ -1244,6 +1244,41 @@ impl<'ctx> MirLowerCtx<'ctx> {
         }
     }
 
+    fn lower_destructing_assignment(
+        &mut self,
+        mut current: BasicBlockId,
+        lhs: ExprId,
+        rhs: Place,
+        span: MirSpan,
+    ) -> Result<Option<BasicBlockId>> {
+        match &self.body.exprs[lhs] {
+            Expr::Tuple { exprs, is_assignee_expr: _ } => {
+                for (i, expr) in exprs.iter().enumerate() {
+                    let Some(c) = self.lower_destructing_assignment(
+                        current,
+                        *expr,
+                        rhs.project(ProjectionElem::TupleOrClosureField(i)),
+                        span,
+                    )? else {
+                        return Ok(None);
+                    };
+                    current = c;
+                }
+                Ok(Some(current))
+            }
+            Expr::Underscore => Ok(Some(current)),
+            _ => {
+                let Some((lhs_place, current)) =
+                    self.lower_expr_as_place(current, lhs, false)?
+                else {
+                    return Ok(None);
+                };
+                self.push_assignment(current, lhs_place, Operand::Copy(rhs).into(), span);
+                Ok(Some(current))
+            }
+        }
+    }
+
     fn lower_assignment(
         &mut self,
         current: BasicBlockId,
@@ -1259,6 +1294,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
         if matches!(&self.body.exprs[lhs], Expr::Underscore) {
             return Ok(Some(current));
         }
+        if matches!(
+            &self.body.exprs[lhs],
+            Expr::Tuple { .. } | Expr::RecordLit { .. } | Expr::Call { .. }
+        ) {
+            let temp = self.temp(self.expr_ty_after_adjustments(rhs), current, rhs.into())?;
+            let temp = Place::from(temp);
+            self.push_assignment(current, temp.clone(), rhs_op.into(), span);
+            return self.lower_destructing_assignment(current, lhs, temp, span);
+        }
         let Some((lhs_place, current)) =
             self.lower_expr_as_place(current, lhs, false)?
         else {
@@ -1308,14 +1352,14 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     .resolve_path_in_value_ns(self.db.upcast(), c)
                     .ok_or_else(unresolved_name)?;
                 match pr {
-                    ResolveValueResult::ValueNs(v) => {
+                    ResolveValueResult::ValueNs(v, _) => {
                         if let ValueNs::ConstId(c) = v {
                             self.lower_const_to_operand(Substitution::empty(Interner), c.into(), ty)
                         } else {
                             not_supported!("bad path in range pattern");
                         }
                     }
-                    ResolveValueResult::Partial(_, _) => {
+                    ResolveValueResult::Partial(_, _, _) => {
                         not_supported!("associated constants in range pattern")
                     }
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
index 3354cbd76a0..1cdfd919742 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -323,7 +323,7 @@ impl MirLowerCtx<'_> {
                                 break 'b (c, x.1);
                             }
                         }
-                        if let ResolveValueResult::ValueNs(v) = pr {
+                        if let ResolveValueResult::ValueNs(v, _) = pr {
                             if let ValueNs::ConstId(c) = v {
                                 break 'b (c, Substitution::empty(Interner));
                             }
diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs
index 0f2fb2c8118..121e5a0a249 100644
--- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs
@@ -3,18 +3,19 @@
 use hir_def::{
     attr::{AttrsWithOwner, Documentation},
     item_scope::ItemInNs,
-    path::ModPath,
-    resolver::HasResolver,
-    AttrDefId, GenericParamId, ModuleDefId,
+    path::{ModPath, Path},
+    per_ns::Namespace,
+    resolver::{HasResolver, Resolver, TypeNs},
+    AssocItemId, AttrDefId, GenericParamId, ModuleDefId,
 };
-use hir_expand::hygiene::Hygiene;
+use hir_expand::{hygiene::Hygiene, name::Name};
 use hir_ty::db::HirDatabase;
 use syntax::{ast, AstNode};
 
 use crate::{
-    Adt, AssocItem, Const, ConstParam, Enum, ExternCrateDecl, Field, Function, GenericParam, Impl,
-    LifetimeParam, Macro, Module, ModuleDef, Static, Struct, Trait, TraitAlias, TypeAlias,
-    TypeParam, Union, Variant,
+    Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, Enum, ExternCrateDecl, Field,
+    Function, GenericParam, Impl, LifetimeParam, Macro, Module, ModuleDef, Static, Struct, Trait,
+    TraitAlias, TypeAlias, TypeParam, Union, Variant, VariantDef,
 };
 
 pub trait HasAttrs {
@@ -25,14 +26,14 @@ pub trait HasAttrs {
         db: &dyn HirDatabase,
         link: &str,
         ns: Option<Namespace>,
-    ) -> Option<ModuleDef>;
+    ) -> Option<DocLinkDef>;
 }
 
-#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
-pub enum Namespace {
-    Types,
-    Values,
-    Macros,
+/// Subset of `ide_db::Definition` that doc links can resolve to.
+pub enum DocLinkDef {
+    ModuleDef(ModuleDef),
+    Field(Field),
+    SelfType(Trait),
 }
 
 macro_rules! impl_has_attrs {
@@ -46,9 +47,14 @@ macro_rules! impl_has_attrs {
                 let def = AttrDefId::$def_id(self.into());
                 db.attrs(def).docs()
             }
-            fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
+            fn resolve_doc_path(
+                self,
+                db: &dyn HirDatabase,
+                link: &str,
+                ns: Option<Namespace>
+            ) -> Option<DocLinkDef> {
                 let def = AttrDefId::$def_id(self.into());
-                resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
+                resolve_doc_path(db, def, link, ns)
             }
         }
     )*};
@@ -79,7 +85,12 @@ macro_rules! impl_has_attrs_enum {
             fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
                 $enum::$variant(self).docs(db)
             }
-            fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
+            fn resolve_doc_path(
+                self,
+                db: &dyn HirDatabase,
+                link: &str,
+                ns: Option<Namespace>
+            ) -> Option<DocLinkDef> {
                 $enum::$variant(self).resolve_doc_path(db, link, ns)
             }
         }
@@ -111,7 +122,7 @@ impl HasAttrs for AssocItem {
         db: &dyn HirDatabase,
         link: &str,
         ns: Option<Namespace>,
-    ) -> Option<ModuleDef> {
+    ) -> Option<DocLinkDef> {
         match self {
             AssocItem::Function(it) => it.resolve_doc_path(db, link, ns),
             AssocItem::Const(it) => it.resolve_doc_path(db, link, ns),
@@ -147,9 +158,9 @@ impl HasAttrs for ExternCrateDecl {
         db: &dyn HirDatabase,
         link: &str,
         ns: Option<Namespace>,
-    ) -> Option<ModuleDef> {
+    ) -> Option<DocLinkDef> {
         let def = AttrDefId::ExternCrateId(self.into());
-        resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
+        resolve_doc_path(db, def, link, ns)
     }
 }
 
@@ -159,7 +170,7 @@ fn resolve_doc_path(
     def: AttrDefId,
     link: &str,
     ns: Option<Namespace>,
-) -> Option<ModuleDefId> {
+) -> Option<DocLinkDef> {
     let resolver = match def {
         AttrDefId::ModuleId(it) => it.resolver(db.upcast()),
         AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
@@ -184,8 +195,107 @@ fn resolve_doc_path(
         .resolver(db.upcast()),
     };
 
-    let modpath = {
-        // FIXME: this is not how we should get a mod path here
+    let mut modpath = modpath_from_str(db, link)?;
+
+    let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
+    if resolved.is_none() {
+        let last_name = modpath.pop_segment()?;
+        resolve_assoc_or_field(db, resolver, modpath, last_name, ns)
+    } else {
+        let def = match ns {
+            Some(Namespace::Types) => resolved.take_types(),
+            Some(Namespace::Values) => resolved.take_values(),
+            Some(Namespace::Macros) => resolved.take_macros().map(ModuleDefId::MacroId),
+            None => resolved.iter_items().next().map(|(it, _)| match it {
+                ItemInNs::Types(it) => it,
+                ItemInNs::Values(it) => it,
+                ItemInNs::Macros(it) => ModuleDefId::MacroId(it),
+            }),
+        };
+        Some(DocLinkDef::ModuleDef(def?.into()))
+    }
+}
+
+fn resolve_assoc_or_field(
+    db: &dyn HirDatabase,
+    resolver: Resolver,
+    path: ModPath,
+    name: Name,
+    ns: Option<Namespace>,
+) -> Option<DocLinkDef> {
+    let path = Path::from_known_path_with_no_generic(path);
+    // FIXME: This does not handle `Self` on trait definitions, which we should resolve to the
+    // trait itself.
+    let base_def = resolver.resolve_path_in_type_ns_fully(db.upcast(), &path)?;
+
+    let ty = match base_def {
+        TypeNs::SelfType(id) => Impl::from(id).self_ty(db),
+        TypeNs::GenericParam(_) => {
+            // Even if this generic parameter has some trait bounds, rustdoc doesn't
+            // resolve `name` to trait items.
+            return None;
+        }
+        TypeNs::AdtId(id) | TypeNs::AdtSelfType(id) => Adt::from(id).ty(db),
+        TypeNs::EnumVariantId(id) => {
+            // Enum variants don't have path candidates.
+            let variant = Variant::from(id);
+            return resolve_field(db, variant.into(), name, ns);
+        }
+        TypeNs::TypeAliasId(id) => {
+            let alias = TypeAlias::from(id);
+            if alias.as_assoc_item(db).is_some() {
+                // We don't normalize associated type aliases, so we have nothing to
+                // resolve `name` to.
+                return None;
+            }
+            alias.ty(db)
+        }
+        TypeNs::BuiltinType(id) => BuiltinType::from(id).ty(db),
+        TypeNs::TraitId(id) => {
+            // Doc paths in this context may only resolve to an item of this trait
+            // (i.e. no items of its supertraits), so we need to handle them here
+            // independently of others.
+            return db.trait_data(id).items.iter().find(|it| it.0 == name).map(|(_, assoc_id)| {
+                let def = match *assoc_id {
+                    AssocItemId::FunctionId(it) => ModuleDef::Function(it.into()),
+                    AssocItemId::ConstId(it) => ModuleDef::Const(it.into()),
+                    AssocItemId::TypeAliasId(it) => ModuleDef::TypeAlias(it.into()),
+                };
+                DocLinkDef::ModuleDef(def)
+            });
+        }
+        TypeNs::TraitAliasId(_) => {
+            // XXX: Do these get resolved?
+            return None;
+        }
+    };
+
+    // FIXME: Resolve associated items here, e.g. `Option::map`. Note that associated items take
+    // precedence over fields.
+
+    let variant_def = match ty.as_adt()? {
+        Adt::Struct(it) => it.into(),
+        Adt::Union(it) => it.into(),
+        Adt::Enum(_) => return None,
+    };
+    resolve_field(db, variant_def, name, ns)
+}
+
+fn resolve_field(
+    db: &dyn HirDatabase,
+    def: VariantDef,
+    name: Name,
+    ns: Option<Namespace>,
+) -> Option<DocLinkDef> {
+    if let Some(Namespace::Types | Namespace::Macros) = ns {
+        return None;
+    }
+    def.fields(db).into_iter().find(|f| f.name(db) == name).map(DocLinkDef::Field)
+}
+
+fn modpath_from_str(db: &dyn HirDatabase, link: &str) -> Option<ModPath> {
+    // FIXME: this is not how we should get a mod path here.
+    let try_get_modpath = |link: &str| {
         let ast_path = ast::SourceFile::parse(&format!("type T = {link};"))
             .syntax_node()
             .descendants()
@@ -193,23 +303,20 @@ fn resolve_doc_path(
         if ast_path.syntax().text() != link {
             return None;
         }
-        ModPath::from_src(db.upcast(), ast_path, &Hygiene::new_unhygienic())?
+        ModPath::from_src(db.upcast(), ast_path, &Hygiene::new_unhygienic())
     };
 
-    let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
-    let resolved = if resolved.is_none() {
-        resolver.resolve_module_path_in_trait_assoc_items(db.upcast(), &modpath)?
-    } else {
-        resolved
-    };
-    match ns {
-        Some(Namespace::Types) => resolved.take_types(),
-        Some(Namespace::Values) => resolved.take_values(),
-        Some(Namespace::Macros) => resolved.take_macros().map(ModuleDefId::MacroId),
-        None => resolved.iter_items().next().map(|it| match it {
-            ItemInNs::Types(it) => it,
-            ItemInNs::Values(it) => it,
-            ItemInNs::Macros(it) => ModuleDefId::MacroId(it),
-        }),
+    let full = try_get_modpath(link);
+    if full.is_some() {
+        return full;
     }
+
+    // Tuple field names cannot be a part of `ModPath` usually, but rustdoc can
+    // resolve doc paths like `TupleStruct::0`.
+    // FIXME: Find a better way to handle these.
+    let (base, maybe_tuple_field) = link.rsplit_once("::")?;
+    let tuple_field = Name::new_tuple_field(maybe_tuple_field.parse().ok()?);
+    let mut modpath = try_get_modpath(base)?;
+    modpath.push_segment(tuple_field);
+    Some(modpath)
 }
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 9dfb98e459b..ac171026d5d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -8,7 +8,6 @@ use hir_def::{
     type_ref::{TypeBound, TypeRef},
     AdtId, GenericDefId,
 };
-use hir_expand::name;
 use hir_ty::{
     display::{
         write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
@@ -19,8 +18,9 @@ use hir_ty::{
 
 use crate::{
     Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Enum, ExternCrateDecl, Field,
-    Function, GenericParam, HasCrate, HasVisibility, LifetimeParam, Macro, Module, Static, Struct,
-    Trait, TraitAlias, TyBuilder, Type, TypeAlias, TypeOrConstParam, TypeParam, Union, Variant,
+    Function, GenericParam, HasCrate, HasVisibility, LifetimeParam, Macro, Module, SelfParam,
+    Static, Struct, Trait, TraitAlias, TyBuilder, Type, TypeAlias, TypeOrConstParam, TypeParam,
+    Union, Variant,
 };
 
 impl HirDisplay for Function {
@@ -57,37 +57,21 @@ impl HirDisplay for Function {
 
         f.write_char('(')?;
 
-        let write_self_param = |ty: &TypeRef, f: &mut HirFormatter<'_>| match ty {
-            TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
-            TypeRef::Reference(inner, lifetime, mut_) if matches!(&**inner, TypeRef::Path(p) if p.is_self_type()) =>
-            {
-                f.write_char('&')?;
-                if let Some(lifetime) = lifetime {
-                    write!(f, "{} ", lifetime.name.display(f.db.upcast()))?;
-                }
-                if let hir_def::type_ref::Mutability::Mut = mut_ {
-                    f.write_str("mut ")?;
-                }
-                f.write_str("self")
-            }
-            _ => {
-                f.write_str("self: ")?;
-                ty.hir_fmt(f)
-            }
-        };
-
         let mut first = true;
+        let mut skip_self = 0;
+        if let Some(self_param) = self.self_param(db) {
+            self_param.hir_fmt(f)?;
+            first = false;
+            skip_self = 1;
+        }
+
         // FIXME: Use resolved `param.ty` once we no longer discard lifetimes
-        for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)) {
+        for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
             let local = param.as_local(db).map(|it| it.name(db));
             if !first {
                 f.write_str(", ")?;
             } else {
                 first = false;
-                if local == Some(name!(self)) {
-                    write_self_param(type_ref, f)?;
-                    continue;
-                }
             }
             match local {
                 Some(name) => write!(f, "{}: ", name.display(f.db.upcast()))?,
@@ -137,6 +121,31 @@ impl HirDisplay for Function {
     }
 }
 
+impl HirDisplay for SelfParam {
+    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
+        let data = f.db.function_data(self.func);
+        let param = data.params.first().unwrap();
+        match &**param {
+            TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
+            TypeRef::Reference(inner, lifetime, mut_) if matches!(&**inner, TypeRef::Path(p) if p.is_self_type()) =>
+            {
+                f.write_char('&')?;
+                if let Some(lifetime) = lifetime {
+                    write!(f, "{} ", lifetime.name.display(f.db.upcast()))?;
+                }
+                if let hir_def::type_ref::Mutability::Mut = mut_ {
+                    f.write_str("mut ")?;
+                }
+                f.write_str("self")
+            }
+            ty => {
+                f.write_str("self: ")?;
+                ty.hir_fmt(f)
+            }
+        }
+    }
+}
+
 impl HirDisplay for Adt {
     fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
         match self {
@@ -357,6 +366,11 @@ fn write_generic_params(
                     delim(f)?;
                     write!(f, "const {}: ", name.display(f.db.upcast()))?;
                     c.ty.hir_fmt(f)?;
+
+                    if let Some(default) = &c.default {
+                        f.write_str(" = ")?;
+                        write!(f, "{}", default.display(f.db.upcast()))?;
+                    }
                 }
             }
         }
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index bf041b61f2f..512fe7e0428 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -63,12 +63,13 @@ use hir_ty::{
     all_super_traits, autoderef,
     consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
     diagnostics::BodyValidationDiagnostic,
+    known_const_to_ast,
     layout::{Layout as TyLayout, RustcEnumVariantIdx, TagEncoding},
     method_resolution::{self, TyFingerprint},
     mir::{self, interpret_mir},
     primitive::UintTy,
     traits::FnTrait,
-    AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
+    AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
     GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
     TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, ValueTyDefId,
     WhereClause,
@@ -87,7 +88,7 @@ use triomphe::Arc;
 use crate::db::{DefDatabase, HirDatabase};
 
 pub use crate::{
-    attrs::{HasAttrs, Namespace},
+    attrs::{DocLinkDef, HasAttrs},
     diagnostics::{
         AnyDiagnostic, BreakOutsideOfLoop, CaseType, ExpectedFunction, InactiveCode,
         IncoherentImpl, IncorrectCase, InvalidDeriveTarget, MacroDefError, MacroError,
@@ -121,6 +122,7 @@ pub use {
         lang_item::LangItem,
         nameres::{DefMap, ModuleSource},
         path::{ModPath, PathKind},
+        per_ns::Namespace,
         type_ref::{Mutability, TypeRef},
         visibility::Visibility,
         // FIXME: This is here since some queries take it as input that are used
@@ -719,20 +721,18 @@ fn emit_def_diagnostic_(
 ) {
     match diag {
         DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates } => {
-            let decl = declaration.to_node(db.upcast());
+            let decl = declaration.to_ptr(db.upcast());
             acc.push(
                 UnresolvedModule {
-                    decl: InFile::new(declaration.file_id, AstPtr::new(&decl)),
+                    decl: InFile::new(declaration.file_id, decl),
                     candidates: candidates.clone(),
                 }
                 .into(),
             )
         }
         DefDiagnosticKind::UnresolvedExternCrate { ast } => {
-            let item = ast.to_node(db.upcast());
-            acc.push(
-                UnresolvedExternCrate { decl: InFile::new(ast.file_id, AstPtr::new(&item)) }.into(),
-            );
+            let item = ast.to_ptr(db.upcast());
+            acc.push(UnresolvedExternCrate { decl: InFile::new(ast.file_id, item) }.into());
         }
 
         DefDiagnosticKind::UnresolvedImport { id, index } => {
@@ -747,14 +747,10 @@ fn emit_def_diagnostic_(
         }
 
         DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
-            let item = ast.to_node(db.upcast());
+            let item = ast.to_ptr(db.upcast());
             acc.push(
-                InactiveCode {
-                    node: ast.with_value(SyntaxNodePtr::new(&item).into()),
-                    cfg: cfg.clone(),
-                    opts: opts.clone(),
-                }
-                .into(),
+                InactiveCode { node: ast.with_value(item), cfg: cfg.clone(), opts: opts.clone() }
+                    .into(),
             );
         }
         DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
@@ -1273,7 +1269,7 @@ impl Adt {
             .fill(|x| {
                 let r = it.next().unwrap_or_else(|| TyKind::Error.intern(Interner));
                 match x {
-                    ParamKind::Type => GenericArgData::Ty(r).intern(Interner),
+                    ParamKind::Type => r.cast(Interner),
                     ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
                 }
             })
@@ -2096,14 +2092,6 @@ impl SelfParam {
             .unwrap_or(Access::Owned)
     }
 
-    pub fn display(self, db: &dyn HirDatabase) -> &'static str {
-        match self.access(db) {
-            Access::Shared => "&self",
-            Access::Exclusive => "&mut self",
-            Access::Owned => "self",
-        }
-    }
-
     pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>> {
         let InFile { file_id, value } = Function::from(self.func).source(db)?;
         value
@@ -3142,12 +3130,8 @@ impl TypeParam {
     }
 
     pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
-        let params = db.generic_defaults(self.id.parent());
-        let local_idx = hir_ty::param_idx(db, self.id.into())?;
+        let ty = generic_arg_from_param(db, self.id.into())?;
         let resolver = self.id.parent().resolver(db.upcast());
-        let ty = params.get(local_idx)?.clone();
-        let subst = TyBuilder::placeholder_subst(db, self.id.parent());
-        let ty = ty.substitute(Interner, &subst);
         match ty.data(Interner) {
             GenericArgData::Ty(it) => {
                 Some(Type::new_with_resolver_inner(db, &resolver, it.clone()))
@@ -3209,6 +3193,19 @@ impl ConstParam {
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         Type::new(db, self.id.parent(), db.const_param_ty(self.id))
     }
+
+    pub fn default(self, db: &dyn HirDatabase) -> Option<ast::ConstArg> {
+        let arg = generic_arg_from_param(db, self.id.into())?;
+        known_const_to_ast(arg.constant(Interner)?, db)
+    }
+}
+
+fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg> {
+    let params = db.generic_defaults(id.parent);
+    let local_idx = hir_ty::param_idx(db, id)?;
+    let ty = params.get(local_idx)?.clone();
+    let subst = TyBuilder::placeholder_subst(db, id.parent);
+    Some(ty.substitute(Interner, &subst))
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -3716,7 +3713,7 @@ impl Type {
             .fill(|x| {
                 let r = it.next().unwrap();
                 match x {
-                    ParamKind::Type => GenericArgData::Ty(r).intern(Interner),
+                    ParamKind::Type => r.cast(Interner),
                     ParamKind::Const(ty) => {
                         // FIXME: this code is not covered in tests.
                         unknown_const_as_generic(ty.clone())
@@ -3749,9 +3746,7 @@ impl Type {
             .fill(|it| {
                 // FIXME: this code is not covered in tests.
                 match it {
-                    ParamKind::Type => {
-                        GenericArgData::Ty(args.next().unwrap().ty.clone()).intern(Interner)
-                    }
+                    ParamKind::Type => args.next().unwrap().ty.clone().cast(Interner),
                     ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()),
                 }
             })
@@ -4414,14 +4409,13 @@ impl Callable {
             Other => CallableKind::Other,
         }
     }
-    pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(ast::SelfParam, Type)> {
+    pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(SelfParam, Type)> {
         let func = match self.callee {
             Callee::Def(CallableDefId::FunctionId(it)) if self.is_bound_method => it,
             _ => return None,
         };
-        let src = func.lookup(db.upcast()).source(db.upcast());
-        let param_list = src.value.param_list()?;
-        Some((param_list.self_param()?, self.ty.derived(self.sig.params()[0].clone())))
+        let func = Function { id: func };
+        Some((func.self_param(db)?, self.ty.derived(self.sig.params()[0].clone())))
     }
     pub fn n_params(&self) -> usize {
         self.sig.params().len() - if self.is_bound_method { 1 } else { 0 }
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index e99d2984c36..b8d4ecd4414 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -170,6 +170,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         self.imp.is_derive_annotated(item)
     }
 
+    /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the
+    /// expansion. `token_to_map` should be a token from the `speculative args` node.
     pub fn speculative_expand(
         &self,
         actual_macro_call: &ast::MacroCall,
@@ -179,6 +181,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         self.imp.speculative_expand(actual_macro_call, speculative_args, token_to_map)
     }
 
+    /// Expand the macro call with a different item as the input, mapping the `token_to_map` down into the
+    /// expansion. `token_to_map` should be a token from the `speculative args` node.
     pub fn speculative_expand_attr_macro(
         &self,
         actual_macro_call: &ast::Item,
@@ -201,14 +205,22 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         )
     }
 
-    /// Descend the token into macrocalls to its first mapped counterpart.
-    pub fn descend_into_macros_single(&self, token: SyntaxToken) -> SyntaxToken {
-        self.imp.descend_into_macros_single(token)
+    /// Descend the token into its macro call if it is part of one, returning the token in the
+    /// expansion that it is associated with. If `offset` points into the token's range, it will
+    /// be considered for the mapping in case of inline format args.
+    pub fn descend_into_macros_single(&self, token: SyntaxToken, offset: TextSize) -> SyntaxToken {
+        self.imp.descend_into_macros_single(token, offset)
     }
 
-    /// Descend the token into macrocalls to all its mapped counterparts.
-    pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
-        self.imp.descend_into_macros(token)
+    /// Descend the token into its macro call if it is part of one, returning the tokens in the
+    /// expansion that it is associated with. If `offset` points into the token's range, it will
+    /// be considered for the mapping in case of inline format args.
+    pub fn descend_into_macros(
+        &self,
+        token: SyntaxToken,
+        offset: TextSize,
+    ) -> SmallVec<[SyntaxToken; 1]> {
+        self.imp.descend_into_macros(token, offset)
     }
 
     /// Descend the token into macrocalls to all its mapped counterparts that have the same text as the input token.
@@ -217,12 +229,17 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     pub fn descend_into_macros_with_same_text(
         &self,
         token: SyntaxToken,
+        offset: TextSize,
     ) -> SmallVec<[SyntaxToken; 1]> {
-        self.imp.descend_into_macros_with_same_text(token)
+        self.imp.descend_into_macros_with_same_text(token, offset)
     }
 
-    pub fn descend_into_macros_with_kind_preference(&self, token: SyntaxToken) -> SyntaxToken {
-        self.imp.descend_into_macros_with_kind_preference(token)
+    pub fn descend_into_macros_with_kind_preference(
+        &self,
+        token: SyntaxToken,
+        offset: TextSize,
+    ) -> SyntaxToken {
+        self.imp.descend_into_macros_with_kind_preference(token, offset)
     }
 
     /// Maps a node down by mapping its first and last token down.
@@ -606,7 +623,7 @@ impl<'db> SemanticsImpl<'db> {
         let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
             resolver
                 .resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
-                .map(|it| macro_id_to_def_id(self.db.upcast(), it))
+                .map(|(it, _)| macro_id_to_def_id(self.db.upcast(), it))
         })?;
         hir_expand::db::expand_speculative(
             self.db.upcast(),
@@ -665,7 +682,7 @@ impl<'db> SemanticsImpl<'db> {
         };
 
         if first == last {
-            self.descend_into_macros_impl(first, &mut |InFile { value, .. }| {
+            self.descend_into_macros_impl(first, 0.into(), &mut |InFile { value, .. }| {
                 if let Some(node) = value.parent_ancestors().find_map(N::cast) {
                     res.push(node)
                 }
@@ -674,7 +691,7 @@ impl<'db> SemanticsImpl<'db> {
         } else {
             // Descend first and last token, then zip them to look for the node they belong to
             let mut scratch: SmallVec<[_; 1]> = smallvec![];
-            self.descend_into_macros_impl(first, &mut |token| {
+            self.descend_into_macros_impl(first, 0.into(), &mut |token| {
                 scratch.push(token);
                 false
             });
@@ -682,6 +699,7 @@ impl<'db> SemanticsImpl<'db> {
             let mut scratch = scratch.into_iter();
             self.descend_into_macros_impl(
                 last,
+                0.into(),
                 &mut |InFile { value: last, file_id: last_fid }| {
                     if let Some(InFile { value: first, file_id: first_fid }) = scratch.next() {
                         if first_fid == last_fid {
@@ -705,19 +723,27 @@ impl<'db> SemanticsImpl<'db> {
         res
     }
 
-    fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
+    fn descend_into_macros(
+        &self,
+        token: SyntaxToken,
+        offset: TextSize,
+    ) -> SmallVec<[SyntaxToken; 1]> {
         let mut res = smallvec![];
-        self.descend_into_macros_impl(token, &mut |InFile { value, .. }| {
+        self.descend_into_macros_impl(token, offset, &mut |InFile { value, .. }| {
             res.push(value);
             false
         });
         res
     }
 
-    fn descend_into_macros_with_same_text(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
+    fn descend_into_macros_with_same_text(
+        &self,
+        token: SyntaxToken,
+        offset: TextSize,
+    ) -> SmallVec<[SyntaxToken; 1]> {
         let text = token.text();
         let mut res = smallvec![];
-        self.descend_into_macros_impl(token.clone(), &mut |InFile { value, .. }| {
+        self.descend_into_macros_impl(token.clone(), offset, &mut |InFile { value, .. }| {
             if value.text() == text {
                 res.push(value);
             }
@@ -729,7 +755,11 @@ impl<'db> SemanticsImpl<'db> {
         res
     }
 
-    fn descend_into_macros_with_kind_preference(&self, token: SyntaxToken) -> SyntaxToken {
+    fn descend_into_macros_with_kind_preference(
+        &self,
+        token: SyntaxToken,
+        offset: TextSize,
+    ) -> SyntaxToken {
         let fetch_kind = |token: &SyntaxToken| match token.parent() {
             Some(node) => match node.kind() {
                 kind @ (SyntaxKind::NAME | SyntaxKind::NAME_REF) => {
@@ -741,7 +771,7 @@ impl<'db> SemanticsImpl<'db> {
         };
         let preferred_kind = fetch_kind(&token);
         let mut res = None;
-        self.descend_into_macros_impl(token.clone(), &mut |InFile { value, .. }| {
+        self.descend_into_macros_impl(token.clone(), offset, &mut |InFile { value, .. }| {
             if fetch_kind(&value) == preferred_kind {
                 res = Some(value);
                 true
@@ -755,9 +785,9 @@ impl<'db> SemanticsImpl<'db> {
         res.unwrap_or(token)
     }
 
-    fn descend_into_macros_single(&self, token: SyntaxToken) -> SyntaxToken {
+    fn descend_into_macros_single(&self, token: SyntaxToken, offset: TextSize) -> SyntaxToken {
         let mut res = token.clone();
-        self.descend_into_macros_impl(token, &mut |InFile { value, .. }| {
+        self.descend_into_macros_impl(token, offset, &mut |InFile { value, .. }| {
             res = value;
             true
         });
@@ -767,9 +797,13 @@ impl<'db> SemanticsImpl<'db> {
     fn descend_into_macros_impl(
         &self,
         token: SyntaxToken,
+        // FIXME: We might want this to be Option<TextSize> to be able to opt out of subrange
+        // mapping, specifically for node downmapping
+        offset: TextSize,
         f: &mut dyn FnMut(InFile<SyntaxToken>) -> bool,
     ) {
         let _p = profile::span("descend_into_macros");
+        let relative_token_offset = token.text_range().start().checked_sub(offset);
         let parent = match token.parent() {
             Some(it) => it,
             None => return,
@@ -796,7 +830,12 @@ impl<'db> SemanticsImpl<'db> {
                     self.cache(value, file_id);
                 }
 
-                let mapped_tokens = expansion_info.map_token_down(self.db.upcast(), item, token)?;
+                let mapped_tokens = expansion_info.map_token_down(
+                    self.db.upcast(),
+                    item,
+                    token,
+                    relative_token_offset,
+                )?;
                 let len = stack.len();
 
                 // requeue the tokens we got from mapping our current token down
@@ -943,7 +982,7 @@ impl<'db> SemanticsImpl<'db> {
         offset: TextSize,
     ) -> impl Iterator<Item = impl Iterator<Item = SyntaxNode> + '_> + '_ {
         node.token_at_offset(offset)
-            .map(move |token| self.descend_into_macros(token))
+            .map(move |token| self.descend_into_macros(token, offset))
             .map(|descendants| {
                 descendants.into_iter().map(move |it| self.token_ancestors_with_macros(it))
             })
@@ -1683,6 +1722,14 @@ impl SemanticsScope<'_> {
             |name, id| cb(name, id.into()),
         )
     }
+
+    pub fn extern_crates(&self) -> impl Iterator<Item = (Name, Module)> + '_ {
+        self.resolver.extern_crates_in_scope().map(|(name, id)| (name, Module { id }))
+    }
+
+    pub fn extern_crate_decls(&self) -> impl Iterator<Item = Name> + '_ {
+        self.resolver.extern_crate_decls_in_scope(self.db.upcast())
+    }
 }
 
 #[derive(Debug)]
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 3499daf1140..f29fb1edf00 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -487,7 +487,7 @@ impl SourceAnalyzer {
         let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
         self.resolver
             .resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Bang))
-            .map(|it| it.into())
+            .map(|(it, _)| it.into())
     }
 
     pub(crate) fn resolve_bind_pat_to_const(
@@ -760,7 +760,7 @@ impl SourceAnalyzer {
         let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
             self.resolver
                 .resolve_path_as_macro(db.upcast(), &path, Some(MacroSubNs::Bang))
-                .map(|it| macro_id_to_def_id(db.upcast(), it))
+                .map(|(it, _)| macro_id_to_def_id(db.upcast(), it))
         })?;
         Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
     }
@@ -966,6 +966,7 @@ pub(crate) fn resolve_hir_path_as_attr_macro(
 ) -> Option<Macro> {
     resolver
         .resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Attr))
+        .map(|(it, _)| it)
         .map(Into::into)
 }
 
@@ -983,7 +984,7 @@ fn resolve_hir_path_(
                 res.map(|ty_ns| (ty_ns, path.segments().first()))
             }
             None => {
-                let (ty, remaining_idx) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
+                let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
                 match remaining_idx {
                     Some(remaining_idx) => {
                         if remaining_idx + 1 == path.segments().len() {
@@ -1067,7 +1068,7 @@ fn resolve_hir_path_(
     let macros = || {
         resolver
             .resolve_path_as_macro(db.upcast(), path.mod_path()?, None)
-            .map(|def| PathResolution::Def(ModuleDef::Macro(def.into())))
+            .map(|(def, _)| PathResolution::Def(ModuleDef::Macro(def.into())))
     };
 
     if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }
diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
index 43d957412bc..ca7874c3683 100644
--- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
@@ -2,8 +2,10 @@
 
 use base_db::FileRange;
 use hir_def::{
-    src::HasSource, AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, Lookup, MacroId,
-    ModuleDefId, ModuleId, TraitId,
+    item_scope::ItemInNs,
+    src::{HasChildSource, HasSource},
+    AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, Lookup, MacroId, ModuleDefId, ModuleId,
+    TraitId,
 };
 use hir_expand::{HirFileId, InFile};
 use hir_ty::db::HirDatabase;
@@ -167,6 +169,40 @@ impl<'a> SymbolCollector<'a> {
             self.collect_from_impl(impl_id);
         }
 
+        // Record renamed imports.
+        // In case it imports multiple items under different namespaces we just pick one arbitrarily
+        // for now.
+        for id in scope.imports() {
+            let loc = id.import.lookup(self.db.upcast());
+            loc.id.item_tree(self.db.upcast());
+            let source = id.import.child_source(self.db.upcast());
+            let Some(use_tree_src) = source.value.get(id.idx) else { continue };
+            let Some(rename) = use_tree_src.rename() else { continue };
+            let Some(name) = rename.name() else { continue };
+
+            let res = scope.fully_resolve_import(self.db.upcast(), id);
+            res.iter_items().for_each(|(item, _)| {
+                let def = match item {
+                    ItemInNs::Types(def) | ItemInNs::Values(def) => def,
+                    ItemInNs::Macros(def) => ModuleDefId::from(def),
+                }
+                .into();
+                let dec_loc = DeclarationLocation {
+                    hir_file_id: source.file_id,
+                    ptr: SyntaxNodePtr::new(use_tree_src.syntax()),
+                    name_ptr: SyntaxNodePtr::new(name.syntax()),
+                };
+
+                self.symbols.push(FileSymbol {
+                    name: name.text().into(),
+                    def,
+                    container_name: self.current_container_name.clone(),
+                    loc: dec_loc,
+                    is_alias: false,
+                });
+            });
+        }
+
         for const_id in scope.unnamed_consts() {
             self.collect_from_body(const_id);
         }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index 6aca716bb60..c0e5429a22c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -422,7 +422,7 @@ impl<'x, 'y, T, V, U: Default> Trait<'x, 'y, T, V, U> for () {
         check_assist(
             add_missing_default_members,
             r#"
-struct Bar<const: N: bool> {
+struct Bar<const N: usize> {
     bar: [i32, N]
 }
 
@@ -439,7 +439,7 @@ impl<const X: usize, Y, Z> Foo<X, Z> for S<Y> {
     $0
 }"#,
             r#"
-struct Bar<const: N: bool> {
+struct Bar<const N: usize> {
     bar: [i32, N]
 }
 
@@ -484,6 +484,107 @@ impl<X> Foo<42, {20 + 22}, X> for () {
     }
 
     #[test]
+    fn test_const_substitution_with_defaults() {
+        check_assist(
+            add_missing_default_members,
+            r#"
+trait Foo<T, const N: usize = 42, const M: bool = false, const P: char = 'a'> {
+    fn get_n(&self) -> usize { N }
+    fn get_m(&self) -> bool { M }
+    fn get_p(&self) -> char { P }
+    fn get_array(&self, arg: &T) -> [bool; N] { [M; N] }
+}
+
+impl<X> Foo<X> for () {
+    $0
+}"#,
+            r#"
+trait Foo<T, const N: usize = 42, const M: bool = false, const P: char = 'a'> {
+    fn get_n(&self) -> usize { N }
+    fn get_m(&self) -> bool { M }
+    fn get_p(&self) -> char { P }
+    fn get_array(&self, arg: &T) -> [bool; N] { [M; N] }
+}
+
+impl<X> Foo<X> for () {
+    $0fn get_n(&self) -> usize { 42 }
+
+    fn get_m(&self) -> bool { false }
+
+    fn get_p(&self) -> char { 'a' }
+
+    fn get_array(&self, arg: &X) -> [bool; 42] { [false; 42] }
+}"#,
+        );
+    }
+
+    #[test]
+    fn test_const_substitution_with_defaults_2() {
+        check_assist(
+            add_missing_impl_members,
+            r#"
+mod m {
+    pub const LEN: usize = 42;
+    pub trait Foo<const M: usize = LEN, const N: usize = M, T = [bool; N]> {
+        fn get_t(&self) -> T;
+    }
+}
+
+impl m::Foo for () {
+    $0
+}"#,
+            r#"
+mod m {
+    pub const LEN: usize = 42;
+    pub trait Foo<const M: usize = LEN, const N: usize = M, T = [bool; N]> {
+        fn get_t(&self) -> T;
+    }
+}
+
+impl m::Foo for () {
+    fn get_t(&self) -> [bool; m::LEN] {
+        ${0:todo!()}
+    }
+}"#,
+        )
+    }
+
+    #[test]
+    fn test_const_substitution_with_defaults_3() {
+        check_assist(
+            add_missing_default_members,
+            r#"
+mod m {
+    pub const VAL: usize = 0;
+
+    pub trait Foo<const N: usize = {40 + 2}, const M: usize = {VAL + 1}> {
+        fn get_n(&self) -> usize { N }
+        fn get_m(&self) -> usize { M }
+    }
+}
+
+impl m::Foo for () {
+    $0
+}"#,
+            r#"
+mod m {
+    pub const VAL: usize = 0;
+
+    pub trait Foo<const N: usize = {40 + 2}, const M: usize = {VAL + 1}> {
+        fn get_n(&self) -> usize { N }
+        fn get_m(&self) -> usize { M }
+    }
+}
+
+impl m::Foo for () {
+    $0fn get_n(&self) -> usize { {40 + 2} }
+
+    fn get_m(&self) -> usize { {m::VAL + 1} }
+}"#,
+        )
+    }
+
+    #[test]
     fn test_cursor_after_empty_impl_def() {
         check_assist(
             add_missing_impl_members,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
index 57cfa17cc8e..66bc2f6dadc 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
@@ -1,6 +1,10 @@
 use std::collections::VecDeque;
 
-use syntax::ast::{self, AstNode};
+use syntax::{
+    ast::{self, AstNode, Expr::BinExpr},
+    ted::{self, Position},
+    SyntaxKind,
+};
 
 use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists};
 
@@ -23,121 +27,117 @@ use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKin
 // }
 // ```
 pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
-    let op = expr.op_kind()?;
-    let op_range = expr.op_token()?.text_range();
+    let mut bin_expr = ctx.find_node_at_offset::<ast::BinExpr>()?;
+    let op = bin_expr.op_kind()?;
+    let op_range = bin_expr.op_token()?.text_range();
 
-    let opposite_op = match op {
-        ast::BinaryOp::LogicOp(ast::LogicOp::And) => "||",
-        ast::BinaryOp::LogicOp(ast::LogicOp::Or) => "&&",
-        _ => return None,
-    };
-
-    let cursor_in_range = op_range.contains_range(ctx.selection_trimmed());
-    if !cursor_in_range {
+    // Is the cursor on the expression's logical operator?
+    if !op_range.contains_range(ctx.selection_trimmed()) {
         return None;
     }
 
-    let mut expr = expr;
-
     // Walk up the tree while we have the same binary operator
-    while let Some(parent_expr) = expr.syntax().parent().and_then(ast::BinExpr::cast) {
-        match expr.op_kind() {
+    while let Some(parent_expr) = bin_expr.syntax().parent().and_then(ast::BinExpr::cast) {
+        match parent_expr.op_kind() {
             Some(parent_op) if parent_op == op => {
-                expr = parent_expr;
+                bin_expr = parent_expr;
             }
             _ => break,
         }
     }
 
-    let mut expr_stack = vec![expr.clone()];
-    let mut terms = Vec::new();
-    let mut op_ranges = Vec::new();
-
-    // Find all the children with the same binary operator
-    while let Some(expr) = expr_stack.pop() {
-        let mut traverse_bin_expr_arm = |expr| {
-            if let ast::Expr::BinExpr(bin_expr) = expr {
-                if let Some(expr_op) = bin_expr.op_kind() {
-                    if expr_op == op {
-                        expr_stack.push(bin_expr);
-                    } else {
-                        terms.push(ast::Expr::BinExpr(bin_expr));
-                    }
+    let op = bin_expr.op_kind()?;
+    let inv_token = match op {
+        ast::BinaryOp::LogicOp(ast::LogicOp::And) => SyntaxKind::PIPE2,
+        ast::BinaryOp::LogicOp(ast::LogicOp::Or) => SyntaxKind::AMP2,
+        _ => return None,
+    };
+
+    let demorganed = bin_expr.clone_subtree().clone_for_update();
+
+    ted::replace(demorganed.op_token()?, ast::make::token(inv_token));
+    let mut exprs = VecDeque::from(vec![
+        (bin_expr.lhs()?, demorganed.lhs()?),
+        (bin_expr.rhs()?, demorganed.rhs()?),
+    ]);
+
+    while let Some((expr, dm)) = exprs.pop_front() {
+        if let BinExpr(bin_expr) = &expr {
+            if let BinExpr(cbin_expr) = &dm {
+                if op == bin_expr.op_kind()? {
+                    ted::replace(cbin_expr.op_token()?, ast::make::token(inv_token));
+                    exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?));
+                    exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?));
                 } else {
-                    terms.push(ast::Expr::BinExpr(bin_expr));
+                    let mut inv = invert_boolean_expression(expr);
+                    if inv.needs_parens_in(dm.syntax().parent()?) {
+                        inv = ast::make::expr_paren(inv).clone_for_update();
+                    }
+                    ted::replace(dm.syntax(), inv.syntax());
                 }
             } else {
-                terms.push(expr);
+                return None;
             }
-        };
-
-        op_ranges.extend(expr.op_token().map(|t| t.text_range()));
-        traverse_bin_expr_arm(expr.lhs()?);
-        traverse_bin_expr_arm(expr.rhs()?);
+        } else {
+            let mut inv = invert_boolean_expression(dm.clone_subtree()).clone_for_update();
+            if inv.needs_parens_in(dm.syntax().parent()?) {
+                inv = ast::make::expr_paren(inv).clone_for_update();
+            }
+            ted::replace(dm.syntax(), inv.syntax());
+        }
     }
 
+    let dm_lhs = demorganed.lhs()?;
+
     acc.add(
         AssistId("apply_demorgan", AssistKind::RefactorRewrite),
         "Apply De Morgan's law",
         op_range,
         |edit| {
-            terms.sort_by_key(|t| t.syntax().text_range().start());
-            let mut terms = VecDeque::from(terms);
-
-            let paren_expr = expr.syntax().parent().and_then(ast::ParenExpr::cast);
-
+            let paren_expr = bin_expr.syntax().parent().and_then(ast::ParenExpr::cast);
             let neg_expr = paren_expr
                 .clone()
                 .and_then(|paren_expr| paren_expr.syntax().parent())
                 .and_then(ast::PrefixExpr::cast)
                 .and_then(|prefix_expr| {
-                    if prefix_expr.op_kind().unwrap() == ast::UnaryOp::Not {
+                    if prefix_expr.op_kind()? == ast::UnaryOp::Not {
                         Some(prefix_expr)
                     } else {
                         None
                     }
                 });
 
-            for op_range in op_ranges {
-                edit.replace(op_range, opposite_op);
-            }
-
             if let Some(paren_expr) = paren_expr {
-                for term in terms {
-                    let range = term.syntax().text_range();
-                    let not_term = invert_boolean_expression(term);
-
-                    edit.replace(range, not_term.syntax().text());
-                }
-
                 if let Some(neg_expr) = neg_expr {
                     cov_mark::hit!(demorgan_double_negation);
-                    edit.replace(neg_expr.op_token().unwrap().text_range(), "");
+                    edit.replace_ast(ast::Expr::PrefixExpr(neg_expr), demorganed.into());
                 } else {
                     cov_mark::hit!(demorgan_double_parens);
-                    edit.replace(paren_expr.l_paren_token().unwrap().text_range(), "!(");
+                    ted::insert_all_raw(
+                        Position::before(dm_lhs.syntax()),
+                        vec![
+                            syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::BANG)),
+                            syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::L_PAREN)),
+                        ],
+                    );
+
+                    ted::append_child_raw(
+                        demorganed.syntax(),
+                        syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::R_PAREN)),
+                    );
+
+                    edit.replace_ast(ast::Expr::ParenExpr(paren_expr), demorganed.into());
                 }
             } else {
-                if let Some(lhs) = terms.pop_front() {
-                    let lhs_range = lhs.syntax().text_range();
-                    let not_lhs = invert_boolean_expression(lhs);
-
-                    edit.replace(lhs_range, format!("!({not_lhs}"));
-                }
-
-                if let Some(rhs) = terms.pop_back() {
-                    let rhs_range = rhs.syntax().text_range();
-                    let not_rhs = invert_boolean_expression(rhs);
-
-                    edit.replace(rhs_range, format!("{not_rhs})"));
-                }
-
-                for term in terms {
-                    let term_range = term.syntax().text_range();
-                    let not_term = invert_boolean_expression(term);
-                    edit.replace(term_range, not_term.to_string());
-                }
+                ted::insert_all_raw(
+                    Position::before(dm_lhs.syntax()),
+                    vec![
+                        syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::BANG)),
+                        syntax::NodeOrToken::Token(ast::make::token(SyntaxKind::L_PAREN)),
+                    ],
+                );
+                ted::append_child_raw(demorganed.syntax(), ast::make::token(SyntaxKind::R_PAREN));
+                edit.replace_ast(bin_expr, demorganed);
             }
         },
     )
@@ -145,9 +145,8 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable};
-
     use super::*;
+    use crate::tests::{check_assist, check_assist_not_applicable};
 
     #[test]
     fn demorgan_handles_leq() {
@@ -213,7 +212,7 @@ fn f() { !(S <= S || S < S) }
     #[test]
     fn demorgan_doesnt_double_negation() {
         cov_mark::check!(demorgan_double_negation);
-        check_assist(apply_demorgan, "fn f() { !(x ||$0 x) }", "fn f() { (!x && !x) }")
+        check_assist(apply_demorgan, "fn f() { !(x ||$0 x) }", "fn f() { !x && !x }")
     }
 
     #[test]
@@ -222,13 +221,38 @@ fn f() { !(S <= S || S < S) }
         check_assist(apply_demorgan, "fn f() { (x ||$0 x) }", "fn f() { !(!x && !x) }")
     }
 
-    // https://github.com/rust-lang/rust-analyzer/issues/10963
+    // FIXME : This needs to go.
+    // // https://github.com/rust-lang/rust-analyzer/issues/10963
+    // #[test]
+    // fn demorgan_doesnt_hang() {
+    //     check_assist(
+    //         apply_demorgan,
+    //         "fn f() { 1 || 3 &&$0 4 || 5 }",
+    //         "fn f() { !(!1 || !3 || !4) || 5 }",
+    //     )
+    // }
+
+    #[test]
+    fn demorgan_keep_pars_for_op_precedence() {
+        check_assist(
+            apply_demorgan,
+            "fn main() {
+    let _ = !(!a ||$0 !(b || c));
+}
+",
+            "fn main() {
+    let _ = a && (b || c);
+}
+",
+        );
+    }
+
     #[test]
-    fn demorgan_doesnt_hang() {
+    fn demorgan_removes_pars_in_eq_precedence() {
         check_assist(
             apply_demorgan,
-            "fn f() { 1 || 3 &&$0 4 || 5 }",
-            "fn f() { !(!1 || !3 || !4) || 5 }",
+            "fn() { let x = a && !(!b |$0| !c); }",
+            "fn() { let x = a && b && c; }",
         )
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
index fe1cb6fce36..76f021ed912 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
@@ -161,9 +161,9 @@ fn process_struct_name_reference(
     let path_segment = name_ref.syntax().parent().and_then(ast::PathSegment::cast)?;
     // A `PathSegment` always belongs to a `Path`, so there's at least one `Path` at this point.
     let full_path =
-        path_segment.syntax().parent()?.ancestors().map_while(ast::Path::cast).last().unwrap();
+        path_segment.syntax().parent()?.ancestors().map_while(ast::Path::cast).last()?;
 
-    if full_path.segment().unwrap().name_ref()? != *name_ref {
+    if full_path.segment()?.name_ref()? != *name_ref {
         // `name_ref` isn't the last segment of the path, so `full_path` doesn't point to the
         // struct we want to edit.
         return None;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
index dcb96ab8af4..7d0e424769e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
@@ -58,7 +58,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
                     return None;
                 }
 
-                let bound_ident = pat.fields().next().unwrap();
+                let bound_ident = pat.fields().next()?;
                 if !ast::IdentPat::can_cast(bound_ident.syntax().kind()) {
                     return None;
                 }
@@ -108,6 +108,15 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
 
     then_block.syntax().last_child_or_token().filter(|t| t.kind() == T!['}'])?;
 
+    let then_block_items = then_block.dedent(IndentLevel(1)).clone_for_update();
+
+    let end_of_then = then_block_items.syntax().last_child_or_token()?;
+    let end_of_then = if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {
+        end_of_then.prev_sibling_or_token()?
+    } else {
+        end_of_then
+    };
+
     let target = if_expr.syntax().text_range();
     acc.add(
         AssistId("convert_to_guarded_return", AssistKind::RefactorRewrite),
@@ -141,16 +150,6 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
                 }
             };
 
-            let then_block_items = then_block.dedent(IndentLevel(1)).clone_for_update();
-
-            let end_of_then = then_block_items.syntax().last_child_or_token().unwrap();
-            let end_of_then =
-                if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {
-                    end_of_then.prev_sibling_or_token().unwrap()
-                } else {
-                    end_of_then
-                };
-
             let then_statements = replacement
                 .children_with_tokens()
                 .chain(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs
index 4f3b6e0c287..c3d925cb26c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs
@@ -48,7 +48,7 @@ pub(crate) fn extract_expressions_from_format_string(
     let tt = fmt_string.syntax().parent().and_then(ast::TokenTree::cast)?;
 
     let expanded_t = ast::String::cast(
-        ctx.sema.descend_into_macros_with_kind_preference(fmt_string.syntax().clone()),
+        ctx.sema.descend_into_macros_with_kind_preference(fmt_string.syntax().clone(), 0.into()),
     )?;
     if !is_format_string(&expanded_t) {
         return None;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index b8b781ea48d..ea7a21e77a4 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -750,7 +750,7 @@ impl FunctionBody {
                         .descendants_with_tokens()
                         .filter_map(SyntaxElement::into_token)
                         .filter(|it| matches!(it.kind(), SyntaxKind::IDENT | T![self]))
-                        .flat_map(|t| sema.descend_into_macros(t))
+                        .flat_map(|t| sema.descend_into_macros(t, 0.into()))
                         .for_each(|t| add_name_if_local(t.parent().and_then(ast::NameRef::cast)));
                 }
             }
@@ -810,7 +810,7 @@ impl FunctionBody {
                         (true, konst.body(), Some(sema.to_def(&konst)?.ty(sema.db)))
                     },
                     ast::ConstParam(cp) => {
-                        (true, cp.default_val(), Some(sema.to_def(&cp)?.ty(sema.db)))
+                        (true, cp.default_val()?.expr(), Some(sema.to_def(&cp)?.ty(sema.db)))
                     },
                     ast::ConstBlockPat(cbp) => {
                         let expr = cbp.block_expr().map(ast::Expr::BlockExpr);
@@ -1385,31 +1385,30 @@ enum FlowHandler {
 
 impl FlowHandler {
     fn from_ret_ty(fun: &Function, ret_ty: &FunType) -> FlowHandler {
-        match &fun.control_flow.kind {
-            None => FlowHandler::None,
-            Some(flow_kind) => {
-                let action = flow_kind.clone();
-                if let FunType::Unit = ret_ty {
-                    match flow_kind {
-                        FlowKind::Return(None)
-                        | FlowKind::Break(_, None)
-                        | FlowKind::Continue(_) => FlowHandler::If { action },
-                        FlowKind::Return(_) | FlowKind::Break(_, _) => {
-                            FlowHandler::IfOption { action }
-                        }
-                        FlowKind::Try { kind } => FlowHandler::Try { kind: kind.clone() },
-                    }
-                } else {
-                    match flow_kind {
-                        FlowKind::Return(None)
-                        | FlowKind::Break(_, None)
-                        | FlowKind::Continue(_) => FlowHandler::MatchOption { none: action },
-                        FlowKind::Return(_) | FlowKind::Break(_, _) => {
-                            FlowHandler::MatchResult { err: action }
-                        }
-                        FlowKind::Try { kind } => FlowHandler::Try { kind: kind.clone() },
-                    }
+        if fun.contains_tail_expr {
+            return FlowHandler::None;
+        }
+        let Some(action) = fun.control_flow.kind.clone() else {
+            return FlowHandler::None;
+        };
+
+        if let FunType::Unit = ret_ty {
+            match action {
+                FlowKind::Return(None) | FlowKind::Break(_, None) | FlowKind::Continue(_) => {
+                    FlowHandler::If { action }
+                }
+                FlowKind::Return(_) | FlowKind::Break(_, _) => FlowHandler::IfOption { action },
+                FlowKind::Try { kind } => FlowHandler::Try { kind },
+            }
+        } else {
+            match action {
+                FlowKind::Return(None) | FlowKind::Break(_, None) | FlowKind::Continue(_) => {
+                    FlowHandler::MatchOption { none: action }
+                }
+                FlowKind::Return(_) | FlowKind::Break(_, _) => {
+                    FlowHandler::MatchResult { err: action }
                 }
+                FlowKind::Try { kind } => FlowHandler::Try { kind },
             }
         }
     }
@@ -1654,11 +1653,7 @@ impl Function {
 
     fn make_ret_ty(&self, ctx: &AssistContext<'_>, module: hir::Module) -> Option<ast::RetType> {
         let fun_ty = self.return_type(ctx);
-        let handler = if self.contains_tail_expr {
-            FlowHandler::None
-        } else {
-            FlowHandler::from_ret_ty(self, &fun_ty)
-        };
+        let handler = FlowHandler::from_ret_ty(self, &fun_ty);
         let ret_ty = match &handler {
             FlowHandler::None => {
                 if matches!(fun_ty, FunType::Unit) {
@@ -1728,11 +1723,7 @@ fn make_body(
     fun: &Function,
 ) -> ast::BlockExpr {
     let ret_ty = fun.return_type(ctx);
-    let handler = if fun.contains_tail_expr {
-        FlowHandler::None
-    } else {
-        FlowHandler::from_ret_ty(fun, &ret_ty)
-    };
+    let handler = FlowHandler::from_ret_ty(fun, &ret_ty);
 
     let block = match &fun.body {
         FunctionBody::Expr(expr) => {
@@ -4471,7 +4462,7 @@ async fn foo() -> Result<(), ()> {
 "#,
             r#"
 async fn foo() -> Result<(), ()> {
-    fun_name().await?
+    fun_name().await
 }
 
 async fn $0fun_name() -> Result<(), ()> {
@@ -4690,7 +4681,7 @@ fn $0fun_name() {
         check_assist(
             extract_function,
             r#"
-//- minicore: result
+//- minicore: result, try
 fn foo() -> Result<(), i64> {
     $0Result::<i32, i64>::Ok(0)?;
     Ok(())$0
@@ -4698,7 +4689,7 @@ fn foo() -> Result<(), i64> {
 "#,
             r#"
 fn foo() -> Result<(), i64> {
-    fun_name()?
+    fun_name()
 }
 
 fn $0fun_name() -> Result<(), i64> {
@@ -5754,6 +5745,34 @@ fn $0fun_name<T, V>(t: T, v: V) -> i32 where T: Into<i32> + Copy, V: Into<i32> {
     }
 
     #[test]
+    fn tail_expr_no_extra_control_flow() {
+        check_assist(
+            extract_function,
+            r#"
+//- minicore: result
+fn fallible() -> Result<(), ()> {
+    $0if true {
+        return Err(());
+    }
+    Ok(())$0
+}
+"#,
+            r#"
+fn fallible() -> Result<(), ()> {
+    fun_name()
+}
+
+fn $0fun_name() -> Result<(), ()> {
+    if true {
+        return Err(());
+    }
+    Ok(())
+}
+"#,
+        );
+    }
+
+    #[test]
     fn non_tail_expr_of_tail_expr_loop() {
         check_assist(
             extract_function,
@@ -5800,12 +5819,6 @@ fn $0fun_name() -> ControlFlow<()> {
             extract_function,
             r#"
 //- minicore: option, try
-impl<T> core::ops::Try for Option<T> {
-    type Output = T;
-    type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
 fn f() -> Option<()> {
     if true {
         let a = $0if true {
@@ -5820,12 +5833,6 @@ fn f() -> Option<()> {
 }
 "#,
             r#"
-impl<T> core::ops::Try for Option<T> {
-    type Output = T;
-    type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
 fn f() -> Option<()> {
     if true {
         let a = fun_name()?;;
@@ -5852,12 +5859,6 @@ fn $0fun_name() -> Option<()> {
             extract_function,
             r#"
 //- minicore: option, try
-impl<T> core::ops::Try for Option<T> {
-    type Output = T;
-    type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
 fn f() -> Option<()> {
     if true {
         $0{
@@ -5874,15 +5875,9 @@ fn f() -> Option<()> {
 }
 "#,
             r#"
-impl<T> core::ops::Try for Option<T> {
-    type Output = T;
-    type Residual = Option<!>;
-}
-impl<T> core::ops::FromResidual for Option<T> {}
-
 fn f() -> Option<()> {
     if true {
-        fun_name()?
+        fun_name()
     } else {
         None
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
index 31fc69562c9..bbac0a26ea4 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_delegate_methods.rs
@@ -95,6 +95,9 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
         let Some(impl_def) = find_struct_impl(ctx, &adt, std::slice::from_ref(&name)) else {
             continue;
         };
+
+        let field = make::ext::field_from_idents(["self", &field_name])?;
+
         acc.add_group(
             &GroupLabel("Generate delegate methods…".to_owned()),
             AssistId("generate_delegate_methods", AssistKind::Generate),
@@ -115,11 +118,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
                     Some(list) => convert_param_list_to_arg_list(list),
                     None => make::arg_list([]),
                 };
-                let tail_expr = make::expr_method_call(
-                    make::ext::field_from_idents(["self", &field_name]).unwrap(), // This unwrap is ok because we have at least 1 arg in the list
-                    make::name_ref(&name),
-                    arg_list,
-                );
+                let tail_expr = make::expr_method_call(field, make::name_ref(&name), arg_list);
                 let ret_type = method_source.ret_type();
                 let is_async = method_source.async_token().is_some();
                 let is_const = method_source.const_token().is_some();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs
index 747f70f9f6f..53ba144ba9e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs
@@ -27,13 +27,19 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
     let cap = ctx.config.snippet_cap?;
     let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
     let target = nominal.syntax().text_range();
+    let derive_attr = nominal
+        .attrs()
+        .filter_map(|x| x.as_simple_call())
+        .filter(|(name, _arg)| name == "derive")
+        .map(|(_name, arg)| arg)
+        .next();
+
+    let delimiter = match &derive_attr {
+        None => None,
+        Some(tt) => Some(tt.right_delimiter_token()?),
+    };
+
     acc.add(AssistId("generate_derive", AssistKind::Generate), "Add `#[derive]`", target, |edit| {
-        let derive_attr = nominal
-            .attrs()
-            .filter_map(|x| x.as_simple_call())
-            .filter(|(name, _arg)| name == "derive")
-            .map(|(_name, arg)| arg)
-            .next();
         match derive_attr {
             None => {
                 let derive = make::attr_outer(make::meta_token_tree(
@@ -45,16 +51,23 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
                 let nominal = edit.make_mut(nominal);
                 nominal.add_attr(derive.clone());
 
+                let delimiter = derive
+                    .meta()
+                    .expect("make::attr_outer was expected to have Meta")
+                    .token_tree()
+                    .expect("failed to get token tree out of Meta")
+                    .r_paren_token()
+                    .expect("make::attr_outer was expected to have a R_PAREN");
+
+                edit.add_tabstop_before_token(cap, delimiter);
+            }
+            Some(_) => {
+                // Just move the cursor.
                 edit.add_tabstop_before_token(
                     cap,
-                    derive.meta().unwrap().token_tree().unwrap().r_paren_token().unwrap(),
+                    delimiter.expect("Right delim token could not be found."),
                 );
             }
-            Some(tt) => {
-                // Just move the cursor.
-                let tt = edit.make_mut(tt);
-                edit.add_tabstop_before_token(cap, tt.right_delimiter_token().unwrap());
-            }
         };
     })
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
index a403d5bc672..e2b82223289 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs
@@ -39,14 +39,11 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
 
     let replacements =
         macro_calls.into_iter().filter_map(compute_dbg_replacement).collect::<Vec<_>>();
-    if replacements.is_empty() {
-        return None;
-    }
 
     acc.add(
         AssistId("remove_dbg", AssistKind::Refactor),
         "Remove dbg!()",
-        replacements.iter().map(|&(range, _)| range).reduce(|acc, range| acc.cover(range)).unwrap(),
+        replacements.iter().map(|&(range, _)| range).reduce(|acc, range| acc.cover(range))?,
         |builder| {
             for (range, expr) in replacements {
                 if let Some(expr) = expr {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs
index dd4839351fb..5fcab8c02b0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs
@@ -67,7 +67,7 @@ pub(crate) fn remove_unused_imports(acc: &mut Assists, ctx: &AssistContext<'_>)
                 // This case maps to the situation where the * token is braced.
                 // In this case, the parent use tree's path is the one we should use to resolve the glob.
                 match u.syntax().ancestors().skip(1).find_map(ast::UseTree::cast) {
-                    Some(parent_u) if parent_u.path().is_some() => parent_u.path().unwrap(),
+                    Some(parent_u) if parent_u.path().is_some() => parent_u.path()?,
                     _ => return None,
                 }
             } else {
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
index 480cb77b4fd..f60ac150164 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs
@@ -20,6 +20,7 @@ pub(crate) mod r#type;
 pub(crate) mod use_;
 pub(crate) mod vis;
 pub(crate) mod env_vars;
+pub(crate) mod extern_crate;
 
 use std::iter;
 
@@ -703,7 +704,9 @@ pub(super) fn complete_name_ref(
                         TypeLocation::TypeAscription(ascription) => {
                             r#type::complete_ascribed_type(acc, ctx, path_ctx, ascription);
                         }
-                        TypeLocation::GenericArgList(_)
+                        TypeLocation::GenericArg { .. }
+                        | TypeLocation::AssocConstEq
+                        | TypeLocation::AssocTypeEq
                         | TypeLocation::TypeBound
                         | TypeLocation::ImplTarget
                         | TypeLocation::ImplTrait
@@ -737,6 +740,7 @@ pub(super) fn complete_name_ref(
                 }
             }
         }
+        NameRefKind::ExternCrate => extern_crate::complete_extern_crate(acc, ctx),
         NameRefKind::DotAccess(dot_access) => {
             flyimport::import_on_the_fly_dot(acc, ctx, dot_access);
             dot::complete_dot(acc, ctx, dot_access);
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs
new file mode 100644
index 00000000000..0d0e143f5f6
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_crate.rs
@@ -0,0 +1,71 @@
+//! Completion for extern crates
+
+use hir::{HasAttrs, Name};
+use ide_db::SymbolKind;
+
+use crate::{context::CompletionContext, CompletionItem, CompletionItemKind};
+
+use super::Completions;
+
+pub(crate) fn complete_extern_crate(acc: &mut Completions, ctx: &CompletionContext<'_>) {
+    let imported_extern_crates: Vec<Name> = ctx.scope.extern_crate_decls().collect();
+
+    for (name, module) in ctx.scope.extern_crates() {
+        if imported_extern_crates.contains(&name) {
+            continue;
+        }
+
+        let mut item = CompletionItem::new(
+            CompletionItemKind::SymbolKind(SymbolKind::Module),
+            ctx.source_range(),
+            name.to_smol_str(),
+        );
+        item.set_documentation(module.docs(ctx.db));
+
+        item.add_to(acc, ctx.db);
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::tests::completion_list_no_kw;
+
+    #[test]
+    fn can_complete_extern_crate() {
+        let case = r#"
+//- /lib.rs crate:other_crate_a
+// nothing here
+//- /other_crate_b.rs crate:other_crate_b
+pub mod good_mod{}
+//- /lib.rs crate:crate_c
+// nothing here
+//- /lib.rs crate:lib deps:other_crate_a,other_crate_b,crate_c extern-prelude:other_crate_a
+extern crate oth$0
+mod other_mod {}
+"#;
+
+        let completion_list = completion_list_no_kw(case);
+
+        assert_eq!("md other_crate_a\n".to_string(), completion_list);
+    }
+
+    #[test]
+    fn will_not_complete_existing_import() {
+        let case = r#"
+//- /lib.rs crate:other_crate_a
+// nothing here
+//- /lib.rs crate:crate_c
+// nothing here
+//- /lib.rs crate:other_crate_b
+//
+//- /lib.rs crate:lib deps:other_crate_a,other_crate_b,crate_c extern-prelude:other_crate_a,other_crate_b
+extern crate other_crate_b;
+extern crate oth$0
+mod other_mod {}
+"#;
+
+        let completion_list = completion_list_no_kw(case);
+
+        assert_eq!("md other_crate_a\n".to_string(), completion_list);
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs
index e4705475638..a30fd13b1d5 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/type.rs
@@ -1,7 +1,7 @@
 //! Completion of names from the current scope in type position.
 
 use hir::{HirDisplay, ScopeDef};
-use syntax::{ast, AstNode, SyntaxKind};
+use syntax::{ast, AstNode};
 
 use crate::{
     context::{PathCompletionCtx, Qualified, TypeAscriptionTarget, TypeLocation},
@@ -20,16 +20,15 @@ pub(crate) fn complete_type_path(
     let scope_def_applicable = |def| {
         use hir::{GenericParam::*, ModuleDef::*};
         match def {
-            ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
+            ScopeDef::GenericParam(LifetimeParam(_)) => location.complete_lifetimes(),
+            ScopeDef::Label(_) => false,
             // no values in type places
             ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_)) | ScopeDef::Local(_) => false,
             // unless its a constant in a generic arg list position
             ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => {
-                matches!(location, TypeLocation::GenericArgList(_))
-            }
-            ScopeDef::ImplSelfType(_) => {
-                !matches!(location, TypeLocation::ImplTarget | TypeLocation::ImplTrait)
+                location.complete_consts()
             }
+            ScopeDef::ImplSelfType(_) => location.complete_self_type(),
             // Don't suggest attribute macros and derives.
             ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
             // Type things are fine
@@ -38,12 +37,12 @@ pub(crate) fn complete_type_path(
             )
             | ScopeDef::AdtSelfType(_)
             | ScopeDef::Unknown
-            | ScopeDef::GenericParam(TypeParam(_)) => true,
+            | ScopeDef::GenericParam(TypeParam(_)) => location.complete_types(),
         }
     };
 
     let add_assoc_item = |acc: &mut Completions, item| match item {
-        hir::AssocItem::Const(ct) if matches!(location, TypeLocation::GenericArgList(_)) => {
+        hir::AssocItem::Const(ct) if matches!(location, TypeLocation::GenericArg { .. }) => {
             acc.add_const(ctx, ct)
         }
         hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => (),
@@ -157,56 +156,30 @@ pub(crate) fn complete_type_path(
                     });
                     return;
                 }
-                TypeLocation::GenericArgList(Some(arg_list)) => {
-                    let in_assoc_type_arg = ctx
-                        .original_token
-                        .parent_ancestors()
-                        .any(|node| node.kind() == SyntaxKind::ASSOC_TYPE_ARG);
-
-                    if !in_assoc_type_arg {
-                        if let Some(path_seg) =
-                            arg_list.syntax().parent().and_then(ast::PathSegment::cast)
-                        {
-                            if path_seg
-                                .syntax()
-                                .ancestors()
-                                .find_map(ast::TypeBound::cast)
-                                .is_some()
-                            {
-                                if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(
-                                    trait_,
-                                ))) = ctx.sema.resolve_path(&path_seg.parent_path())
-                                {
-                                    let arg_idx = arg_list
-                                        .generic_args()
-                                        .filter(|arg| {
-                                            arg.syntax().text_range().end()
-                                                < ctx.original_token.text_range().start()
-                                        })
-                                        .count();
-
-                                    let n_required_params =
-                                        trait_.type_or_const_param_count(ctx.sema.db, true);
-                                    if arg_idx >= n_required_params {
-                                        trait_
-                                            .items_with_supertraits(ctx.sema.db)
-                                            .into_iter()
-                                            .for_each(|it| {
-                                                if let hir::AssocItem::TypeAlias(alias) = it {
-                                                    cov_mark::hit!(
-                                                        complete_assoc_type_in_generics_list
-                                                    );
-                                                    acc.add_type_alias_with_eq(ctx, alias);
-                                                }
-                                            });
-
-                                        let n_params =
-                                            trait_.type_or_const_param_count(ctx.sema.db, false);
-                                        if arg_idx >= n_params {
-                                            return; // only show assoc types
-                                        }
-                                    }
+                TypeLocation::GenericArg {
+                    args: Some(arg_list), of_trait: Some(trait_), ..
+                } => {
+                    if arg_list.syntax().ancestors().find_map(ast::TypeBound::cast).is_some() {
+                        let arg_idx = arg_list
+                            .generic_args()
+                            .filter(|arg| {
+                                arg.syntax().text_range().end()
+                                    < ctx.original_token.text_range().start()
+                            })
+                            .count();
+
+                        let n_required_params = trait_.type_or_const_param_count(ctx.sema.db, true);
+                        if arg_idx >= n_required_params {
+                            trait_.items_with_supertraits(ctx.sema.db).into_iter().for_each(|it| {
+                                if let hir::AssocItem::TypeAlias(alias) = it {
+                                    cov_mark::hit!(complete_assoc_type_in_generics_list);
+                                    acc.add_type_alias_with_eq(ctx, alias);
                                 }
+                            });
+
+                            let n_params = trait_.type_or_const_param_count(ctx.sema.db, false);
+                            if arg_idx >= n_params {
+                                return; // only show assoc types
                             }
                         }
                     }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
index 3cb65b2729a..0da7ba6d000 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -155,13 +155,63 @@ pub(crate) struct ExprCtx {
 pub(crate) enum TypeLocation {
     TupleField,
     TypeAscription(TypeAscriptionTarget),
-    GenericArgList(Option<ast::GenericArgList>),
+    /// Generic argument position e.g. `Foo<$0>`
+    GenericArg {
+        /// The generic argument list containing the generic arg
+        args: Option<ast::GenericArgList>,
+        /// `Some(trait_)` if `trait_` is being instantiated with `args`
+        of_trait: Option<hir::Trait>,
+        /// The generic parameter being filled in by the generic arg
+        corresponding_param: Option<ast::GenericParam>,
+    },
+    /// Associated type equality constraint e.g. `Foo<Bar = $0>`
+    AssocTypeEq,
+    /// Associated constant equality constraint e.g. `Foo<X = $0>`
+    AssocConstEq,
     TypeBound,
     ImplTarget,
     ImplTrait,
     Other,
 }
 
+impl TypeLocation {
+    pub(crate) fn complete_lifetimes(&self) -> bool {
+        matches!(
+            self,
+            TypeLocation::GenericArg {
+                corresponding_param: Some(ast::GenericParam::LifetimeParam(_)),
+                ..
+            }
+        )
+    }
+
+    pub(crate) fn complete_consts(&self) -> bool {
+        match self {
+            TypeLocation::GenericArg {
+                corresponding_param: Some(ast::GenericParam::ConstParam(_)),
+                ..
+            } => true,
+            TypeLocation::AssocConstEq => true,
+            _ => false,
+        }
+    }
+
+    pub(crate) fn complete_types(&self) -> bool {
+        match self {
+            TypeLocation::GenericArg { corresponding_param: Some(param), .. } => {
+                matches!(param, ast::GenericParam::TypeParam(_))
+            }
+            TypeLocation::AssocConstEq => false,
+            TypeLocation::AssocTypeEq => true,
+            _ => true,
+        }
+    }
+
+    pub(crate) fn complete_self_type(&self) -> bool {
+        self.complete_types() && !matches!(self, TypeLocation::ImplTarget | TypeLocation::ImplTrait)
+    }
+}
+
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub(crate) enum TypeAscriptionTarget {
     Let(Option<ast::Pat>),
@@ -301,6 +351,7 @@ pub(super) enum NameRefKind {
         expr: ast::RecordExpr,
     },
     Pattern(PatternContext),
+    ExternCrate,
 }
 
 /// The identifier we are currently completing.
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index 3ea50659030..1e6b2f319aa 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -1,11 +1,11 @@
 //! Module responsible for analyzing the code surrounding the cursor for completion.
 use std::iter;
 
-use hir::{Semantics, Type, TypeInfo, Variant};
+use hir::{HasSource, Semantics, Type, TypeInfo, Variant};
 use ide_db::{active_parameter::ActiveParameter, RootDatabase};
 use syntax::{
     algo::{find_node_at_offset, non_trivia_sibling},
-    ast::{self, AttrKind, HasArgList, HasLoopBody, HasName, NameOrNameRef},
+    ast::{self, AttrKind, HasArgList, HasGenericParams, HasLoopBody, HasName, NameOrNameRef},
     match_ast, AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
     SyntaxToken, TextRange, TextSize, T,
 };
@@ -624,6 +624,10 @@ fn classify_name_ref(
                 });
                 return Some(make_res(kind));
             },
+            ast::ExternCrate(_) => {
+                let kind = NameRefKind::ExternCrate;
+                return Some(make_res(kind));
+            },
             ast::MethodCallExpr(method) => {
                 let receiver = find_opt_node_in_file(original_file, method.receiver());
                 let kind = NameRefKind::DotAccess(DotAccess {
@@ -719,6 +723,136 @@ fn classify_name_ref(
         None
     };
 
+    let generic_arg_location = |arg: ast::GenericArg| {
+        let mut override_location = None;
+        let location = find_opt_node_in_file_compensated(
+            sema,
+            original_file,
+            arg.syntax().parent().and_then(ast::GenericArgList::cast),
+        )
+        .map(|args| {
+            let mut in_trait = None;
+            let param = (|| {
+                let parent = args.syntax().parent()?;
+                let params = match_ast! {
+                    match parent {
+                        ast::PathSegment(segment) => {
+                            match sema.resolve_path(&segment.parent_path().top_path())? {
+                                hir::PathResolution::Def(def) => match def {
+                                    hir::ModuleDef::Function(func) => {
+                                        func.source(sema.db)?.value.generic_param_list()
+                                    }
+                                    hir::ModuleDef::Adt(adt) => {
+                                        adt.source(sema.db)?.value.generic_param_list()
+                                    }
+                                    hir::ModuleDef::Variant(variant) => {
+                                        variant.parent_enum(sema.db).source(sema.db)?.value.generic_param_list()
+                                    }
+                                    hir::ModuleDef::Trait(trait_) => {
+                                        if let ast::GenericArg::AssocTypeArg(arg) = &arg {
+                                            let arg_name = arg.name_ref()?;
+                                            let arg_name = arg_name.text();
+                                            for item in trait_.items_with_supertraits(sema.db) {
+                                                match item {
+                                                    hir::AssocItem::TypeAlias(assoc_ty) => {
+                                                        if assoc_ty.name(sema.db).as_str()? == arg_name {
+                                                            override_location = Some(TypeLocation::AssocTypeEq);
+                                                            return None;
+                                                        }
+                                                    },
+                                                    hir::AssocItem::Const(const_) => {
+                                                        if const_.name(sema.db)?.as_str()? == arg_name {
+                                                            override_location =  Some(TypeLocation::AssocConstEq);
+                                                            return None;
+                                                        }
+                                                    },
+                                                    _ => (),
+                                                }
+                                            }
+                                            return None;
+                                        } else {
+                                            in_trait = Some(trait_);
+                                            trait_.source(sema.db)?.value.generic_param_list()
+                                        }
+                                    }
+                                    hir::ModuleDef::TraitAlias(trait_) => {
+                                        trait_.source(sema.db)?.value.generic_param_list()
+                                    }
+                                    hir::ModuleDef::TypeAlias(ty_) => {
+                                        ty_.source(sema.db)?.value.generic_param_list()
+                                    }
+                                    _ => None,
+                                },
+                                _ => None,
+                            }
+                        },
+                        ast::MethodCallExpr(call) => {
+                            let func = sema.resolve_method_call(&call)?;
+                            func.source(sema.db)?.value.generic_param_list()
+                        },
+                        ast::AssocTypeArg(arg) => {
+                            let trait_ = ast::PathSegment::cast(arg.syntax().parent()?.parent()?)?;
+                            match sema.resolve_path(&trait_.parent_path().top_path())? {
+                                hir::PathResolution::Def(def) => match def {
+                                    hir::ModuleDef::Trait(trait_) => {
+                                        let arg_name = arg.name_ref()?;
+                                        let arg_name = arg_name.text();
+                                        let trait_items = trait_.items_with_supertraits(sema.db);
+                                        let assoc_ty = trait_items.iter().find_map(|item| match item {
+                                            hir::AssocItem::TypeAlias(assoc_ty) => {
+                                                (assoc_ty.name(sema.db).as_str()? == arg_name)
+                                                    .then_some(assoc_ty)
+                                            },
+                                            _ => None,
+                                        })?;
+                                        assoc_ty.source(sema.db)?.value.generic_param_list()
+                                    }
+                                    _ => None,
+                                },
+                                _ => None,
+                            }
+                        },
+                        _ => None,
+                    }
+                }?;
+                // Determine the index of the argument in the `GenericArgList` and match it with
+                // the corresponding parameter in the `GenericParamList`. Since lifetime parameters
+                // are often omitted, ignore them for the purposes of matching the argument with
+                // its parameter unless a lifetime argument is provided explicitly. That is, for
+                // `struct S<'a, 'b, T>`, match `S::<$0>` to `T` and `S::<'a, $0, _>` to `'b`.
+                // FIXME: This operates on the syntax tree and will produce incorrect results when
+                // generic parameters are disabled by `#[cfg]` directives. It should operate on the
+                // HIR, but the functionality necessary to do so is not exposed at the moment.
+                let mut explicit_lifetime_arg = false;
+                let arg_idx = arg
+                    .syntax()
+                    .siblings(Direction::Prev)
+                    // Skip the node itself
+                    .skip(1)
+                    .map(|arg| if ast::LifetimeArg::can_cast(arg.kind()) { explicit_lifetime_arg = true })
+                    .count();
+                let param_idx = if explicit_lifetime_arg {
+                    arg_idx
+                } else {
+                    // Lifetimes parameters always precede type and generic parameters,
+                    // so offset the argument index by the total number of lifetime params
+                    arg_idx + params.lifetime_params().count()
+                };
+                params.generic_params().nth(param_idx)
+            })();
+            (args, in_trait, param)
+        });
+        let (arg_list, of_trait, corresponding_param) = match location {
+            Some((arg_list, of_trait, param)) => (Some(arg_list), of_trait, param),
+            _ => (None, None, None),
+        };
+        override_location.unwrap_or(TypeLocation::GenericArg {
+            args: arg_list,
+            of_trait,
+            corresponding_param,
+        })
+    };
+
     let type_location = |node: &SyntaxNode| {
         let parent = node.parent()?;
         let res = match_ast! {
@@ -774,9 +908,12 @@ fn classify_name_ref(
                 ast::TypeBound(_) => TypeLocation::TypeBound,
                 // is this case needed?
                 ast::TypeBoundList(_) => TypeLocation::TypeBound,
-                ast::GenericArg(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, it.syntax().parent().and_then(ast::GenericArgList::cast))),
+                ast::GenericArg(it) => generic_arg_location(it),
                 // is this case needed?
-                ast::GenericArgList(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, Some(it))),
+                ast::GenericArgList(it) => {
+                    let args = find_opt_node_in_file_compensated(sema, original_file, Some(it));
+                    TypeLocation::GenericArg { args, of_trait: None, corresponding_param: None }
+                },
                 ast::TupleField(_) => TypeLocation::TupleField,
                 _ => return None,
             }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
index 8c038c0fbaa..4cdfd546f6a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs
@@ -1286,3 +1286,57 @@ macro_rules! println {
         expect![""],
     )
 }
+
+#[test]
+fn no_completions_for_external_doc_hidden_in_path() {
+    check(
+        r#"
+//- /main.rs crate:main deps:dep
+fn main() {
+    Span$0
+}
+//- /lib.rs crate:dep
+#[doc(hidden)]
+pub mod bridge {
+    pub mod server {
+        pub trait Span
+    }
+}
+pub mod bridge2 {
+    #[doc(hidden)]
+    pub mod server2 {
+        pub trait Span
+    }
+}
+"#,
+        expect![""],
+    );
+    // unless re-exported
+    check(
+        r#"
+//- /main.rs crate:main deps:dep
+fn main() {
+    Span$0
+}
+//- /lib.rs crate:dep
+#[doc(hidden)]
+pub mod bridge {
+    pub mod server {
+        pub trait Span
+    }
+}
+pub use bridge::server::Span;
+pub mod bridge2 {
+    #[doc(hidden)]
+    pub mod server2 {
+        pub trait Span2
+    }
+}
+pub use bridge2::server2::Span2;
+"#,
+        expect![[r#"
+            tt Span (use dep::Span)
+            tt Span2 (use dep::Span2)
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
index 8cb1ff4a125..d518dd76410 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/type_pos.rs
@@ -384,10 +384,8 @@ trait Trait2<T>: Trait1 {
 fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
 "#,
         expect![[r#"
-            ct CONST
-            cp CONST_PARAM
             en Enum
-            ma makro!(…)   macro_rules! makro
+            ma makro!(…) macro_rules! makro
             md module
             st Record
             st Tuple
@@ -404,14 +402,13 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
     );
     check(
         r#"
-trait Trait2 {
+trait Trait2<T> {
     type Foo;
 }
 
 fn foo<'lt, T: Trait2<self::$0>, const CONST_PARAM: usize>(_: T) {}
     "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…) macro_rules! makro
             md module
@@ -437,7 +434,6 @@ trait Tr<T> {
 impl Tr<$0
     "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…) macro_rules! makro
             md module
@@ -485,7 +481,6 @@ trait MyTrait<T, U> {
 fn f(t: impl MyTrait<u$0
 "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…) macro_rules! makro
             md module
@@ -511,7 +506,6 @@ trait MyTrait<T, U> {
 fn f(t: impl MyTrait<u8, u$0
 "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…) macro_rules! makro
             md module
@@ -555,7 +549,6 @@ trait MyTrait<T, U = u8> {
 fn f(t: impl MyTrait<u$0
 "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…) macro_rules! makro
             md module
@@ -581,7 +574,6 @@ trait MyTrait<T, U = u8> {
 fn f(t: impl MyTrait<u8, u$0
 "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…)             macro_rules! makro
             md module
@@ -627,7 +619,6 @@ trait MyTrait {
 fn f(t: impl MyTrait<Item1 = $0
 "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…) macro_rules! makro
             md module
@@ -653,7 +644,6 @@ trait MyTrait {
 fn f(t: impl MyTrait<Item1 = u8, Item2 = $0
 "#,
         expect![[r#"
-            ct CONST
             en Enum
             ma makro!(…) macro_rules! makro
             md module
@@ -668,6 +658,22 @@ fn f(t: impl MyTrait<Item1 = u8, Item2 = $0
             kw self::
         "#]],
     );
+
+    check(
+        r#"
+trait MyTrait {
+    const C: usize;
+};
+
+fn f(t: impl MyTrait<C = $0
+"#,
+        expect![[r#"
+            ct CONST
+            ma makro!(…) macro_rules! makro
+            kw crate::
+            kw self::
+        "#]],
+    );
 }
 
 #[test]
@@ -719,3 +725,267 @@ pub struct S;
         "#]],
     )
 }
+
+#[test]
+fn completes_const_and_type_generics_separately() {
+    // Function generic params
+    check(
+        r#"
+    struct Foo;
+    const X: usize = 0;
+    fn foo<T, const N: usize>() {}
+    fn main() {
+        foo::<F$0, _>();
+    }
+            "#,
+        expect![[r#"
+                en Enum
+                ma makro!(…) macro_rules! makro
+                md module
+                st Foo
+                st Record
+                st Tuple
+                st Unit
+                tt Trait
+                un Union
+                bt u32
+                kw crate::
+                kw self::
+            "#]],
+    );
+    // FIXME: This should probably also suggest completions for types, at least those that have
+    // associated constants usable in this position. For example, a user could be typing
+    // `foo::<_, { usize::MAX }>()`, but we currently don't suggest `usize` in constant position.
+    check(
+        r#"
+    struct Foo;
+    const X: usize = 0;
+    fn foo<T, const N: usize>() {}
+    fn main() {
+        foo::<_, $0>();
+    }
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Method generic params
+    check(
+        r#"
+    const X: usize = 0;
+    struct Foo;
+    impl Foo { fn bar<const N: usize, T>(self) {} }
+    fn main() {
+        Foo.bar::<_, $0>();
+    }
+            "#,
+        expect![[r#"
+                en Enum
+                ma makro!(…) macro_rules! makro
+                md module
+                st Foo
+                st Record
+                st Tuple
+                st Unit
+                tt Trait
+                un Union
+                bt u32
+                kw crate::
+                kw self::
+            "#]],
+    );
+    check(
+        r#"
+    const X: usize = 0;
+    struct Foo;
+    impl Foo { fn bar<const N: usize, T>(self) {} }
+    fn main() {
+        Foo.bar::<X$0, _>();
+    }
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Associated type generic params
+    check(
+        r#"
+    const X: usize = 0;
+    struct Foo;
+    trait Bar {
+        type Baz<T, const X: usize>;
+    }
+    fn foo(_: impl Bar<Baz<F$0, 0> = ()>) {}
+            "#,
+        expect![[r#"
+                en Enum
+                ma makro!(…) macro_rules! makro
+                md module
+                st Foo
+                st Record
+                st Tuple
+                st Unit
+                tt Bar
+                tt Trait
+                un Union
+                bt u32
+                kw crate::
+                kw self::
+            "#]],
+    );
+    check(
+        r#"
+    const X: usize = 0;
+    struct Foo;
+    trait Bar {
+        type Baz<T, const X: usize>;
+    }
+    fn foo<T: Bar<Baz<(), $0> = ()>>() {}
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Type generic params
+    check(
+        r#"
+    const X: usize = 0;
+    struct Foo<T, const N: usize>(T);
+    fn main() {
+        let _: Foo::<_, $0> = Foo(());
+    }
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Type alias generic params
+    check(
+        r#"
+    const X: usize = 0;
+    struct Foo<T, const N: usize>(T);
+    type Bar<const X: usize, U> = Foo<U, X>;
+    fn main() {
+        let _: Bar::<X$0, _> = Bar(());
+    }
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Enum variant params
+    check(
+        r#"
+    const X: usize = 0;
+    enum Foo<T, const N: usize> { A(T), B }
+    fn main() {
+        Foo::B::<(), $0>;
+    }
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Trait params
+    check(
+        r#"
+    const X: usize = 0;
+    trait Foo<T, const N: usize> {}
+    impl Foo<(), $0> for () {}
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Trait alias params
+    check(
+        r#"
+    #![feature(trait_alias)]
+    const X: usize = 0;
+    trait Foo<T, const N: usize> {}
+    trait Bar<const M: usize, U> = Foo<U, M>;
+    fn foo<T: Bar<X$0, ()>>() {}
+            "#,
+        expect![[r#"
+                ct CONST
+                ct X
+                ma makro!(…) macro_rules! makro
+                kw crate::
+                kw self::
+            "#]],
+    );
+
+    // Omitted lifetime params
+    check(
+        r#"
+struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
+fn foo<'a>() { S::<F$0, _>; }
+        "#,
+        expect![[r#"
+            ct CONST
+            ma makro!(…) macro_rules! makro
+            kw crate::
+            kw self::
+        "#]],
+    );
+    // Explicit lifetime params
+    check(
+        r#"
+struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
+fn foo<'a>() { S::<'static, 'static, F$0, _>; }
+        "#,
+        expect![[r#"
+            ct CONST
+            ma makro!(…) macro_rules! makro
+            kw crate::
+            kw self::
+        "#]],
+    );
+    check(
+        r#"
+struct S<'a, 'b, const C: usize, T>(core::marker::PhantomData<&'a &'b T>);
+fn foo<'a>() { S::<'static, F$0, _, _>; }
+        "#,
+        expect![[r#"
+            lt 'a
+            ma makro!(…) macro_rules! makro
+            kw crate::
+            kw self::
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
index 5e4562d9c58..4ce80532e8e 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -7,7 +7,7 @@
 
 use arrayvec::ArrayVec;
 use hir::{
-    Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper,
+    Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, DocLinkDef,
     ExternCrateDecl, Field, Function, GenericParam, HasVisibility, Impl, Label, Local, Macro,
     Module, ModuleDef, Name, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias,
     TypeAlias, Variant, Visibility,
@@ -649,3 +649,13 @@ impl From<ModuleDef> for Definition {
         }
     }
 }
+
+impl From<DocLinkDef> for Definition {
+    fn from(def: DocLinkDef) -> Self {
+        match def {
+            DocLinkDef::ModuleDef(it) => it.into(),
+            DocLinkDef::Field(it) => it.into(),
+            DocLinkDef::SelfType(it) => it.into(),
+        }
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
index 1eb8f00020b..330af442f75 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/helpers.rs
@@ -117,7 +117,7 @@ pub fn get_definition(
     sema: &Semantics<'_, RootDatabase>,
     token: SyntaxToken,
 ) -> Option<Definition> {
-    for token in sema.descend_into_macros(token) {
+    for token in sema.descend_into_macros(token, 0.into()) {
         let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops);
         if let Some(&[x]) = def.as_deref() {
             return Some(x);
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
index e52dc356775..e475c5cd66b 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs
@@ -6,7 +6,7 @@ use hir::{
 use itertools::Itertools;
 use rustc_hash::FxHashSet;
 use syntax::{
-    ast::{self, HasName},
+    ast::{self, make, HasName},
     utils::path_to_string_stripping_turbo_fish,
     AstNode, SyntaxNode,
 };
@@ -607,7 +607,7 @@ impl ImportCandidate {
     fn for_name(sema: &Semantics<'_, RootDatabase>, name: &ast::Name) -> Option<Self> {
         if sema
             .scope(name.syntax())?
-            .speculative_resolve(&ast::make::ext::ident_path(&name.text()))
+            .speculative_resolve(&make::ext::ident_path(&name.text()))
             .is_some()
         {
             return None;
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index f27ed485d81..ac3511ba47b 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -94,18 +94,21 @@ impl fmt::Debug for RootDatabase {
 }
 
 impl Upcast<dyn ExpandDatabase> for RootDatabase {
+    #[inline]
     fn upcast(&self) -> &(dyn ExpandDatabase + 'static) {
         &*self
     }
 }
 
 impl Upcast<dyn DefDatabase> for RootDatabase {
+    #[inline]
     fn upcast(&self) -> &(dyn DefDatabase + 'static) {
         &*self
     }
 }
 
 impl Upcast<dyn HirDatabase> for RootDatabase {
+    #[inline]
     fn upcast(&self) -> &(dyn HirDatabase + 'static) {
         &*self
     }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
index 1d0cb426a57..fb75b5b4584 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -5,7 +5,7 @@ use either::Either;
 use hir::{AsAssocItem, HirDisplay, SemanticsScope};
 use rustc_hash::FxHashMap;
 use syntax::{
-    ast::{self, AstNode},
+    ast::{self, make, AstNode},
     ted, SyntaxNode,
 };
 
@@ -21,6 +21,7 @@ enum TypeOrConst {
 }
 
 type LifetimeName = String;
+type DefaultedParam = Either<hir::TypeParam, hir::ConstParam>;
 
 /// `PathTransform` substitutes path in SyntaxNodes in bulk.
 ///
@@ -115,7 +116,7 @@ impl<'a> PathTransform<'a> {
         };
         let mut type_substs: FxHashMap<hir::TypeParam, ast::Type> = Default::default();
         let mut const_substs: FxHashMap<hir::ConstParam, SyntaxNode> = Default::default();
-        let mut default_types: Vec<hir::TypeParam> = Default::default();
+        let mut defaulted_params: Vec<DefaultedParam> = Default::default();
         self.generic_def
             .into_iter()
             .flat_map(|it| it.type_params(db))
@@ -138,8 +139,8 @@ impl<'a> PathTransform<'a> {
                         if let Some(default) =
                             &default.display_source_code(db, source_module.into(), false).ok()
                         {
-                            type_substs.insert(k, ast::make::ty(default).clone_for_update());
-                            default_types.push(k);
+                            type_substs.insert(k, make::ty(default).clone_for_update());
+                            defaulted_params.push(Either::Left(k));
                         }
                     }
                 }
@@ -155,11 +156,19 @@ impl<'a> PathTransform<'a> {
                         // is a standalone statement or a part of another expresson)
                         // and sometimes require slight modifications; see
                         // https://doc.rust-lang.org/reference/statements.html#expression-statements
+                        // (default values in curly brackets can cause the same problem)
                         const_substs.insert(k, expr.syntax().clone());
                     }
                 }
-                (Either::Left(_), None) => (), // FIXME: get default const value
-                _ => (),                       // ignore mismatching params
+                (Either::Left(k), None) => {
+                    if let Some(default) = k.default(db) {
+                        if let Some(default) = default.expr() {
+                            const_substs.insert(k, default.syntax().clone_for_update());
+                            defaulted_params.push(Either::Right(k));
+                        }
+                    }
+                }
+                _ => (), // ignore mismatching params
             });
         let lifetime_substs: FxHashMap<_, _> = self
             .generic_def
@@ -175,7 +184,7 @@ impl<'a> PathTransform<'a> {
             target_module,
             source_scope: self.source_scope,
         };
-        ctx.transform_default_type_substs(default_types);
+        ctx.transform_default_values(defaulted_params);
         ctx
     }
 }
@@ -212,13 +221,19 @@ impl Ctx<'_> {
         });
     }
 
-    fn transform_default_type_substs(&self, default_types: Vec<hir::TypeParam>) {
-        for k in default_types {
-            let v = self.type_substs.get(&k).unwrap();
+    fn transform_default_values(&self, defaulted_params: Vec<DefaultedParam>) {
+        // By now the default values are simply copied from where they are declared
+        // and should be transformed. As any value is allowed to refer to previous
+        // generic (both type and const) parameters, they should be all iterated left-to-right.
+        for param in defaulted_params {
+            let value = match param {
+                Either::Left(k) => self.type_substs.get(&k).unwrap().syntax(),
+                Either::Right(k) => self.const_substs.get(&k).unwrap(),
+            };
             // `transform_path` may update a node's parent and that would break the
             // tree traversal. Thus all paths in the tree are collected into a vec
             // so that such operation is safe.
-            let paths = postorder(&v.syntax()).filter_map(ast::Path::cast).collect::<Vec<_>>();
+            let paths = postorder(value).filter_map(ast::Path::cast).collect::<Vec<_>>();
             for path in paths {
                 self.transform_path(path);
             }
@@ -263,15 +278,14 @@ impl Ctx<'_> {
                                 hir::ModuleDef::Trait(trait_ref),
                                 false,
                             )?;
-                            match ast::make::ty_path(mod_path_to_ast(&found_path)) {
+                            match make::ty_path(mod_path_to_ast(&found_path)) {
                                 ast::Type::PathType(path_ty) => Some(path_ty),
                                 _ => None,
                             }
                         });
 
-                        let segment = ast::make::path_segment_ty(subst.clone(), trait_ref);
-                        let qualified =
-                            ast::make::path_from_segments(std::iter::once(segment), false);
+                        let segment = make::path_segment_ty(subst.clone(), trait_ref);
+                        let qualified = make::path_from_segments(std::iter::once(segment), false);
                         ted::replace(path.syntax(), qualified.clone_for_update().syntax());
                     } else if let Some(path_ty) = ast::PathType::cast(parent) {
                         ted::replace(
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index d5abd099126..7e00d368652 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -456,14 +456,14 @@ impl<'a> FindUsages<'a> {
                     it.text().trim_start_matches("r#") == name
                 })
                 .into_iter()
-                .flat_map(|token| {
+                .flat_map(move |token| {
                     // FIXME: There should be optimization potential here
                     // Currently we try to descend everything we find which
                     // means we call `Semantics::descend_into_macros` on
                     // every textual hit. That function is notoriously
                     // expensive even for things that do not get down mapped
                     // into macros.
-                    sema.descend_into_macros(token).into_iter().filter_map(|it| it.parent())
+                    sema.descend_into_macros(token, offset).into_iter().filter_map(|it| it.parent())
                 })
         };
 
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
index b54c43b296b..f699f999baf 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/symbol_index.rs
@@ -323,6 +323,8 @@ impl Query {
                             hir::ModuleDef::Adt(..)
                                 | hir::ModuleDef::TypeAlias(..)
                                 | hir::ModuleDef::BuiltinType(..)
+                                | hir::ModuleDef::TraitAlias(..)
+                                | hir::ModuleDef::Trait(..)
                         )
                     {
                         continue;
@@ -417,9 +419,16 @@ const CONST_WITH_INNER: () = {
 
 mod b_mod;
 
+
+use define_struct as really_define_struct;
+use Macro as ItemLikeMacro;
+use Macro as Trait; // overlay namespaces
 //- /b_mod.rs
 struct StructInModB;
-        "#,
+use super::Macro as SuperItemLikeMacro;
+use crate::b_mod::StructInModB as ThisStruct;
+use crate::Trait as IsThisJustATrait;
+"#,
         );
 
         let symbols: Vec<_> = Crate::from(db.test_crate())
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
index 1a00e29384e..87ad5844c64 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
+++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
@@ -119,6 +119,35 @@
                 is_alias: false,
             },
             FileSymbol {
+                name: "ItemLikeMacro",
+                def: Macro(
+                    Macro {
+                        id: Macro2Id(
+                            Macro2Id(
+                                0,
+                            ),
+                        ),
+                    },
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: FileId(
+                        FileId(
+                            0,
+                        ),
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 654..676,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 663..676,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
                 name: "Macro",
                 def: Macro(
                     Macro {
@@ -353,6 +382,35 @@
                 is_alias: false,
             },
             FileSymbol {
+                name: "Trait",
+                def: Macro(
+                    Macro {
+                        id: Macro2Id(
+                            Macro2Id(
+                                0,
+                            ),
+                        ),
+                    },
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: FileId(
+                        FileId(
+                            0,
+                        ),
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 682..696,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 691..696,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
                 name: "Union",
                 def: Adt(
                     Union(
@@ -552,6 +610,35 @@
                 is_alias: false,
             },
             FileSymbol {
+                name: "really_define_struct",
+                def: Macro(
+                    Macro {
+                        id: MacroRulesId(
+                            MacroRulesId(
+                                1,
+                            ),
+                        ),
+                    },
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: FileId(
+                        FileId(
+                            0,
+                        ),
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 611..648,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 628..648,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
                 name: "trait_fn",
                 def: Function(
                     Function {
@@ -632,6 +719,35 @@
         },
         [
             FileSymbol {
+                name: "IsThisJustATrait",
+                def: Macro(
+                    Macro {
+                        id: Macro2Id(
+                            Macro2Id(
+                                0,
+                            ),
+                        ),
+                    },
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: FileId(
+                        FileId(
+                            1,
+                        ),
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 111..143,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 127..143,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
                 name: "StructInModB",
                 def: Adt(
                     Struct(
@@ -660,6 +776,93 @@
                 container_name: None,
                 is_alias: false,
             },
+            FileSymbol {
+                name: "SuperItemLikeMacro",
+                def: Macro(
+                    Macro {
+                        id: Macro2Id(
+                            Macro2Id(
+                                0,
+                            ),
+                        ),
+                    },
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: FileId(
+                        FileId(
+                            1,
+                        ),
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 25..59,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 41..59,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
+                name: "ThisStruct",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                3,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: FileId(
+                        FileId(
+                            1,
+                        ),
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 65..105,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 95..105,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
+                name: "ThisStruct",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                3,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: FileId(
+                        FileId(
+                            1,
+                        ),
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 65..105,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 95..105,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
         ],
     ),
 ]
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
index f96ea29ae2f..a915391ad90 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/use_trivial_constructor.rs
@@ -1,31 +1,29 @@
 //! Functionality for generating trivial constructors
 
 use hir::StructKind;
-use syntax::ast;
+use syntax::ast::{make, Expr, Path};
 
 /// given a type return the trivial constructor (if one exists)
 pub fn use_trivial_constructor(
     db: &crate::RootDatabase,
-    path: ast::Path,
+    path: Path,
     ty: &hir::Type,
-) -> Option<ast::Expr> {
+) -> Option<Expr> {
     match ty.as_adt() {
         Some(hir::Adt::Enum(x)) => {
             if let &[variant] = &*x.variants(db) {
                 if variant.kind(db) == hir::StructKind::Unit {
-                    let path = ast::make::path_qualified(
+                    let path = make::path_qualified(
                         path,
-                        syntax::ast::make::path_segment(ast::make::name_ref(
-                            &variant.name(db).to_smol_str(),
-                        )),
+                        make::path_segment(make::name_ref(&variant.name(db).to_smol_str())),
                     );
 
-                    return Some(syntax::ast::make::expr_path(path));
+                    return Some(make::expr_path(path));
                 }
             }
         }
         Some(hir::Adt::Struct(x)) if x.kind(db) == StructKind::Unit => {
-            return Some(syntax::ast::make::expr_path(path));
+            return Some(make::expr_path(path));
         }
         _ => {}
     }
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
index a8e88369088..60fcbbbd397 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
+++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs
@@ -560,8 +560,10 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
                         placeholder_value.autoref_kind = self
                             .sema
                             .resolve_method_call_as_callable(code)
-                            .and_then(|callable| callable.receiver_param(self.sema.db))
-                            .map(|(self_param, _)| self_param.kind())
+                            .and_then(|callable| {
+                                let (self_param, _) = callable.receiver_param(self.sema.db)?;
+                                Some(self_param.source(self.sema.db)?.value.kind())
+                            })
                             .unwrap_or(ast::SelfParamKind::Owned);
                     }
                 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
index dd1d0d75c63..f834f2ce592 100644
--- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs
@@ -74,18 +74,20 @@ pub(crate) fn incoming_calls(
     Some(calls.into_items())
 }
 
-pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> {
+pub(crate) fn outgoing_calls(
+    db: &RootDatabase,
+    FilePosition { file_id, offset }: FilePosition,
+) -> Option<Vec<CallItem>> {
     let sema = Semantics::new(db);
-    let file_id = position.file_id;
     let file = sema.parse(file_id);
     let file = file.syntax();
-    let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
+    let token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
         IDENT => 1,
         _ => 0,
     })?;
     let mut calls = CallLocations::default();
 
-    sema.descend_into_macros(token)
+    sema.descend_into_macros(token, offset)
         .into_iter()
         .filter_map(|it| it.parent_ancestors().nth(1).and_then(ast::Item::cast))
         .filter_map(|item| match item {
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
index d240127f376..901f7a2a79a 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -131,19 +131,19 @@ pub(crate) fn remove_links(markdown: &str) -> String {
 // |===
 pub(crate) fn external_docs(
     db: &RootDatabase,
-    position: &FilePosition,
+    FilePosition { file_id, offset }: FilePosition,
     target_dir: Option<&OsStr>,
     sysroot: Option<&OsStr>,
 ) -> Option<DocumentationLinks> {
     let sema = &Semantics::new(db);
-    let file = sema.parse(position.file_id).syntax().clone();
-    let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
+    let file = sema.parse(file_id).syntax().clone();
+    let token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
         IDENT | INT_NUMBER | T![self] => 3,
         T!['('] | T![')'] => 2,
         kind if kind.is_trivia() => 0,
         _ => 1,
     })?;
-    let token = sema.descend_into_macros_single(token);
+    let token = sema.descend_into_macros_single(token, offset);
 
     let node = token.parent()?;
     let definition = match_ast! {
@@ -285,7 +285,7 @@ impl DocCommentToken {
         let original_start = doc_token.text_range().start();
         let relative_comment_offset = offset - original_start - prefix_len;
 
-        sema.descend_into_macros(doc_token).into_iter().find_map(|t| {
+        sema.descend_into_macros(doc_token, offset).into_iter().find_map(|t| {
             let (node, descended_prefix_len) = match_ast! {
                 match t {
                     ast::Comment(comment) => (t.parent()?, TextSize::try_from(comment.prefix().len()).ok()?),
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
index 05a64b33bfd..8036c77072b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
@@ -518,6 +518,62 @@ fn function();
 }
 
 #[test]
+fn doc_links_field() {
+    check_doc_links(
+        r#"
+/// [`S::f`]
+/// [`S2::f`]
+/// [`T::0`]
+/// [`U::a`]
+/// [`E::A::f`]
+/// [`E::B::0`]
+struct S$0 {
+    f: i32,
+  //^ S::f
+  //^ S2::f
+}
+type S2 = S;
+struct T(i32);
+       //^^^ T::0
+union U {
+    a: i32,
+  //^ U::a
+}
+enum E {
+    A { f: i32 },
+      //^ E::A::f
+    B(i32),
+    //^^^ E::B::0
+}
+"#,
+    );
+}
+
+#[test]
+fn doc_links_field_via_self() {
+    check_doc_links(
+        r#"
+/// [`Self::f`]
+struct S$0 {
+    f: i32,
+  //^ Self::f
+}
+"#,
+    );
+}
+
+#[test]
+fn doc_links_tuple_field_via_self() {
+    check_doc_links(
+        r#"
+/// [`Self::0`]
+struct S$0(i32);
+       //^^^ Self::0
+"#,
+    );
+}
+
+#[test]
 fn rewrite_html_root_url() {
     check_rewrite(
         r#"
diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
index d6bbf2bf794..119a9c7c3f4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs
@@ -40,28 +40,33 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
     // struct Bar;
     // ```
 
-    let derive = sema.descend_into_macros(tok.clone()).into_iter().find_map(|descended| {
-        let hir_file = sema.hir_file_for(&descended.parent()?);
-        if !hir_file.is_derive_attr_pseudo_expansion(db) {
-            return None;
-        }
+    let derive =
+        sema.descend_into_macros(tok.clone(), 0.into()).into_iter().find_map(|descended| {
+            let hir_file = sema.hir_file_for(&descended.parent()?);
+            if !hir_file.is_derive_attr_pseudo_expansion(db) {
+                return None;
+            }
 
-        let name = descended.parent_ancestors().filter_map(ast::Path::cast).last()?.to_string();
-        // up map out of the #[derive] expansion
-        let token = hir::InFile::new(hir_file, descended).upmap(db)?.value;
-        let attr = token.parent_ancestors().find_map(ast::Attr::cast)?;
-        let expansions = sema.expand_derive_macro(&attr)?;
-        let idx = attr
-            .token_tree()?
-            .token_trees_and_tokens()
-            .filter_map(NodeOrToken::into_token)
-            .take_while(|it| it != &token)
-            .filter(|it| it.kind() == T![,])
-            .count();
-        let expansion =
-            format(db, SyntaxKind::MACRO_ITEMS, position.file_id, expansions.get(idx).cloned()?);
-        Some(ExpandedMacro { name, expansion })
-    });
+            let name = descended.parent_ancestors().filter_map(ast::Path::cast).last()?.to_string();
+            // up map out of the #[derive] expansion
+            let token = hir::InFile::new(hir_file, descended).upmap(db)?.value;
+            let attr = token.parent_ancestors().find_map(ast::Attr::cast)?;
+            let expansions = sema.expand_derive_macro(&attr)?;
+            let idx = attr
+                .token_tree()?
+                .token_trees_and_tokens()
+                .filter_map(NodeOrToken::into_token)
+                .take_while(|it| it != &token)
+                .filter(|it| it.kind() == T![,])
+                .count();
+            let expansion = format(
+                db,
+                SyntaxKind::MACRO_ITEMS,
+                position.file_id,
+                expansions.get(idx).cloned()?,
+            );
+            Some(ExpandedMacro { name, expansion })
+        });
 
     if derive.is_some() {
         return derive;
diff --git a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
index f9061822244..3d89599c583 100644
--- a/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/extend_selection.rs
@@ -17,8 +17,6 @@ use crate::FileRange;
 // Extends or shrinks the current selection to the encompassing syntactic construct
 // (expression, statement, item, module, etc). It works with multiple cursors.
 //
-// This is a standard LSP feature and not a protocol extension.
-//
 // |===
 // | Editor  | Shortcut
 //
@@ -142,8 +140,10 @@ fn extend_tokens_from_range(
 
     // compute original mapped token range
     let extended = {
-        let fst_expanded = sema.descend_into_macros_single(first_token.clone());
-        let lst_expanded = sema.descend_into_macros_single(last_token.clone());
+        let fst_expanded =
+            sema.descend_into_macros_single(first_token.clone(), original_range.start());
+        let lst_expanded =
+            sema.descend_into_macros_single(last_token.clone(), original_range.end());
         let mut lca =
             algo::least_common_ancestor(&fst_expanded.parent()?, &lst_expanded.parent()?)?;
         lca = shallowest_node(&lca);
@@ -154,13 +154,16 @@ fn extend_tokens_from_range(
     };
 
     // Compute parent node range
-    let validate = |token: &SyntaxToken| -> bool {
-        let expanded = sema.descend_into_macros_single(token.clone());
-        let parent = match expanded.parent() {
-            Some(it) => it,
-            None => return false,
-        };
-        algo::least_common_ancestor(&extended, &parent).as_ref() == Some(&extended)
+    let validate = |offset: TextSize| {
+        let extended = &extended;
+        move |token: &SyntaxToken| -> bool {
+            let expanded = sema.descend_into_macros_single(token.clone(), offset);
+            let parent = match expanded.parent() {
+                Some(it) => it,
+                None => return false,
+            };
+            algo::least_common_ancestor(extended, &parent).as_ref() == Some(extended)
+        }
     };
 
     // Find the first and last text range under expanded parent
@@ -168,14 +171,14 @@ fn extend_tokens_from_range(
         let token = token.prev_token()?;
         skip_trivia_token(token, Direction::Prev)
     })
-    .take_while(validate)
+    .take_while(validate(original_range.start()))
     .last()?;
 
     let last = successors(Some(last_token), |token| {
         let token = token.next_token()?;
         skip_trivia_token(token, Direction::Next)
     })
-    .take_while(validate)
+    .take_while(validate(original_range.end()))
     .last()?;
 
     let range = first.text_range().cover(last.text_range());
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs
index c39c696cfd9..7e0fab42608 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_declaration.rs
@@ -20,16 +20,16 @@ use crate::{
 // - fields in patterns will navigate to the field declaration of the struct, union or variant
 pub(crate) fn goto_declaration(
     db: &RootDatabase,
-    position: FilePosition,
+    position @ FilePosition { file_id, offset }: FilePosition,
 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
     let sema = Semantics::new(db);
-    let file = sema.parse(position.file_id).syntax().clone();
+    let file = sema.parse(file_id).syntax().clone();
     let original_token = file
-        .token_at_offset(position.offset)
+        .token_at_offset(offset)
         .find(|it| matches!(it.kind(), IDENT | T![self] | T![super] | T![crate] | T![Self]))?;
     let range = original_token.text_range();
     let info: Vec<NavigationTarget> = sema
-        .descend_into_macros(original_token)
+        .descend_into_macros(original_token, offset)
         .iter()
         .filter_map(|token| {
             let parent = token.parent()?;
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index 21471ab2a03..e09b9f39148 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -29,45 +29,39 @@ use syntax::{ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T};
 // image::https://user-images.githubusercontent.com/48062697/113065563-025fbe00-91b1-11eb-83e4-a5a703610b23.gif[]
 pub(crate) fn goto_definition(
     db: &RootDatabase,
-    position: FilePosition,
+    FilePosition { file_id, offset }: FilePosition,
 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
     let sema = &Semantics::new(db);
-    let file = sema.parse(position.file_id).syntax().clone();
-    let original_token =
-        pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
-            IDENT
-            | INT_NUMBER
-            | LIFETIME_IDENT
-            | T![self]
-            | T![super]
-            | T![crate]
-            | T![Self]
-            | COMMENT => 4,
-            // index and prefix ops
-            T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
-            kind if kind.is_keyword() => 2,
-            T!['('] | T![')'] => 2,
-            kind if kind.is_trivia() => 0,
-            _ => 1,
-        })?;
+    let file = sema.parse(file_id).syntax().clone();
+    let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
+        IDENT
+        | INT_NUMBER
+        | LIFETIME_IDENT
+        | T![self]
+        | T![super]
+        | T![crate]
+        | T![Self]
+        | COMMENT => 4,
+        // index and prefix ops
+        T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
+        kind if kind.is_keyword() => 2,
+        T!['('] | T![')'] => 2,
+        kind if kind.is_trivia() => 0,
+        _ => 1,
+    })?;
     if let Some(doc_comment) = token_as_doc_comment(&original_token) {
-        return doc_comment.get_definition_with_descend_at(
-            sema,
-            position.offset,
-            |def, _, link_range| {
-                let nav = def.try_to_nav(db)?;
-                Some(RangeInfo::new(link_range, vec![nav]))
-            },
-        );
+        return doc_comment.get_definition_with_descend_at(sema, offset, |def, _, link_range| {
+            let nav = def.try_to_nav(db)?;
+            Some(RangeInfo::new(link_range, vec![nav]))
+        });
     }
     let navs = sema
-        .descend_into_macros(original_token.clone())
+        .descend_into_macros(original_token.clone(), offset)
         .into_iter()
         .filter_map(|token| {
             let parent = token.parent()?;
             if let Some(tt) = ast::TokenTree::cast(parent) {
-                if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), position.file_id)
-                {
+                if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), file_id) {
                     return Some(vec![x]);
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
index 37166bdbd0c..544c6b42317 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_implementation.rs
@@ -22,20 +22,19 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav};
 // image::https://user-images.githubusercontent.com/48062697/113065566-02f85480-91b1-11eb-9288-aaad8abd8841.gif[]
 pub(crate) fn goto_implementation(
     db: &RootDatabase,
-    position: FilePosition,
+    FilePosition { file_id, offset }: FilePosition,
 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
     let sema = Semantics::new(db);
-    let source_file = sema.parse(position.file_id);
+    let source_file = sema.parse(file_id);
     let syntax = source_file.syntax().clone();
 
-    let original_token =
-        pick_best_token(syntax.token_at_offset(position.offset), |kind| match kind {
-            IDENT | T![self] | INT_NUMBER => 1,
-            _ => 0,
-        })?;
+    let original_token = pick_best_token(syntax.token_at_offset(offset), |kind| match kind {
+        IDENT | T![self] | INT_NUMBER => 1,
+        _ => 0,
+    })?;
     let range = original_token.text_range();
     let navs =
-        sema.descend_into_macros(original_token)
+        sema.descend_into_macros(original_token, offset)
             .into_iter()
             .filter_map(|token| token.parent().and_then(ast::NameLike::cast))
             .filter_map(|node| match &node {
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
index 6048990f749..955923d7691 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
@@ -16,13 +16,13 @@ use crate::{FilePosition, NavigationTarget, RangeInfo, TryToNav};
 // image::https://user-images.githubusercontent.com/48062697/113020657-b560f500-917a-11eb-9007-0f809733a338.gif[]
 pub(crate) fn goto_type_definition(
     db: &RootDatabase,
-    position: FilePosition,
+    FilePosition { file_id, offset }: FilePosition,
 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
     let sema = hir::Semantics::new(db);
 
-    let file: ast::SourceFile = sema.parse(position.file_id);
+    let file: ast::SourceFile = sema.parse(file_id);
     let token: SyntaxToken =
-        pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind {
+        pick_best_token(file.syntax().token_at_offset(offset), |kind| match kind {
             IDENT | INT_NUMBER | T![self] => 2,
             kind if kind.is_trivia() => 0,
             _ => 1,
@@ -37,7 +37,7 @@ pub(crate) fn goto_type_definition(
         }
     };
     let range = token.text_range();
-    sema.descend_into_macros(token)
+    sema.descend_into_macros(token, offset)
         .into_iter()
         .filter_map(|token| {
             let ty = sema
diff --git a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
index 43e89a334bf..46a0464e9e6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/highlight_related.rs
@@ -15,6 +15,7 @@ use syntax::{
     SyntaxKind::{self, IDENT, INT_NUMBER},
     SyntaxNode, SyntaxToken, TextRange, T,
 };
+use text_edit::TextSize;
 
 use crate::{navigation_target::ToNav, references, NavigationTarget, TryToNav};
 
@@ -51,7 +52,7 @@ pub struct HighlightRelatedConfig {
 pub(crate) fn highlight_related(
     sema: &Semantics<'_, RootDatabase>,
     config: HighlightRelatedConfig,
-    FilePosition { offset, file_id }: FilePosition,
+    pos @ FilePosition { offset, file_id }: FilePosition,
 ) -> Option<Vec<HighlightedRange>> {
     let _p = profile::span("highlight_related");
     let syntax = sema.parse(file_id).syntax().clone();
@@ -79,7 +80,7 @@ pub(crate) fn highlight_related(
         }
         T![|] if config.closure_captures => highlight_closure_captures(sema, token, file_id),
         T![move] if config.closure_captures => highlight_closure_captures(sema, token, file_id),
-        _ if config.references => highlight_references(sema, &syntax, token, file_id),
+        _ if config.references => highlight_references(sema, &syntax, token, pos),
         _ => None,
     }
 }
@@ -129,9 +130,9 @@ fn highlight_references(
     sema: &Semantics<'_, RootDatabase>,
     node: &SyntaxNode,
     token: SyntaxToken,
-    file_id: FileId,
+    FilePosition { file_id, offset }: FilePosition,
 ) -> Option<Vec<HighlightedRange>> {
-    let defs = find_defs(sema, token.clone());
+    let defs = find_defs(sema, token.clone(), offset);
     let usages = defs
         .iter()
         .filter_map(|&d| {
@@ -455,8 +456,12 @@ fn cover_range(r0: Option<TextRange>, r1: Option<TextRange>) -> Option<TextRange
     }
 }
 
-fn find_defs(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> FxHashSet<Definition> {
-    sema.descend_into_macros(token)
+fn find_defs(
+    sema: &Semantics<'_, RootDatabase>,
+    token: SyntaxToken,
+    offset: TextSize,
+) -> FxHashSet<Definition> {
+    sema.descend_into_macros(token, offset)
         .into_iter()
         .filter_map(|token| IdentClass::classify_token(sema, &token))
         .map(IdentClass::definitions_no_ops)
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 40659e6c263..21934b9480e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -162,9 +162,9 @@ fn hover_simple(
     // prefer descending the same token kind in attribute expansions, in normal macros text
     // equivalency is more important
     let descended = if in_attr {
-        [sema.descend_into_macros_with_kind_preference(original_token.clone())].into()
+        [sema.descend_into_macros_with_kind_preference(original_token.clone(), offset)].into()
     } else {
-        sema.descend_into_macros_with_same_text(original_token.clone())
+        sema.descend_into_macros_with_same_text(original_token.clone(), offset)
     };
     let descended = || descended.iter();
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index ddc71dffa8a..d0f9f7b0e16 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -1557,6 +1557,49 @@ fn test_hover_function_show_types() {
 }
 
 #[test]
+fn test_hover_function_associated_type_params() {
+    check(
+        r#"
+trait Foo { type Bar; }
+impl Foo for i32 { type Bar = i64; }
+fn foo(arg: <i32 as Foo>::Bar) {}
+fn main() { foo$0; }
+"#,
+        expect![[r#"
+            *foo*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn foo(arg: <i32 as Foo>::Bar)
+            ```
+        "#]],
+    );
+
+    check(
+        r#"
+trait Foo<T> { type Bar<U>; }
+impl Foo<i64> for i32 { type Bar<U> = i32; }
+fn foo(arg: <<i32 as Foo<i64>>::Bar<i8> as Foo<i64>>::Bar<i8>) {}
+fn main() { foo$0; }
+"#,
+        expect![[r#"
+            *foo*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn foo(arg: <<i32 as Foo<i64>>::Bar<i8> as Foo<i64>>::Bar<i8>)
+            ```
+        "#]],
+    );
+}
+
+#[test]
 fn test_hover_function_pointer_show_identifiers() {
     check(
         r#"type foo$0 = fn(a: i32, b: i32) -> i32;"#,
@@ -3292,7 +3335,50 @@ struct S$0T<const C: usize = 1, T = Foo>(T);
             ```
 
             ```rust
-            struct ST<const C: usize, T = Foo>
+            struct ST<const C: usize = 1, T = Foo>
+            ```
+        "#]],
+    );
+}
+
+#[test]
+fn const_generic_default_value() {
+    check(
+        r#"
+struct Foo;
+struct S$0T<const C: usize = {40 + 2}, T = Foo>(T);
+"#,
+        expect![[r#"
+            *ST*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            struct ST<const C: usize = {const}, T = Foo>
+            ```
+        "#]],
+    );
+}
+
+#[test]
+fn const_generic_default_value_2() {
+    check(
+        r#"
+struct Foo;
+const VAL = 1;
+struct S$0T<const C: usize = VAL, T = Foo>(T);
+"#,
+        expect![[r#"
+            *ST*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            struct ST<const C: usize = VAL, T = Foo>
             ```
         "#]],
     );
@@ -6469,3 +6555,22 @@ fn test() {
         "#]],
     );
 }
+
+#[test]
+fn generic_params_disabled_by_cfg() {
+    check(
+        r#"
+struct S<#[cfg(never)] T>;
+fn test() {
+    let s$0: S = S;
+}
+"#,
+        expect![[r#"
+            *s*
+
+            ```rust
+            let s: S // size = 0, align = 1
+            ```
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index bf77d55d58e..c9cdbff7d7d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -484,7 +484,7 @@ impl Analysis {
         sysroot: Option<&OsStr>,
     ) -> Cancellable<doc_links::DocumentationLinks> {
         self.with_db(|db| {
-            doc_links::external_docs(db, &position, target_dir, sysroot).unwrap_or_default()
+            doc_links::external_docs(db, position, target_dir, sysroot).unwrap_or_default()
         })
     }
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 17f3771b1a5..2ca2b5b1d5f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -99,7 +99,7 @@ pub(crate) fn moniker(
         });
     }
     let navs = sema
-        .descend_into_macros(original_token.clone())
+        .descend_into_macros(original_token.clone(), offset)
         .into_iter()
         .filter_map(|token| {
             IdentClass::classify_token(sema, &token).map(IdentClass::definitions_no_ops).map(|it| {
diff --git a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs
index d1479dd1e58..0740bfbc7b1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/navigation_target.rs
@@ -175,8 +175,12 @@ impl TryToNav for FileSymbol {
 
         Some(NavigationTarget {
             file_id: full_range.file_id,
-            name: if self.is_alias { self.def.name(db)?.to_smol_str() } else { self.name.clone() },
-            alias: if self.is_alias { Some(self.name.clone()) } else { None },
+            name: self
+                .is_alias
+                .then(|| self.def.name(db))
+                .flatten()
+                .map_or_else(|| self.name.clone(), |it| it.to_smol_str()),
+            alias: self.is_alias.then(|| self.name.clone()),
             kind: Some(hir::ModuleDefId::from(self.def).into()),
             full_range: full_range.range,
             focus_range,
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index 813f9ed943f..2d0295692ac 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -126,7 +126,7 @@ pub(crate) fn find_defs<'a>(
         )
     });
     token.map(|token| {
-        sema.descend_into_macros_with_same_text(token)
+        sema.descend_into_macros_with_same_text(token, offset)
             .into_iter()
             .filter_map(|it| ast::NameLike::cast(it.parent()?))
             .filter_map(move |name_like| {
diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
index 7795be54e26..847ab3d21ad 100644
--- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -67,17 +67,20 @@ impl SignatureHelp {
 }
 
 /// Computes parameter information for the given position.
-pub(crate) fn signature_help(db: &RootDatabase, position: FilePosition) -> Option<SignatureHelp> {
+pub(crate) fn signature_help(
+    db: &RootDatabase,
+    FilePosition { file_id, offset }: FilePosition,
+) -> Option<SignatureHelp> {
     let sema = Semantics::new(db);
-    let file = sema.parse(position.file_id);
+    let file = sema.parse(file_id);
     let file = file.syntax();
     let token = file
-        .token_at_offset(position.offset)
+        .token_at_offset(offset)
         .left_biased()
         // if the cursor is sandwiched between two space tokens and the call is unclosed
         // this prevents us from leaving the CallExpression
         .and_then(|tok| algo::skip_trivia_token(tok, Direction::Prev))?;
-    let token = sema.descend_into_macros_single(token);
+    let token = sema.descend_into_macros_single(token, offset);
 
     for node in token.parent_ancestors() {
         match_ast! {
@@ -202,7 +205,7 @@ fn signature_help_for_call(
     res.signature.push('(');
     {
         if let Some((self_param, _)) = callable.receiver_param(db) {
-            format_to!(res.signature, "{}", self_param)
+            format_to!(res.signature, "{}", self_param.display(db))
         }
         let mut buf = String::new();
         for (idx, (pat, ty)) in callable.params(db).into_iter().enumerate() {
@@ -1315,6 +1318,25 @@ id! {
     }
 
     #[test]
+    fn fn_signature_for_method_call_defined_in_macro() {
+        check(
+            r#"
+macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
+struct S;
+id! {
+    impl S {
+        fn foo<'a>(&'a mut self) {}
+    }
+}
+fn test() { S.foo($0); }
+"#,
+            expect![[r#"
+                fn foo(&'a mut self)
+            "#]],
+        );
+    }
+
+    #[test]
     fn call_info_for_lambdas() {
         check(
             r#"
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
index ae97236409e..bb01c81d66f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
@@ -395,10 +395,10 @@ fn traverse(
                 NodeOrToken::Token(token) if token.kind() != COMMENT => {
                     let token = match attr_or_derive_item {
                         Some(AttrOrDerive::Attr(_)) => {
-                            sema.descend_into_macros_with_kind_preference(token)
+                            sema.descend_into_macros_with_kind_preference(token, 0.into())
                         }
                         Some(AttrOrDerive::Derive(_)) | None => {
-                            sema.descend_into_macros_single(token)
+                            sema.descend_into_macros_single(token, 0.into())
                         }
                     };
                     match token.parent().and_then(ast::NameLike::cast) {
diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
index 62b2accf5cd..7b9bb61e696 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
@@ -961,6 +961,7 @@ impl TtTreeSink<'_> {
                 if has_pseudo_dot {
                     assert!(right.is_empty(), "{left}.{right}");
                 } else {
+                    assert!(!right.is_empty(), "{left}.{right}");
                     self.inner.start_node(SyntaxKind::NAME_REF);
                     self.inner.token(SyntaxKind::INT_NUMBER, right);
                     self.inner.finish_node();
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
index 333318f53b7..6a2a9adce15 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs
@@ -184,7 +184,9 @@ pub(crate) mod entry {
             };
             p.bump_any();
             while !p.at(EOF) && !p.at(closing_paren_kind) {
-                expressions::expr(p);
+                if expressions::expr(p).is_none() {
+                    break;
+                }
                 if !p.at(EOF) && !p.at(closing_paren_kind) {
                     p.expect(T![,]);
                 }
diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
index 8ed1c84c4c6..29d9b05d3f3 100644
--- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs
@@ -88,7 +88,7 @@ fn const_param(p: &mut Parser<'_>, m: Marker) {
 
         // test const_param_default_path
         // struct A<const N: i32 = i32::MAX>;
-        generic_args::const_arg_expr(p);
+        generic_args::const_arg(p);
     }
 
     m.complete(p, CONST_PARAM);
diff --git a/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs b/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
index 53cdad64992..2c47e3d086d 100644
--- a/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/shortcuts.rs
@@ -46,12 +46,16 @@ impl LexedStr<'_> {
                     // Tag the token as joint if it is float with a fractional part
                     // we use this jointness to inform the parser about what token split
                     // event to emit when we encounter a float literal in a field access
-                    if kind == SyntaxKind::FLOAT_NUMBER && !self.text(i).ends_with('.') {
-                        res.was_joint();
+                    if kind == SyntaxKind::FLOAT_NUMBER {
+                        if !self.text(i).ends_with('.') {
+                            res.was_joint();
+                        } else {
+                            was_joint = false;
+                        }
+                    } else {
+                        was_joint = true;
                     }
                 }
-
-                was_joint = true;
             }
         }
         res
@@ -204,6 +208,7 @@ impl Builder<'_, '_> {
                     assert!(right.is_empty(), "{left}.{right}");
                     self.state = State::Normal;
                 } else {
+                    assert!(!right.is_empty(), "{left}.{right}");
                     (self.sink)(StrStep::Enter { kind: SyntaxKind::NAME_REF });
                     (self.sink)(StrStep::Token { kind: SyntaxKind::INT_NUMBER, text: right });
                     (self.sink)(StrStep::Exit);
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast
index 809ad1b8d5b..49f163b164a 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/0022_recover_from_missing_const_default.rast
@@ -20,7 +20,8 @@ SOURCE_FILE
                 IDENT "i32"
         WHITESPACE " "
         EQ "="
-      WHITESPACE " "
+        WHITESPACE " "
+        CONST_ARG
       COMMA ","
       WHITESPACE " "
       CONST_PARAM
@@ -37,8 +38,9 @@ SOURCE_FILE
                 IDENT "i32"
         WHITESPACE " "
         EQ "="
+        CONST_ARG
       R_ANGLE ">"
     SEMICOLON ";"
   WHITESPACE "\n"
-error 23: expected a generic const argument
+error 24: expected a generic const argument
 error 40: expected a generic const argument
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast
index 11002bf98d0..3f5fb47d287 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rast
@@ -21,16 +21,17 @@ SOURCE_FILE
         WHITESPACE " "
         EQ "="
         WHITESPACE " "
-        PATH_EXPR
-          PATH
+        CONST_ARG
+          PATH_EXPR
             PATH
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "i32"
+              COLON2 "::"
               PATH_SEGMENT
                 NAME_REF
-                  IDENT "i32"
-            COLON2 "::"
-            PATH_SEGMENT
-              NAME_REF
-                IDENT "MAX"
+                  IDENT "MAX"
       R_ANGLE ">"
     SEMICOLON ";"
   WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast
index 0607ff54fbb..d6501137498 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0199_const_param_default_expression.rast
@@ -21,14 +21,15 @@ SOURCE_FILE
         WHITESPACE " "
         EQ "="
         WHITESPACE " "
-        BLOCK_EXPR
-          STMT_LIST
-            L_CURLY "{"
-            WHITESPACE " "
-            LITERAL
-              INT_NUMBER "1"
-            WHITESPACE " "
-            R_CURLY "}"
+        CONST_ARG
+          BLOCK_EXPR
+            STMT_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              LITERAL
+                INT_NUMBER "1"
+              WHITESPACE " "
+              R_CURLY "}"
       R_ANGLE ">"
     SEMICOLON ";"
   WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast
index 8e52313651c..6de10353bf0 100644
--- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast
+++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0200_const_param_default_literal.rast
@@ -21,10 +21,11 @@ SOURCE_FILE
         WHITESPACE " "
         EQ "="
         WHITESPACE " "
-        PREFIX_EXPR
-          MINUS "-"
-          LITERAL
-            INT_NUMBER "1"
+        CONST_ARG
+          PREFIX_EXPR
+            MINUS "-"
+            LITERAL
+              INT_NUMBER "1"
       R_ANGLE ">"
     SEMICOLON ";"
   WHITESPACE "\n"
diff --git a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
index 71303d5a631..814a0257402 100644
--- a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
+++ b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
@@ -10,13 +10,13 @@ pub struct StopWatch {
     time: Instant,
     #[cfg(target_os = "linux")]
     counter: Option<perf_event::Counter>,
-    memory: Option<MemoryUsage>,
+    memory: MemoryUsage,
 }
 
 pub struct StopWatchSpan {
     pub time: Duration,
     pub instructions: Option<u64>,
-    pub memory: Option<MemoryUsage>,
+    pub memory: MemoryUsage,
 }
 
 impl StopWatch {
@@ -45,20 +45,16 @@ impl StopWatch {
                 None
             }
         };
+        let memory = MemoryUsage::now();
         let time = Instant::now();
         StopWatch {
             time,
             #[cfg(target_os = "linux")]
             counter,
-            memory: None,
+            memory,
         }
     }
-    pub fn memory(mut self, yes: bool) -> StopWatch {
-        if yes {
-            self.memory = Some(MemoryUsage::now());
-        }
-        self
-    }
+
     pub fn elapsed(&mut self) -> StopWatchSpan {
         let time = self.time.elapsed();
 
@@ -69,7 +65,7 @@ impl StopWatch {
         #[cfg(not(target_os = "linux"))]
         let instructions = None;
 
-        let memory = self.memory.map(|it| MemoryUsage::now() - it);
+        let memory = MemoryUsage::now() - self.memory;
         StopWatchSpan { time, instructions, memory }
     }
 }
@@ -93,9 +89,7 @@ impl fmt::Display for StopWatchSpan {
             }
             write!(f, ", {instructions}{prefix}instr")?;
         }
-        if let Some(memory) = self.memory {
-            write!(f, ", {memory}")?;
-        }
+        write!(f, ", {}", self.memory)?;
         Ok(())
     }
 }
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index f51ea7eeb22..13463e9f72e 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -167,7 +167,8 @@ impl ProjectWorkspace {
                 cmd.envs(&config.extra_env);
                 cmd.arg("--version").current_dir(current_dir);
                 cmd
-            })?;
+            })
+            .with_context(|| format!("Failed to query rust toolchain version at {current_dir}, is your toolchain setup correctly?"))?;
             anyhow::Ok(
                 cargo_version
                     .get(prefix.len()..)
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index 5bfac7ee45c..1f9d6db9314 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -24,7 +24,7 @@ crossbeam-channel = "0.5.5"
 dissimilar = "1.0.4"
 itertools = "0.10.5"
 scip = "0.1.1"
-lsp-types = { version = "=0.94", features = ["proposed"] }
+lsp-types = { version = "=0.94.0", features = ["proposed"] }
 parking_lot = "0.12.1"
 xflags = "0.3.0"
 oorandom = "11.1.3"
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
index f446a7c0596..4a03be1893c 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -235,9 +235,7 @@ impl flags::AnalysisStats {
         if let Some(instructions) = total_span.instructions {
             report_metric("total instructions", instructions, "#instr");
         }
-        if let Some(memory) = total_span.memory {
-            report_metric("total memory", memory.allocated.megabytes() as u64, "MB");
-        }
+        report_metric("total memory", total_span.memory.allocated.megabytes() as u64, "MB");
 
         if env::var("RA_COUNT").is_ok() {
             eprintln!("{}", profile::countme::get_all());
@@ -257,7 +255,7 @@ impl flags::AnalysisStats {
             eprintln!("source files: {total_file_size}, macro files: {total_macro_file_size}");
         }
 
-        if self.memory_usage && verbosity.is_verbose() {
+        if verbosity.is_verbose() {
             print_memory_usage(host, vfs);
         }
 
@@ -814,7 +812,7 @@ impl flags::AnalysisStats {
     }
 
     fn stop_watch(&self) -> StopWatch {
-        StopWatch::start().memory(self.memory_usage)
+        StopWatch::start()
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
index 13b7f039bb0..419440b6df7 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs
@@ -62,8 +62,6 @@ xflags::xflags! {
             optional --randomize
             /// Run type inference in parallel.
             optional --parallel
-            /// Collect memory usage statistics.
-            optional --memory-usage
             /// Print the total length of all source and macro files (whitespace is not counted).
             optional --source-stats
 
@@ -191,7 +189,6 @@ pub struct AnalysisStats {
     pub output: Option<OutputFormat>,
     pub randomize: bool,
     pub parallel: bool,
-    pub memory_usage: bool,
     pub source_stats: bool,
     pub only: Option<String>,
     pub with_deps: bool,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index fa20c796ec2..40c50f6d176 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -150,18 +150,22 @@ config_data! {
         ///
         /// Set to `"all"` to pass `--all-features` to Cargo.
         check_features | checkOnSave_features: Option<CargoFeaturesDef>  = "null",
+        /// List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
+        ///
+        /// For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
+        check_ignore: FxHashSet<String> = "[]",
         /// Specifies the working directory for running checks.
         /// - "workspace": run checks for workspaces in the corresponding workspaces' root directories.
         // FIXME: Ideally we would support this in some way
-        ///   This falls back to "root" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.
+        ///   This falls back to "root" if `#rust-analyzer.cargo.check.invocationStrategy#` is set to `once`.
         /// - "root": run checks in the project's root directory.
-        /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+        /// This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
         /// is set.
         check_invocationLocation | checkOnSave_invocationLocation: InvocationLocation = "\"workspace\"",
-        /// Specifies the invocation strategy to use when running the checkOnSave command.
+        /// Specifies the invocation strategy to use when running the check command.
         /// If `per_workspace` is set, the command will be executed for each workspace.
         /// If `once` is set, the command will be executed once.
-        /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+        /// This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
         /// is set.
         check_invocationStrategy | checkOnSave_invocationStrategy: InvocationStrategy = "\"per_workspace\"",
         /// Whether to pass `--no-default-features` to Cargo. Defaults to
@@ -1098,6 +1102,7 @@ impl Config {
             remap_prefix: self.data.diagnostics_remapPrefix.clone(),
             warnings_as_info: self.data.diagnostics_warningsAsInfo.clone(),
             warnings_as_hint: self.data.diagnostics_warningsAsHint.clone(),
+            check_ignore: self.data.check_ignore.clone(),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
index 33422fd058e..b65f38a0c71 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs
@@ -6,6 +6,7 @@ use std::mem;
 use ide::FileId;
 use ide_db::FxHashMap;
 use nohash_hasher::{IntMap, IntSet};
+use rustc_hash::FxHashSet;
 use triomphe::Arc;
 
 use crate::lsp_ext;
@@ -17,6 +18,7 @@ pub struct DiagnosticsMapConfig {
     pub remap_prefix: FxHashMap<String, String>,
     pub warnings_as_info: Vec<String>,
     pub warnings_as_hint: Vec<String>,
+    pub check_ignore: FxHashSet<String>,
 }
 
 #[derive(Debug, Default, Clone)]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
index e1d1130ff1b..06564578d80 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -292,6 +292,13 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
 
     let mut source = String::from("rustc");
     let mut code = rd.code.as_ref().map(|c| c.code.clone());
+
+    if let Some(code_val) = &code {
+        if config.check_ignore.contains(code_val) {
+            return Vec::new();
+        }
+    }
+
     if let Some(code_val) = &code {
         // See if this is an RFC #2103 scoped lint (e.g. from Clippy)
         let scoped_code: Vec<&str> = code_val.split("::").collect();
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 138ddd20897..ea7ebd85b33 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -296,7 +296,7 @@ TypeParam =
 
 ConstParam =
   Attr* 'const' Name ':' Type
-  ('=' default_val:Expr)?
+  ('=' default_val:ConstArg)?
 
 LifetimeParam =
   Attr* Lifetime (':' TypeBoundList?)?
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
index 0b27faa535d..16448db04f8 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs
@@ -709,7 +709,7 @@ impl ConstParam {
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
-    pub fn default_val(&self) -> Option<Expr> { support::child(&self.syntax) }
+    pub fn default_val(&self) -> Option<ConstArg> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 4c6db0ef06c..17e311c0c50 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -503,11 +503,16 @@ pub fn hacky_block_expr(
 pub fn expr_unit() -> ast::Expr {
     expr_from_text("()")
 }
+
 pub fn expr_literal(text: &str) -> ast::Literal {
     assert_eq!(text.trim(), text);
     ast_from_text(&format!("fn f() {{ let _ = {text}; }}"))
 }
 
+pub fn expr_const_value(text: &str) -> ast::ConstArg {
+    ast_from_text(&format!("trait Foo<const N: usize = {text}> {{}}"))
+}
+
 pub fn expr_empty_block() -> ast::Expr {
     expr_from_text("{}")
 }
@@ -1100,7 +1105,7 @@ pub mod tokens {
 
     pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = Lazy::new(|| {
         SourceFile::parse(
-            "const C: <()>::Item = (1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p)\n;\n\n",
+            "const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p)\n;\n\n",
         )
     });
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
index 3308077da5b..691d0c618f3 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
@@ -61,6 +61,14 @@ impl ast::BlockExpr {
     pub fn tail_expr(&self) -> Option<ast::Expr> {
         self.stmt_list()?.tail_expr()
     }
+    /// Block expressions accept outer and inner attributes, but only when they are the outer
+    /// expression of an expression statement or the final expression of another block expression.
+    pub fn may_carry_attributes(&self) -> bool {
+        matches!(
+            self.syntax().parent().map(|it| it.kind()),
+            Some(SyntaxKind::BLOCK_EXPR | SyntaxKind::EXPR_STMT)
+        )
+    }
 }
 
 #[derive(Debug, PartialEq, Eq, Clone)]
diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
index 4cd668a0cd5..27c8a13e58d 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs
@@ -195,11 +195,16 @@ impl ast::TokenTree {
                     // Tag the token as joint if it is float with a fractional part
                     // we use this jointness to inform the parser about what token split
                     // event to emit when we encounter a float literal in a field access
-                    if kind == SyntaxKind::FLOAT_NUMBER && !t.text().ends_with('.') {
-                        parser_input.was_joint();
+                    if kind == SyntaxKind::FLOAT_NUMBER {
+                        if !t.text().ends_with('.') {
+                            parser_input.was_joint();
+                        } else {
+                            was_joint = false;
+                        }
+                    } else {
+                        was_joint = true;
                     }
                 }
-                was_joint = true;
             }
         }
 
@@ -250,6 +255,7 @@ impl ast::TokenTree {
                             if has_pseudo_dot {
                                 assert!(right.is_empty(), "{left}.{right}");
                             } else {
+                                assert!(!right.is_empty(), "{left}.{right}");
                                 builder.start_node(SyntaxKind::NAME_REF);
                                 builder.token(SyntaxKind::INT_NUMBER, right);
                                 builder.finish_node();
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
index 75e7a3fec00..3f8b5a08969 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
@@ -313,7 +313,7 @@ impl FixtureWithProjectMeta {
 }
 
 impl MiniCore {
-    const RAW_SOURCE: &str = include_str!("./minicore.rs");
+    const RAW_SOURCE: &'static str = include_str!("./minicore.rs");
 
     fn has_flag(&self, flag: &str) -> bool {
         self.activated_flags.iter().any(|it| it == flag)
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index ea00c9540ff..71feed0f72c 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -161,23 +161,30 @@ List of features to activate. Defaults to
 
 Set to `"all"` to pass `--all-features` to Cargo.
 --
+[[rust-analyzer.check.ignore]]rust-analyzer.check.ignore (default: `[]`)::
++
+--
+List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
+
+For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
+--
 [[rust-analyzer.check.invocationLocation]]rust-analyzer.check.invocationLocation (default: `"workspace"`)::
 +
 --
 Specifies the working directory for running checks.
 - "workspace": run checks for workspaces in the corresponding workspaces' root directories.
-  This falls back to "root" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.
+  This falls back to "root" if `#rust-analyzer.cargo.check.invocationStrategy#` is set to `once`.
 - "root": run checks in the project's root directory.
-This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
 is set.
 --
 [[rust-analyzer.check.invocationStrategy]]rust-analyzer.check.invocationStrategy (default: `"per_workspace"`)::
 +
 --
-Specifies the invocation strategy to use when running the checkOnSave command.
+Specifies the invocation strategy to use when running the check command.
 If `per_workspace` is set, the command will be executed for each workspace.
 If `once` is set, the command will be executed once.
-This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+This config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`
 is set.
 --
 [[rust-analyzer.check.noDefaultFeatures]]rust-analyzer.check.noDefaultFeatures (default: `null`)::
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 76d7e91f381..44f1b81675a 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -292,6 +292,11 @@
                 "command": "rust-analyzer.viewMemoryLayout",
                 "title": "View Memory Layout",
                 "category": "rust-analyzer"
+            },
+            {
+                "command": "rust-analyzer.toggleCheckOnSave",
+                "title": "Toggle Check on Save",
+                "category": "rust-analyzer"
             }
         ],
         "keybindings": [
@@ -700,8 +705,17 @@
                         }
                     ]
                 },
+                "rust-analyzer.check.ignore": {
+                    "markdownDescription": "List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.\n\nFor example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...",
+                    "default": [],
+                    "type": "array",
+                    "items": {
+                        "type": "string"
+                    },
+                    "uniqueItems": true
+                },
                 "rust-analyzer.check.invocationLocation": {
-                    "markdownDescription": "Specifies the working directory for running checks.\n- \"workspace\": run checks for workspaces in the corresponding workspaces' root directories.\n    This falls back to \"root\" if `#rust-analyzer.cargo.checkOnSave.invocationStrategy#` is set to `once`.\n- \"root\": run checks in the project's root directory.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.",
+                    "markdownDescription": "Specifies the working directory for running checks.\n- \"workspace\": run checks for workspaces in the corresponding workspaces' root directories.\n    This falls back to \"root\" if `#rust-analyzer.cargo.check.invocationStrategy#` is set to `once`.\n- \"root\": run checks in the project's root directory.\nThis config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`\nis set.",
                     "default": "workspace",
                     "type": "string",
                     "enum": [
@@ -714,7 +728,7 @@
                     ]
                 },
                 "rust-analyzer.check.invocationStrategy": {
-                    "markdownDescription": "Specifies the invocation strategy to use when running the checkOnSave command.\nIf `per_workspace` is set, the command will be executed for each workspace.\nIf `once` is set, the command will be executed once.\nThis config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`\nis set.",
+                    "markdownDescription": "Specifies the invocation strategy to use when running the check command.\nIf `per_workspace` is set, the command will be executed for each workspace.\nIf `once` is set, the command will be executed once.\nThis config only has an effect when `#rust-analyzer.cargo.check.overrideCommand#`\nis set.",
                     "default": "per_workspace",
                     "type": "string",
                     "enum": [
diff --git a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
index ef4dff095cf..6cf399599d9 100644
--- a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
+++ b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
@@ -20,7 +20,7 @@ export async function bootstrap(
 
     log.info("Using server binary at", path);
 
-    if (!isValidExecutable(path)) {
+    if (!isValidExecutable(path, config.serverExtraEnv)) {
         if (config.serverPath) {
             throw new Error(`Failed to execute ${path} --version. \`config.server.path\` or \`config.serverPath\` has been set explicitly.\
             Consider removing this config or making a valid server binary available at that path.`);
diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts
index e21f536f26a..aba37bac27d 100644
--- a/src/tools/rust-analyzer/editors/code/src/commands.ts
+++ b/src/tools/rust-analyzer/editors/code/src/commands.ts
@@ -1407,3 +1407,10 @@ locate()
         ctx.pushExtCleanup(document);
     };
 }
+
+export function toggleCheckOnSave(ctx: Ctx): Cmd {
+    return async () => {
+        await ctx.config.toggleCheckOnSave();
+        ctx.refreshServerStatus();
+    };
+}
diff --git a/src/tools/rust-analyzer/editors/code/src/config.ts b/src/tools/rust-analyzer/editors/code/src/config.ts
index 0e64054c11d..39e2f767c76 100644
--- a/src/tools/rust-analyzer/editors/code/src/config.ts
+++ b/src/tools/rust-analyzer/editors/code/src/config.ts
@@ -216,6 +216,39 @@ export class Config {
             ),
         );
     }
+    get checkOnSave() {
+        return this.get<boolean>("checkOnSave") ?? false;
+    }
+    async toggleCheckOnSave() {
+        const config = this.cfg.inspect<boolean>("checkOnSave") ?? { key: "checkOnSave" };
+        let overrideInLanguage;
+        let target;
+        let value;
+        if (
+            config.workspaceFolderValue !== undefined ||
+            config.workspaceFolderLanguageValue !== undefined
+        ) {
+            target = vscode.ConfigurationTarget.WorkspaceFolder;
+            overrideInLanguage = config.workspaceFolderLanguageValue;
+            value = config.workspaceFolderValue || config.workspaceFolderLanguageValue;
+        } else if (
+            config.workspaceValue !== undefined ||
+            config.workspaceLanguageValue !== undefined
+        ) {
+            target = vscode.ConfigurationTarget.Workspace;
+            overrideInLanguage = config.workspaceLanguageValue;
+            value = config.workspaceValue || config.workspaceLanguageValue;
+        } else if (config.globalValue !== undefined || config.globalLanguageValue !== undefined) {
+            target = vscode.ConfigurationTarget.Global;
+            overrideInLanguage = config.globalLanguageValue;
+            value = config.globalValue || config.globalLanguageValue;
+        } else if (config.defaultValue !== undefined || config.defaultLanguageValue !== undefined) {
+            overrideInLanguage = config.defaultLanguageValue;
+            value = config.defaultValue || config.defaultLanguageValue;
+        }
+        await this.cfg.update("checkOnSave", !(value || false), target || null, overrideInLanguage);
+    }
+
     get traceExtension() {
         return this.get<boolean>("trace.extension");
     }
diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts
index 16c14ca54f2..363a7a82e68 100644
--- a/src/tools/rust-analyzer/editors/code/src/ctx.ts
+++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts
@@ -94,6 +94,7 @@ export class Ctx {
     private unlinkedFiles: vscode.Uri[];
     private _dependencies: RustDependenciesProvider | undefined;
     private _treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId> | undefined;
+    private lastStatus: ServerStatusParams | { health: "stopped" } = { health: "stopped" };
 
     get client() {
         return this._client;
@@ -404,7 +405,15 @@ export class Ctx {
     }
 
     setServerStatus(status: ServerStatusParams | { health: "stopped" }) {
+        this.lastStatus = status;
+        this.updateStatusBarItem();
+    }
+    refreshServerStatus() {
+        this.updateStatusBarItem();
+    }
+    private updateStatusBarItem() {
         let icon = "";
+        const status = this.lastStatus;
         const statusBar = this.statusBar;
         statusBar.show();
         statusBar.tooltip = new vscode.MarkdownString("", true);
@@ -447,13 +456,18 @@ export class Ctx {
                     "statusBarItem.warningBackground",
                 );
                 statusBar.command = "rust-analyzer.startServer";
-                statusBar.text = `$(stop-circle) rust-analyzer`;
+                statusBar.text = "$(stop-circle) rust-analyzer";
                 return;
         }
         if (statusBar.tooltip.value) {
             statusBar.tooltip.appendMarkdown("\n\n---\n\n");
         }
-        statusBar.tooltip.appendMarkdown("\n\n[Open logs](command:rust-analyzer.openLogs)");
+        statusBar.tooltip.appendMarkdown("\n\n[Open Logs](command:rust-analyzer.openLogs)");
+        statusBar.tooltip.appendMarkdown(
+            `\n\n[${
+                this.config.checkOnSave ? "Disable" : "Enable"
+            } Check on Save](command:rust-analyzer.toggleCheckOnSave)`,
+        );
         statusBar.tooltip.appendMarkdown(
             "\n\n[Reload Workspace](command:rust-analyzer.reloadWorkspace)",
         );
diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts
index 448150bac06..ee5e5b1b80c 100644
--- a/src/tools/rust-analyzer/editors/code/src/main.ts
+++ b/src/tools/rust-analyzer/editors/code/src/main.ts
@@ -180,6 +180,7 @@ function createCommands(): Record<string, CommandFactory> {
         ssr: { enabled: commands.ssr },
         serverVersion: { enabled: commands.serverVersion },
         viewMemoryLayout: { enabled: commands.viewMemoryLayout },
+        toggleCheckOnSave: { enabled: commands.toggleCheckOnSave },
         // Internal commands which are invoked by the server.
         applyActionGroup: { enabled: commands.applyActionGroup },
         applySnippetWorkspaceEdit: { enabled: commands.applySnippetWorkspaceEditCommand },
diff --git a/src/tools/rust-analyzer/editors/code/src/util.ts b/src/tools/rust-analyzer/editors/code/src/util.ts
index 38ce6761578..0414ea0f806 100644
--- a/src/tools/rust-analyzer/editors/code/src/util.ts
+++ b/src/tools/rust-analyzer/editors/code/src/util.ts
@@ -2,6 +2,7 @@ import * as vscode from "vscode";
 import { strict as nativeAssert } from "assert";
 import { exec, type ExecOptions, spawnSync } from "child_process";
 import { inspect } from "util";
+import type { Env } from "./client";
 
 export function assert(condition: boolean, explanation: string): asserts condition {
     try {
@@ -93,10 +94,13 @@ export function isDocumentInWorkspace(document: RustDocument): boolean {
     return false;
 }
 
-export function isValidExecutable(path: string): boolean {
+export function isValidExecutable(path: string, extraEnv: Env): boolean {
     log.debug("Checking availability of a binary at", path);
 
-    const res = spawnSync(path, ["--version"], { encoding: "utf8" });
+    const res = spawnSync(path, ["--version"], {
+        encoding: "utf8",
+        env: { ...process.env, ...extraEnv },
+    });
 
     const printOutput = res.error ? log.warn : log.info;
     printOutput(path, "--version:", res);
@@ -151,6 +155,7 @@ export function execute(command: string, options: ExecOptions): Promise<string>
 }
 
 export function executeDiscoverProject(command: string, options: ExecOptions): Promise<string> {
+    options = Object.assign({ maxBuffer: 10 * 1024 * 1024 }, options);
     log.info(`running command: ${command}`);
     return new Promise((resolve, reject) => {
         exec(command, options, (err, stdout, _) => {
diff --git a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
index 01707d30191..e1c49db39d5 100644
--- a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
+++ b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lsp-server"
-version = "0.7.2"
+version = "0.7.3"
 description = "Generic LSP server scaffold."
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server"
@@ -9,7 +9,8 @@ edition = "2021"
 [dependencies]
 log = "0.4.17"
 serde_json = "1.0.96"
-serde = { version = "1.0.156", features = ["derive"] }
+# See https://github.com/serde-rs/serde/issues/2538#issuecomment-1684517372 for why we pin serde
+serde = { version = "1.0.156, < 1.0.172", features = ["derive"] }
 crossbeam-channel = "0.5.6"
 
 [dev-dependencies]
diff --git a/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs b/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs
index 49a825e579b..e487b9b4622 100644
--- a/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs
+++ b/src/tools/rust-analyzer/lib/lsp-server/src/stdio.rs
@@ -3,6 +3,8 @@ use std::{
     thread,
 };
 
+use log::debug;
+
 use crossbeam_channel::{bounded, Receiver, Sender};
 
 use crate::Message;
@@ -23,7 +25,8 @@ pub(crate) fn stdio_transport() -> (Sender<Message>, Receiver<Message>, IoThread
         while let Some(msg) = Message::read(&mut stdin)? {
             let is_exit = matches!(&msg, Message::Notification(n) if n.is_exit());
 
-            reader_sender.send(msg).unwrap();
+            debug!("sending message {:#?}", msg);
+            reader_sender.send(msg).expect("receiver was dropped, failed to send a message");
 
             if is_exit {
                 break;
diff --git a/src/tools/rust-analyzer/xtask/src/metrics.rs b/src/tools/rust-analyzer/xtask/src/metrics.rs
index 68537423195..e4710260409 100644
--- a/src/tools/rust-analyzer/xtask/src/metrics.rs
+++ b/src/tools/rust-analyzer/xtask/src/metrics.rs
@@ -103,9 +103,7 @@ impl Metrics {
         path: &str,
     ) -> anyhow::Result<()> {
         eprintln!("\nMeasuring analysis-stats/{name}");
-        let output =
-            cmd!(sh, "./target/release/rust-analyzer -q analysis-stats --memory-usage {path}")
-                .read()?;
+        let output = cmd!(sh, "./target/release/rust-analyzer -q analysis-stats {path}").read()?;
         for (metric, value, unit) in parse_metrics(&output) {
             self.report(&format!("analysis-stats/{name}/{metric}"), value, unit.into());
         }
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 18a08f17ba0..5e8edd8f8bf 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -819,6 +819,8 @@ impl Rewrite for ast::Ty {
             ast::TyKind::Tup(ref items) => {
                 rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
             }
+            ast::TyKind::AnonStruct(_) => Some(context.snippet(self.span).to_owned()),
+            ast::TyKind::AnonUnion(_) => Some(context.snippet(self.span).to_owned()),
             ast::TyKind::Path(ref q_self, ref path) => {
                 rewrite_path(context, PathContext::Type, q_self, path, shape)
             }
diff --git a/src/tools/rustfmt/tests/target/anonymous-types.rs b/src/tools/rustfmt/tests/target/anonymous-types.rs
new file mode 100644
index 00000000000..8e08c314ed1
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/anonymous-types.rs
@@ -0,0 +1,19 @@
+// Test for issue 85480
+// Pretty print anonymous struct and union types
+
+// pp-exact
+// pretty-compare-only
+
+struct Foo {
+    _: union  {
+        _: struct  {
+            a: u8,
+            b: u16,
+        },
+        c: u32,
+    },
+    d: u64,
+    e: f32,
+}
+
+fn main() {}
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 3414924007b..6a197527a64 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -10,8 +10,8 @@ use std::path::{Path, PathBuf};
 
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1891;
-const ROOT_ENTRY_LIMIT: usize = 866;
+const ISSUES_ENTRY_LIMIT: usize = 1874;
+const ROOT_ENTRY_LIMIT: usize = 865;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm-maybe-uninit.rs
new file mode 100644
index 00000000000..d7e4a948954
--- /dev/null
+++ b/tests/codegen/asm-maybe-uninit.rs
@@ -0,0 +1,27 @@
+// compile-flags: -O
+// only-x86_64
+
+#![crate_type = "rlib"]
+#![allow(asm_sub_register)]
+
+use std::mem::MaybeUninit;
+use std::arch::asm;
+
+// CHECK-LABEL: @int
+#[no_mangle]
+pub unsafe fn int(x: MaybeUninit<i32>) -> MaybeUninit<i32> {
+    let y: MaybeUninit<i32>;
+    asm!("/*{}{}*/", in(reg) x, out(reg) y);
+    y
+}
+
+// CHECK-LABEL: @inout
+#[no_mangle]
+pub unsafe fn inout(mut x: i32) -> MaybeUninit<u32> {
+    let mut y: MaybeUninit<u32>;
+    asm!("/*{}*/", inout(reg) x => y);
+    asm!("/*{}*/", inout(reg) y => x);
+    asm!("/*{}*/", inlateout(reg) x => y);
+    asm!("/*{}*/", inlateout(reg) y => x);
+    y
+}
diff --git a/tests/codegen/box-maybe-uninit.rs b/tests/codegen/box-uninit-bytes.rs
index 282af99b067..732da0a1794 100644
--- a/tests/codegen/box-maybe-uninit.rs
+++ b/tests/codegen/box-uninit-bytes.rs
@@ -25,6 +25,20 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
     Box::new(MaybeUninit::uninit())
 }
 
+#[repr(align(1024))]
+pub struct LotsaPadding(usize);
+
+// Boxing a value with padding should not copy junk from the stack
+#[no_mangle]
+pub fn box_lotsa_padding() -> Box<LotsaPadding> {
+    // CHECK-LABEL: @box_lotsa_padding
+    // CHECK-NOT: alloca
+    // CHECK-NOT: getelementptr
+    // CHECK-NOT: memcpy
+    // CHECK-NOT: memset
+    Box::new(LotsaPadding(42))
+}
+
 // Hide the `allocalign` attribute in the declaration of __rust_alloc
 // from the CHECK-NOT above, and also verify the attributes got set reasonably.
 // CHECK: declare {{(dso_local )?}}noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
diff --git a/tests/codegen/debuginfo-inline-callsite-location.rs b/tests/codegen/debuginfo-inline-callsite-location.rs
new file mode 100644
index 00000000000..e2ea9dda4a0
--- /dev/null
+++ b/tests/codegen/debuginfo-inline-callsite-location.rs
@@ -0,0 +1,26 @@
+// compile-flags: -g -O
+
+// Check that each inline call site for the same function uses the same "sub-program" so that LLVM
+// can correctly merge the debug info if it merges the inlined code (e.g., for merging of tail
+// calls to panic.
+
+// CHECK:       tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E
+// CHECK-SAME:  !dbg ![[#first_dbg:]]
+// CHECK:       tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E
+// CHECK-SAME:  !dbg ![[#second_dbg:]]
+
+// CHECK:       ![[#func_dbg:]] = distinct !DISubprogram(name: "unwrap<i32>"
+// CHECK:       ![[#first_dbg]] = !DILocation(line: [[#]]
+// CHECK-SAME:  scope: ![[#func_dbg]], inlinedAt: ![[#]])
+// CHECK:       ![[#second_dbg]] = !DILocation(line: [[#]]
+// CHECK-SAME:  scope: ![[#func_dbg]], inlinedAt: ![[#]])
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+extern "C" fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 {
+    let x1 = x.unwrap();
+    let y1 = y.unwrap();
+
+    x1 + y1
+}
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 da608e180c5..2d8b13e2080 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
@@ -500,12 +500,12 @@ pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { }
 // CHECK: ![[TYPE45]] = !{i64 0, !"_ZTSFvu5usizeE"}
 // CHECK: ![[TYPE46]] = !{i64 0, !"_ZTSFvu5usizeS_E"}
 // CHECK: ![[TYPE47]] = !{i64 0, !"_ZTSFvu5usizeS_S_E"}
-// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvu3f32E"}
-// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvu3f32S_E"}
-// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvu3f32S_S_E"}
-// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvu3f64E"}
-// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvu3f64S_E"}
-// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvu3f64S_S_E"}
+// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvfE"}
+// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvffE"}
+// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvfffE"}
+// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvdE"}
+// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvddE"}
+// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvdddE"}
 // CHECK: ![[TYPE54]] = !{i64 0, !"_ZTSFvu4charE"}
 // CHECK: ![[TYPE55]] = !{i64 0, !"_ZTSFvu4charS_E"}
 // CHECK: ![[TYPE56]] = !{i64 0, !"_ZTSFvu4charS_S_E"}
diff --git a/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
index a59ffe97bf0..6c3128f8c36 100644
--- a/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
+++ b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
@@ -9,7 +9,7 @@ fn main() -> () {
     bb0: {
         StorageLive(_1);
         _1 = const ();
-        asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind terminate];
+        asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind terminate(abi)];
     }
 
     bb1: {
diff --git a/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff b/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff
index 15269fb8f6c..f187f959727 100644
--- a/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff
+++ b/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff
@@ -47,7 +47,7 @@
   
       bb2 (cleanup): {
           _5 = move _6;
--         drop(_6) -> [return: bb6, unwind terminate];
+-         drop(_6) -> [return: bb6, unwind terminate(cleanup)];
 +         goto -> bb6;
       }
   
@@ -71,12 +71,12 @@
       }
   
       bb6 (cleanup): {
--         drop(_5) -> [return: bb7, unwind terminate];
+-         drop(_5) -> [return: bb7, unwind terminate(cleanup)];
 +         goto -> bb7;
       }
   
       bb7 (cleanup): {
--         drop(_4) -> [return: bb8, unwind terminate];
+-         drop(_4) -> [return: bb8, unwind terminate(cleanup)];
 +         goto -> bb8;
       }
   
diff --git a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir
index a9bc2e89034..75070ffda11 100644
--- a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir
@@ -51,7 +51,7 @@ fn main() -> () {
 
     bb2 (cleanup): {
         _5 = move _6;
-        drop(_6) -> [return: bb6, unwind terminate];
+        drop(_6) -> [return: bb6, unwind terminate(cleanup)];
     }
 
     bb3: {
@@ -73,11 +73,11 @@ fn main() -> () {
     }
 
     bb6 (cleanup): {
-        drop(_5) -> [return: bb7, unwind terminate];
+        drop(_5) -> [return: bb7, unwind terminate(cleanup)];
     }
 
     bb7 (cleanup): {
-        drop(_4) -> [return: bb8, unwind terminate];
+        drop(_4) -> [return: bb8, unwind terminate(cleanup)];
     }
 
     bb8 (cleanup): {
diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir
index d196b045a1b..1c7ef7f8345 100644
--- a/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir
+++ b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-abort.mir
@@ -54,15 +54,15 @@ fn main() -> () {
     }
 
     bb6 (cleanup): {
-        drop(_7) -> [return: bb7, unwind terminate];
+        drop(_7) -> [return: bb7, unwind terminate(cleanup)];
     }
 
     bb7 (cleanup): {
-        drop(_1) -> [return: bb9, unwind terminate];
+        drop(_1) -> [return: bb9, unwind terminate(cleanup)];
     }
 
     bb8 (cleanup): {
-        drop(_5) -> [return: bb9, unwind terminate];
+        drop(_5) -> [return: bb9, unwind terminate(cleanup)];
     }
 
     bb9 (cleanup): {
diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir
index a72d22a9c9f..4ad1c2de129 100644
--- a/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/box_expr.main.ElaborateDrops.before.panic-unwind.mir
@@ -54,15 +54,15 @@ fn main() -> () {
     }
 
     bb6 (cleanup): {
-        drop(_7) -> [return: bb7, unwind terminate];
+        drop(_7) -> [return: bb7, unwind terminate(cleanup)];
     }
 
     bb7 (cleanup): {
-        drop(_1) -> [return: bb9, unwind terminate];
+        drop(_1) -> [return: bb9, unwind terminate(cleanup)];
     }
 
     bb8 (cleanup): {
-        drop(_5) -> [return: bb9, unwind terminate];
+        drop(_5) -> [return: bb9, unwind terminate(cleanup)];
     }
 
     bb9 (cleanup): {
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 1caf9e4a523..ea0edb610f5 100644
--- a/tests/mir-opt/building/enum_cast.droppy.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.droppy.built.after.mir
@@ -62,7 +62,7 @@ fn droppy() -> () {
     }
 
     bb4 (cleanup): {
-        drop(_2) -> [return: bb5, unwind terminate];
+        drop(_2) -> [return: bb5, unwind terminate(cleanup)];
     }
 
     bb5 (cleanup): {
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
index fea1138ba8d..82424de0392 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
@@ -89,15 +89,15 @@ fn move_out_by_subslice() -> () {
     }
 
     bb9 (cleanup): {
-        drop(_1) -> [return: bb12, unwind terminate];
+        drop(_1) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb10 (cleanup): {
-        drop(_7) -> [return: bb11, unwind terminate];
+        drop(_7) -> [return: bb11, unwind terminate(cleanup)];
     }
 
     bb11 (cleanup): {
-        drop(_2) -> [return: bb12, unwind terminate];
+        drop(_2) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
index 3def40a8578..0872d1b6ac0 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
@@ -89,15 +89,15 @@ fn move_out_from_end() -> () {
     }
 
     bb9 (cleanup): {
-        drop(_1) -> [return: bb12, unwind terminate];
+        drop(_1) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb10 (cleanup): {
-        drop(_7) -> [return: bb11, unwind terminate];
+        drop(_7) -> [return: bb11, unwind terminate(cleanup)];
     }
 
     bb11 (cleanup): {
-        drop(_2) -> [return: bb12, unwind terminate];
+        drop(_2) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
diff --git a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff
index 1a4372afe69..f2b87221f2b 100644
--- a/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff
+++ b/tests/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstSimplify.panic-unwind.diff
@@ -63,7 +63,7 @@
       }
   
       bb4 (cleanup): {
-          drop(_2) -> [return: bb5, unwind terminate];
+          drop(_2) -> [return: bb5, unwind terminate(cleanup)];
       }
   
       bb5 (cleanup): {
diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-abort.diff b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-abort.diff
new file mode 100644
index 00000000000..dc0f9073416
--- /dev/null
+++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-abort.diff
@@ -0,0 +1,15 @@
+- // MIR for `move_packed` before DeadStoreElimination
++ // MIR for `move_packed` after DeadStoreElimination
+  
+  fn move_packed(_1: Packed) -> () {
+      let mut _0: ();
+  
+      bb0: {
+          _0 = use_both(const 0_i32, (_1.1: i32)) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-unwind.diff b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-unwind.diff
new file mode 100644
index 00000000000..86ef026ec5c
--- /dev/null
+++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.move_packed.DeadStoreElimination.panic-unwind.diff
@@ -0,0 +1,15 @@
+- // MIR for `move_packed` before DeadStoreElimination
++ // MIR for `move_packed` after DeadStoreElimination
+  
+  fn move_packed(_1: Packed) -> () {
+      let mut _0: ();
+  
+      bb0: {
+          _0 = use_both(const 0_i32, (_1.1: i32)) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/dead-store-elimination/call_arg_copy.rs b/tests/mir-opt/dead-store-elimination/call_arg_copy.rs
index 41f91fc1306..f09cdee1482 100644
--- a/tests/mir-opt/dead-store-elimination/call_arg_copy.rs
+++ b/tests/mir-opt/dead-store-elimination/call_arg_copy.rs
@@ -2,6 +2,12 @@
 // unit-test: DeadStoreElimination
 // compile-flags: -Zmir-enable-passes=+CopyProp
 
+#![feature(core_intrinsics)]
+#![feature(custom_mir)]
+#![allow(internal_features)]
+
+use std::intrinsics::mir::*;
+
 #[inline(never)]
 fn use_both(_: i32, _: i32) {}
 
@@ -10,6 +16,26 @@ fn move_simple(x: i32) {
     use_both(x, x);
 }
 
+#[repr(packed)]
+struct Packed {
+    x: u8,
+    y: i32,
+}
+
+// EMIT_MIR call_arg_copy.move_packed.DeadStoreElimination.diff
+#[custom_mir(dialect = "analysis")]
+fn move_packed(packed: Packed) {
+    mir!(
+        {
+            Call(RET = use_both(0, packed.y), ret)
+        }
+        ret = {
+            Return()
+        }
+    )
+}
+
 fn main() {
     move_simple(1);
+    move_packed(Packed { x: 0, y: 1 });
 }
diff --git a/tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff
index 024d9bc7f51..8ac6acd0e4a 100644
--- a/tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff
+++ b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-abort.diff
@@ -28,7 +28,7 @@
       }
   
       bb4 (cleanup): {
-          drop(_2) -> [return: bb5, unwind terminate];
+          drop(_2) -> [return: bb5, unwind terminate(cleanup)];
       }
   
       bb5 (cleanup): {
diff --git a/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff
index 2ada087b4bd..aa9fcb505e6 100644
--- a/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff
+++ b/tests/mir-opt/derefer_inline_test.main.Derefer.panic-unwind.diff
@@ -28,7 +28,7 @@
       }
   
       bb4 (cleanup): {
-          drop(_2) -> [return: bb5, unwind terminate];
+          drop(_2) -> [return: bb5, unwind terminate(cleanup)];
       }
   
       bb5 (cleanup): {
diff --git a/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir
index 6a4c5436fce..6fcceb6c66b 100644
--- a/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir
+++ b/tests/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir
@@ -104,7 +104,7 @@ yields ()
 
     bb13 (cleanup): {
         StorageDead(_3);
-        drop(_1) -> [return: bb14, unwind terminate];
+        drop(_1) -> [return: bb14, unwind terminate(cleanup)];
     }
 
     bb14 (cleanup): {
@@ -113,6 +113,6 @@ yields ()
 
     bb15 (cleanup): {
         StorageDead(_3);
-        drop(_1) -> [return: bb14, unwind terminate];
+        drop(_1) -> [return: bb14, unwind terminate(cleanup)];
     }
 }
diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff
index 503dc5beb19..aa9429c46d8 100644
--- a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-abort.diff
@@ -17,7 +17,7 @@
           StorageLive(_1);
 -         _1 = foo() -> [return: bb1, unwind unreachable];
 +         StorageLive(_2);
-+         asm!("", options(MAY_UNWIND)) -> [return: bb2, unwind terminate];
++         asm!("", options(MAY_UNWIND)) -> [return: bb2, unwind terminate(abi)];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
index 684211b53b3..ea9c360aa7b 100644
--- a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
@@ -32,7 +32,7 @@
 +     }
 + 
 +     bb3 (cleanup): {
-+         drop(_2) -> [return: bb4, unwind terminate];
++         drop(_2) -> [return: bb4, unwind terminate(cleanup)];
 +     }
 + 
 +     bb4 (cleanup): {
diff --git a/tests/mir-opt/inline/cycle.f.Inline.panic-unwind.diff b/tests/mir-opt/inline/cycle.f.Inline.panic-unwind.diff
index f3a6ee22c20..b7fea4f2e14 100644
--- a/tests/mir-opt/inline/cycle.f.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/cycle.f.Inline.panic-unwind.diff
@@ -30,7 +30,7 @@
       }
   
       bb3 (cleanup): {
-          drop(_1) -> [return: bb4, unwind terminate];
+          drop(_1) -> [return: bb4, unwind terminate(cleanup)];
       }
   
       bb4 (cleanup): {
diff --git a/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
index ad801fd280a..1fd1014ba1d 100644
--- a/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
@@ -36,7 +36,7 @@
 +     }
 + 
 +     bb3 (cleanup): {
-+         drop(_2) -> [return: bb4, unwind terminate];
++         drop(_2) -> [return: bb4, unwind terminate(cleanup)];
 +     }
 + 
 +     bb4 (cleanup): {
diff --git a/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
index 99dc64115a9..e8299db47db 100644
--- a/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
@@ -36,7 +36,7 @@
 +     }
 + 
 +     bb3 (cleanup): {
-+         drop(_2) -> [return: bb4, unwind terminate];
++         drop(_2) -> [return: bb4, unwind terminate(cleanup)];
 +     }
 + 
 +     bb4 (cleanup): {
diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
index ef85e075eeb..b82961c2815 100644
--- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
@@ -27,7 +27,7 @@
       }
   
       bb3 (cleanup): {
-          drop(_1) -> [return: bb4, unwind terminate];
+          drop(_1) -> [return: bb4, unwind terminate(cleanup)];
       }
   
       bb4 (cleanup): {
diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
index 5df730a9930..47fd0ed0799 100644
--- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
@@ -30,7 +30,7 @@
       }
   
       bb3 (cleanup): {
-          drop(_1) -> [return: bb4, unwind terminate];
+          drop(_1) -> [return: bb4, unwind terminate(cleanup)];
       }
   
       bb4 (cleanup): {
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
index 073ddeff7ca..9f8c5806c90 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
@@ -54,11 +54,11 @@
 +     }
 + 
 +     bb4 (cleanup): {
-+         drop(_4) -> [return: bb5, unwind terminate];
++         drop(_4) -> [return: bb5, unwind terminate(cleanup)];
 +     }
 + 
 +     bb5 (cleanup): {
-+         drop(_2) -> [return: bb6, unwind terminate];
++         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
 +     }
 + 
 +     bb6 (cleanup): {
diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
index 54c33aac9e8..675292f06d6 100644
--- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff
@@ -155,7 +155,7 @@
 -         StorageDead(_1);
 -         return;
 +     bb3 (cleanup): {
-+         drop(_2) -> [return: bb2, unwind terminate];
++         drop(_2) -> [return: bb2, unwind terminate(cleanup)];
       }
   
 -     bb4 (cleanup): {
diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
index b750330df92..5a946712ea4 100644
--- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
@@ -37,7 +37,7 @@
       }
   
       bb4 (cleanup): {
-          drop(_1) -> [return: bb5, unwind terminate];
+          drop(_1) -> [return: bb5, unwind terminate(cleanup)];
       }
   
       bb5 (cleanup): {
diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff
index 7765e491d89..cbfb39115b3 100644
--- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff
@@ -40,7 +40,7 @@
       }
   
       bb4 (cleanup): {
-          drop(_1) -> [return: bb5, unwind terminate];
+          drop(_1) -> [return: bb5, unwind terminate(cleanup)];
       }
   
       bb5 (cleanup): {
diff --git a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff b/tests/mir-opt/inline/unsized_argument.caller.Inline.diff
index 6ee6a0ffe4c..ab81f707148 100644
--- a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff
+++ b/tests/mir-opt/inline/unsized_argument.caller.Inline.diff
@@ -40,7 +40,7 @@
   
       bb4 (cleanup): {
           _8 = &mut _3;
-          _9 = <Box<[i32]> as Drop>::drop(move _8) -> [return: bb1, unwind terminate];
+          _9 = <Box<[i32]> as Drop>::drop(move _8) -> [return: bb1, unwind terminate(cleanup)];
       }
   }
   
diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-abort.diff b/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-abort.diff
index 11501907b88..4469270a9b2 100644
--- a/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-abort.diff
+++ b/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-abort.diff
@@ -40,17 +40,17 @@
       }
   
       bb3 (cleanup): {
--         drop(_3) -> [return: bb5, unwind terminate];
+-         drop(_3) -> [return: bb5, unwind terminate(cleanup)];
 +         goto -> bb5;
       }
   
       bb4 (cleanup): {
--         drop(_4) -> [return: bb5, unwind terminate];
+-         drop(_4) -> [return: bb5, unwind terminate(cleanup)];
 +         goto -> bb5;
       }
   
       bb5 (cleanup): {
--         drop(_2) -> [return: bb6, unwind terminate];
+-         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
 +         goto -> bb8;
       }
   
@@ -59,7 +59,7 @@
 +     }
 + 
 +     bb7 (cleanup): {
-+         drop(_2) -> [return: bb6, unwind terminate];
++         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
 +     }
 + 
 +     bb8 (cleanup): {
diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff
index 11501907b88..4469270a9b2 100644
--- a/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff
+++ b/tests/mir-opt/issue_41110.main.ElaborateDrops.panic-unwind.diff
@@ -40,17 +40,17 @@
       }
   
       bb3 (cleanup): {
--         drop(_3) -> [return: bb5, unwind terminate];
+-         drop(_3) -> [return: bb5, unwind terminate(cleanup)];
 +         goto -> bb5;
       }
   
       bb4 (cleanup): {
--         drop(_4) -> [return: bb5, unwind terminate];
+-         drop(_4) -> [return: bb5, unwind terminate(cleanup)];
 +         goto -> bb5;
       }
   
       bb5 (cleanup): {
--         drop(_2) -> [return: bb6, unwind terminate];
+-         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
 +         goto -> bb8;
       }
   
@@ -59,7 +59,7 @@
 +     }
 + 
 +     bb7 (cleanup): {
-+         drop(_2) -> [return: bb6, unwind terminate];
++         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
 +     }
 + 
 +     bb8 (cleanup): {
diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff
index 65f4806aaf7..78184f6aeeb 100644
--- a/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff
+++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-abort.diff
@@ -47,7 +47,7 @@
   
       bb3 (cleanup): {
           _2 = move _5;
--         drop(_5) -> [return: bb8, unwind terminate];
+-         drop(_5) -> [return: bb8, unwind terminate(cleanup)];
 +         goto -> bb8;
       }
   
@@ -70,17 +70,17 @@
       }
   
       bb7 (cleanup): {
--         drop(_4) -> [return: bb8, unwind terminate];
+-         drop(_4) -> [return: bb8, unwind terminate(cleanup)];
 +         goto -> bb8;
       }
   
       bb8 (cleanup): {
--         drop(_2) -> [return: bb9, unwind terminate];
+-         drop(_2) -> [return: bb9, unwind terminate(cleanup)];
 +         goto -> bb9;
       }
   
       bb9 (cleanup): {
--         drop(_1) -> [return: bb10, unwind terminate];
+-         drop(_1) -> [return: bb10, unwind terminate(cleanup)];
 +         goto -> bb12;
       }
   
@@ -89,7 +89,7 @@
 +     }
 + 
 +     bb11 (cleanup): {
-+         drop(_1) -> [return: bb10, unwind terminate];
++         drop(_1) -> [return: bb10, unwind terminate(cleanup)];
 +     }
 + 
 +     bb12 (cleanup): {
diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff
index 4845fc732aa..688887c3c1f 100644
--- a/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff
+++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.panic-unwind.diff
@@ -47,7 +47,7 @@
   
       bb3 (cleanup): {
           _2 = move _5;
--         drop(_5) -> [return: bb8, unwind terminate];
+-         drop(_5) -> [return: bb8, unwind terminate(cleanup)];
 +         goto -> bb8;
       }
   
@@ -70,17 +70,17 @@
       }
   
       bb7 (cleanup): {
--         drop(_4) -> [return: bb8, unwind terminate];
+-         drop(_4) -> [return: bb8, unwind terminate(cleanup)];
 +         goto -> bb8;
       }
   
       bb8 (cleanup): {
--         drop(_2) -> [return: bb9, unwind terminate];
+-         drop(_2) -> [return: bb9, unwind terminate(cleanup)];
 +         goto -> bb9;
       }
   
       bb9 (cleanup): {
--         drop(_1) -> [return: bb10, unwind terminate];
+-         drop(_1) -> [return: bb10, unwind terminate(cleanup)];
 +         goto -> bb12;
       }
   
@@ -89,7 +89,7 @@
 +     }
 + 
 +     bb11 (cleanup): {
-+         drop(_1) -> [return: bb10, unwind terminate];
++         drop(_1) -> [return: bb10, unwind terminate(cleanup)];
 +     }
 + 
 +     bb12 (cleanup): {
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff
index aca7fe95c18..b57fe348c2d 100644
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff
@@ -58,7 +58,7 @@
 +         _8 = const true;
 +         _9 = const true;
           _1 = move _3;
--         drop(_3) -> [return: bb11, unwind terminate];
+-         drop(_3) -> [return: bb11, unwind terminate(cleanup)];
 +         goto -> bb11;
       }
   
@@ -102,7 +102,7 @@
       }
   
       bb11 (cleanup): {
--         drop(_1) -> [return: bb12, unwind terminate];
+-         drop(_1) -> [return: bb12, unwind terminate(cleanup)];
 +         goto -> bb12;
       }
   
@@ -124,7 +124,7 @@
 +     }
 + 
 +     bb16 (cleanup): {
-+         drop(_1) -> [return: bb12, unwind terminate];
++         drop(_1) -> [return: bb12, unwind terminate(cleanup)];
 +     }
 + 
 +     bb17: {
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
index 60ce9cd8ad9..2156850e38c 100644
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
@@ -58,7 +58,7 @@
 +         _8 = const true;
 +         _9 = const true;
           _1 = move _3;
--         drop(_3) -> [return: bb11, unwind terminate];
+-         drop(_3) -> [return: bb11, unwind terminate(cleanup)];
 +         goto -> bb11;
       }
   
@@ -102,7 +102,7 @@
       }
   
       bb11 (cleanup): {
--         drop(_1) -> [return: bb12, unwind terminate];
+-         drop(_1) -> [return: bb12, unwind terminate(cleanup)];
 +         goto -> bb12;
       }
   
@@ -124,7 +124,7 @@
 +     }
 + 
 +     bb16 (cleanup): {
-+         drop(_1) -> [return: bb12, unwind terminate];
++         drop(_1) -> [return: bb12, unwind terminate(cleanup)];
 +     }
 + 
 +     bb17: {
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
index ae0beffae18..73462967850 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
@@ -100,11 +100,11 @@ fn test() -> Option<Box<u32>> {
     }
 
     bb11 (cleanup): {
-        drop(_1) -> [return: bb13, unwind terminate];
+        drop(_1) -> [return: bb13, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
-        drop(_5) -> [return: bb13, unwind terminate];
+        drop(_5) -> [return: bb13, unwind terminate(cleanup)];
     }
 
     bb13 (cleanup): {
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
index 7ecdc428e59..8264e2cabbc 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
@@ -100,11 +100,11 @@ fn test() -> Option<Box<u32>> {
     }
 
     bb11 (cleanup): {
-        drop(_1) -> [return: bb13, unwind terminate];
+        drop(_1) -> [return: bb13, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
-        drop(_5) -> [return: bb13, unwind terminate];
+        drop(_5) -> [return: bb13, unwind terminate(cleanup)];
     }
 
     bb13 (cleanup): {
diff --git a/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir
index 92f52e138a5..cce1a1fd2ef 100644
--- a/tests/mir-opt/issue_91633.bar.built.after.mir
+++ b/tests/mir-opt/issue_91633.bar.built.after.mir
@@ -28,7 +28,7 @@ fn bar(_1: Box<[T]>) -> () {
     }
 
     bb3 (cleanup): {
-        drop(_1) -> [return: bb4, unwind terminate];
+        drop(_1) -> [return: bb4, unwind terminate(cleanup)];
     }
 
     bb4 (cleanup): {
diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir
index 4529c58a137..a66769f0d11 100644
--- a/tests/mir-opt/issue_91633.foo.built.after.mir
+++ b/tests/mir-opt/issue_91633.foo.built.after.mir
@@ -45,7 +45,7 @@ fn foo(_1: Box<[T]>) -> T {
     }
 
     bb5 (cleanup): {
-        drop(_1) -> [return: bb6, unwind terminate];
+        drop(_1) -> [return: bb6, unwind terminate(cleanup)];
     }
 
     bb6 (cleanup): {
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index be09ed641b8..3e817ff433b 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -243,7 +243,7 @@
       }
   
 -     bb25 (cleanup): {
--         drop(_2) -> [return: bb26, unwind terminate];
+-         drop(_2) -> [return: bb26, unwind terminate(cleanup)];
 +     bb22 (cleanup): {
 +         goto -> bb27;
       }
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index be09ed641b8..3e817ff433b 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -243,7 +243,7 @@
       }
   
 -     bb25 (cleanup): {
--         drop(_2) -> [return: bb26, unwind terminate];
+-         drop(_2) -> [return: bb26, unwind terminate(cleanup)];
 +     bb22 (cleanup): {
 +         goto -> bb27;
       }
diff --git a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir
index e22fc7d54bc..99a7a6b6154 100644
--- a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir
+++ b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-abort.mir
@@ -31,7 +31,7 @@ fn main() -> () {
     }
 
     bb3 (cleanup): {
-        drop(_2) -> [return: bb4, unwind terminate];
+        drop(_2) -> [return: bb4, unwind terminate(cleanup)];
     }
 
     bb4 (cleanup): {
diff --git a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir
index 6fb107929e6..7364b329e12 100644
--- a/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.panic-unwind.mir
@@ -31,7 +31,7 @@ fn main() -> () {
     }
 
     bb3 (cleanup): {
-        drop(_2) -> [return: bb4, unwind terminate];
+        drop(_2) -> [return: bb4, unwind terminate(cleanup)];
     }
 
     bb4 (cleanup): {
diff --git a/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index bc04790028d..0ef19180459 100644
--- a/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -33,7 +33,7 @@ fn main() -> () {
 
     bb1 (cleanup): {
         (_1.0: Aligned) = move _4;
-        drop(_1) -> [return: bb3, unwind terminate];
+        drop(_1) -> [return: bb3, unwind terminate(cleanup)];
     }
 
     bb2: {
diff --git a/tests/mir-opt/pre-codegen/chained_comparison.rs b/tests/mir-opt/pre-codegen/chained_comparison.rs
index f7879140f81..43030041983 100644
--- a/tests/mir-opt/pre-codegen/chained_comparison.rs
+++ b/tests/mir-opt/pre-codegen/chained_comparison.rs
@@ -1,5 +1,4 @@
 // compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2
-// ignore-debug
 
 #![crate_type = "lib"]
 
diff --git a/tests/mir-opt/pre-codegen/checked_ops.rs b/tests/mir-opt/pre-codegen/checked_ops.rs
index dee43b0c6f8..23d78e98777 100644
--- a/tests/mir-opt/pre-codegen/checked_ops.rs
+++ b/tests/mir-opt/pre-codegen/checked_ops.rs
@@ -1,6 +1,5 @@
 // compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2
 // needs-unwind
-// ignore-debug
 // only-x86_64
 
 #![crate_type = "lib"]
diff --git a/tests/mir-opt/pre-codegen/intrinsics.rs b/tests/mir-opt/pre-codegen/intrinsics.rs
index ecdb656cb85..e32e04384c4 100644
--- a/tests/mir-opt/pre-codegen/intrinsics.rs
+++ b/tests/mir-opt/pre-codegen/intrinsics.rs
@@ -1,6 +1,5 @@
 // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 // only-64bit
-// ignore-debug
 
 // Checks that we do not have any branches in the MIR for the two tested functions.
 
diff --git a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
index 940b9ae1156..4db829a5ec3 100644
--- a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
@@ -83,7 +83,7 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
     }
 
     bb9 (cleanup): {
-        drop(_5) -> [return: bb10, unwind terminate];
+        drop(_5) -> [return: bb10, unwind terminate(cleanup)];
     }
 
     bb10 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
index 2614160363e..c30df7425d2 100644
--- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
@@ -75,7 +75,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
     }
 
     bb9 (cleanup): {
-        drop(_5) -> [return: bb10, unwind terminate];
+        drop(_5) -> [return: bb10, unwind terminate(cleanup)];
     }
 
     bb10 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/loops.rs b/tests/mir-opt/pre-codegen/loops.rs
index 67f549a511c..f3ba409229d 100644
--- a/tests/mir-opt/pre-codegen/loops.rs
+++ b/tests/mir-opt/pre-codegen/loops.rs
@@ -1,6 +1,5 @@
 // compile-flags: -O -Zmir-opt-level=2 -g
 // needs-unwind
-// ignore-debug
 
 #![crate_type = "lib"]
 
diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir
index 8eff46fb931..cb29473d762 100644
--- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir
@@ -67,7 +67,7 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
     }
 
     bb9 (cleanup): {
-        drop(_3) -> [return: bb10, unwind terminate];
+        drop(_3) -> [return: bb10, unwind terminate(cleanup)];
     }
 
     bb10 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/mem_replace.rs b/tests/mir-opt/pre-codegen/mem_replace.rs
index e5066c38b96..a139848bab2 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.rs
+++ b/tests/mir-opt/pre-codegen/mem_replace.rs
@@ -1,6 +1,6 @@
 // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 // only-64bit
-// ignore-debug
+// ignore-debug the standard library debug assertions leak into this test
 
 #![crate_type = "lib"]
 
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index 4d7c017dad4..35f7356d47a 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -127,7 +127,7 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     }
 
     bb11 (cleanup): {
-        drop(_3) -> [return: bb12, unwind terminate];
+        drop(_3) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
index bbab4e47a3a..a677e8b439f 100644
--- a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir
@@ -82,7 +82,7 @@ fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     }
 
     bb8 (cleanup): {
-        drop(_3) -> [return: bb9, unwind terminate];
+        drop(_3) -> [return: bb9, unwind terminate(cleanup)];
     }
 
     bb9 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/range_iter.rs b/tests/mir-opt/pre-codegen/range_iter.rs
index cabd9419e92..9552144787d 100644
--- a/tests/mir-opt/pre-codegen/range_iter.rs
+++ b/tests/mir-opt/pre-codegen/range_iter.rs
@@ -1,6 +1,5 @@
 // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 // only-64bit
-// ignore-debug
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 #![crate_type = "lib"]
diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir
index 68d78f74328..312565e45c3 100644
--- a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir
@@ -3,9 +3,9 @@
 fn ezmap(_1: Option<i32>) -> Option<i32> {
     debug x => _1;
     let mut _0: std::option::Option<i32>;
-    scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map.rs:18:12: 18:15]>) {
+    scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map.rs:17:12: 17:15]>) {
         debug slf => _1;
-        debug f => const ZeroSized: [closure@$DIR/simple_option_map.rs:18:12: 18:15];
+        debug f => const ZeroSized: [closure@$DIR/simple_option_map.rs:17:12: 17:15];
         let mut _2: isize;
         let _3: i32;
         let mut _4: i32;
diff --git a/tests/mir-opt/pre-codegen/simple_option_map.rs b/tests/mir-opt/pre-codegen/simple_option_map.rs
index fb3da68e4af..d4f28dda6c6 100644
--- a/tests/mir-opt/pre-codegen/simple_option_map.rs
+++ b/tests/mir-opt/pre-codegen/simple_option_map.rs
@@ -1,6 +1,5 @@
 // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 // only-64bit
-// ignore-debug
 
 #[inline(always)]
 fn map<T, U, F>(slf: Option<T>, f: F) -> Option<U>
diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs
index d80bff50c31..57ffb07e294 100644
--- a/tests/mir-opt/pre-codegen/slice_index.rs
+++ b/tests/mir-opt/pre-codegen/slice_index.rs
@@ -1,6 +1,6 @@
 // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 // only-64bit
-// ignore-debug
+// ignore-debug the standard library debug assertions leak into this test
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 #![crate_type = "lib"]
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index 836fa2677b1..3d76bab7ce7 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -195,7 +195,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb11 (cleanup): {
-        drop(_2) -> [return: bb12, unwind terminate];
+        drop(_2) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index 65baaf64a9e..e8586cec981 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -182,7 +182,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb11 (cleanup): {
-        drop(_2) -> [return: bb12, unwind terminate];
+        drop(_2) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index f7b19e80e44..8bd072fd625 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -143,7 +143,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb12 (cleanup): {
-        drop(_2) -> [return: bb13, unwind terminate];
+        drop(_2) -> [return: bb13, unwind terminate(cleanup)];
     }
 
     bb13 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index 43f8806e165..3cdc49f6056 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -196,7 +196,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb11 (cleanup): {
-        drop(_2) -> [return: bb12, unwind terminate];
+        drop(_2) -> [return: bb12, unwind terminate(cleanup)];
     }
 
     bb12 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.rs b/tests/mir-opt/pre-codegen/slice_iter.rs
index 4e954aa3433..1790056369c 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.rs
+++ b/tests/mir-opt/pre-codegen/slice_iter.rs
@@ -1,6 +1,6 @@
 // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 // only-64bit
-// ignore-debug
+// ignore-debug the standard library debug assertions leak into this test
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 #![crate_type = "lib"]
diff --git a/tests/mir-opt/pre-codegen/try_identity.rs b/tests/mir-opt/pre-codegen/try_identity.rs
index 079ecccab28..a227c82d6a3 100644
--- a/tests/mir-opt/pre-codegen/try_identity.rs
+++ b/tests/mir-opt/pre-codegen/try_identity.rs
@@ -1,6 +1,5 @@
 // compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
 // only-64bit
-// ignore-debug
 
 // Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings
 // of that syntax.
diff --git a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
index 508f964099a..7d3346faba6 100644
--- a/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.panic-unwind.mir
@@ -167,11 +167,11 @@ fn main() -> () {
     }
 
     bb7 (cleanup): {
-        drop(_21) -> [return: bb9, unwind terminate];
+        drop(_21) -> [return: bb9, unwind terminate(cleanup)];
     }
 
     bb8 (cleanup): {
-        drop(_5) -> [return: bb9, unwind terminate];
+        drop(_5) -> [return: bb9, unwind terminate(cleanup)];
     }
 
     bb9 (cleanup): {
diff --git a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
index 9bf69acd356..3a8b457a7a1 100644
--- a/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
@@ -24,7 +24,7 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
     bb3 (cleanup): {
         _4 = &raw mut (*_1)[_3];
         _3 = Add(move _3, const 1_usize);
-        drop((*_4)) -> [return: bb4, unwind terminate];
+        drop((*_4)) -> [return: bb4, unwind terminate(cleanup)];
     }
 
     bb4 (cleanup): {
diff --git a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
index ee90a540720..b5879418355 100644
--- a/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/unusual_item_types.core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
@@ -22,7 +22,7 @@ fn std::ptr::drop_in_place(_1: *mut Vec<i32>) -> () {
     }
 
     bb4 (cleanup): {
-        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb2, unwind terminate];
+        drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> [return: bb2, unwind terminate(cleanup)];
     }
 
     bb5: {
diff --git a/tests/run-coverage-rustdoc/doctest.coverage b/tests/run-coverage-rustdoc/doctest.coverage
index 07f1e6b3ee5..5797784f411 100644
--- a/tests/run-coverage-rustdoc/doctest.coverage
+++ b/tests/run-coverage-rustdoc/doctest.coverage
@@ -10,6 +10,8 @@ $DIR/auxiliary/doctest_crate.rs:
    LL|      3|}
 
 $DIR/doctest.rs:
+   LL|       |// aux-build:doctest_crate.rs
+   LL|       |
    LL|       |//! This test ensures that code from doctests is properly re-mapped.
    LL|       |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
    LL|       |//!
@@ -78,7 +80,7 @@ $DIR/doctest.rs:
    LL|       |//!     doctest_main()
    LL|       |//! }
    LL|       |//! ```
-   LL|       |// aux-build:doctest_crate.rs
+   LL|       |
    LL|       |/// doctest attached to fn testing external code:
    LL|       |/// ```
    LL|      1|/// extern crate doctest_crate;
diff --git a/tests/run-coverage-rustdoc/doctest.rs b/tests/run-coverage-rustdoc/doctest.rs
index 251b0c291e9..4006d723ce0 100644
--- a/tests/run-coverage-rustdoc/doctest.rs
+++ b/tests/run-coverage-rustdoc/doctest.rs
@@ -1,3 +1,5 @@
+// aux-build:doctest_crate.rs
+
 //! This test ensures that code from doctests is properly re-mapped.
 //! See <https://github.com/rust-lang/rust/issues/79417> for more info.
 //!
@@ -63,7 +65,7 @@
 //!     doctest_main()
 //! }
 //! ```
-// aux-build:doctest_crate.rs
+
 /// doctest attached to fn testing external code:
 /// ```
 /// extern crate doctest_crate;
diff --git a/tests/run-coverage/assert.coverage b/tests/run-coverage/assert.coverage
index 3c6108e436a..8b997724c4a 100644
--- a/tests/run-coverage/assert.coverage
+++ b/tests/run-coverage/assert.coverage
@@ -7,7 +7,7 @@
                                                   ^1
    LL|      3|}
    LL|       |
-   LL|      1|fn main() -> Result<(),u8> {
+   LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut countdown = 10;
    LL|     11|    while countdown > 0 {
    LL|     11|        if countdown == 1 {
diff --git a/tests/run-coverage/assert.rs b/tests/run-coverage/assert.rs
index d32a37e078e..85e6662a6ad 100644
--- a/tests/run-coverage/assert.rs
+++ b/tests/run-coverage/assert.rs
@@ -6,7 +6,7 @@ fn might_fail_assert(one_plus_one: u32) {
     assert_eq!(1 + 1, one_plus_one, "the argument was wrong");
 }
 
-fn main() -> Result<(),u8> {
+fn main() -> Result<(), u8> {
     let mut countdown = 10;
     while countdown > 0 {
         if countdown == 1 {
diff --git a/tests/run-coverage/async2.coverage b/tests/run-coverage/async2.coverage
index 7e0139ae036..fcb0a3aed64 100644
--- a/tests/run-coverage/async2.coverage
+++ b/tests/run-coverage/async2.coverage
@@ -1,11 +1,5 @@
    LL|       |// compile-flags: --edition=2018
    LL|       |
-   LL|       |use core::{
-   LL|       |    future::Future,
-   LL|       |    marker::Send,
-   LL|       |    pin::Pin,
-   LL|       |};
-   LL|       |
    LL|      1|fn non_async_func() {
    LL|      1|    println!("non_async_func was covered");
    LL|      1|    let b = true;
@@ -15,9 +9,6 @@
                    ^0
    LL|      1|}
    LL|       |
-   LL|       |
-   LL|       |
-   LL|       |
    LL|      1|async fn async_func() {
    LL|      1|    println!("async_func was covered");
    LL|      1|    let b = true;
@@ -27,9 +18,6 @@
                    ^0
    LL|      1|}
    LL|       |
-   LL|       |
-   LL|       |
-   LL|       |
    LL|      1|async fn async_func_just_println() {
    LL|      1|    println!("async_func_just_println was covered");
    LL|      1|}
diff --git a/tests/run-coverage/async2.rs b/tests/run-coverage/async2.rs
index 959d48ce9db..2884ff297af 100644
--- a/tests/run-coverage/async2.rs
+++ b/tests/run-coverage/async2.rs
@@ -1,11 +1,5 @@
 // compile-flags: --edition=2018
 
-use core::{
-    future::Future,
-    marker::Send,
-    pin::Pin,
-};
-
 fn non_async_func() {
     println!("non_async_func was covered");
     let b = true;
@@ -14,9 +8,6 @@ fn non_async_func() {
     }
 }
 
-
-
-
 async fn async_func() {
     println!("async_func was covered");
     let b = true;
@@ -25,9 +16,6 @@ async fn async_func() {
     }
 }
 
-
-
-
 async fn async_func_just_println() {
     println!("async_func_just_println was covered");
 }
diff --git a/tests/run-coverage/auxiliary/inline_always_with_dead_code.rs b/tests/run-coverage/auxiliary/inline_always_with_dead_code.rs
index 2b21dee6ccf..9dc50dae25a 100644
--- a/tests/run-coverage/auxiliary/inline_always_with_dead_code.rs
+++ b/tests/run-coverage/auxiliary/inline_always_with_dead_code.rs
@@ -4,9 +4,9 @@
 
 mod foo {
     #[inline(always)]
-    pub fn called() { }
+    pub fn called() {}
 
-    fn uncalled() { }
+    fn uncalled() {}
 }
 
 pub mod bar {
diff --git a/tests/run-coverage/auxiliary/unused_mod_helper.rs b/tests/run-coverage/auxiliary/unused_mod_helper.rs
index ae1cc1531ed..88c5dac65cb 100644
--- a/tests/run-coverage/auxiliary/unused_mod_helper.rs
+++ b/tests/run-coverage/auxiliary/unused_mod_helper.rs
@@ -1,3 +1,4 @@
+#[allow(dead_code)]
 pub fn never_called_function() {
     println!("I am never called");
 }
diff --git a/tests/run-coverage/auxiliary/used_crate.rs b/tests/run-coverage/auxiliary/used_crate.rs
index 16592d48dda..c086ef21e1a 100644
--- a/tests/run-coverage/auxiliary/used_crate.rs
+++ b/tests/run-coverage/auxiliary/used_crate.rs
@@ -1,6 +1,8 @@
 #![allow(unused_assignments, unused_variables)]
+// Verify that coverage works with optimizations:
 // compile-flags: -C opt-level=3
-use std::fmt::Debug; // ^^ validates coverage now works with optimizations
+
+use std::fmt::Debug;
 
 pub fn used_function() {
     // Initialize test constants in a way that cannot be determined at compile time, to ensure
@@ -42,6 +44,7 @@ pub fn unused_function() {
     }
 }
 
+#[allow(dead_code)]
 fn unused_private_function() {
     let is_true = std::env::args().len() == 1;
     let mut countdown = 2;
diff --git a/tests/run-coverage/auxiliary/used_inline_crate.rs b/tests/run-coverage/auxiliary/used_inline_crate.rs
index 8b8e9d5483f..e8929de6b36 100644
--- a/tests/run-coverage/auxiliary/used_inline_crate.rs
+++ b/tests/run-coverage/auxiliary/used_inline_crate.rs
@@ -1,7 +1,7 @@
 #![allow(unused_assignments, unused_variables)]
-
+// Verify that coverage works with optimizations:
 // compile-flags: -C opt-level=3
-// ^^ validates coverage now works with optimizations
+
 use std::fmt::Debug;
 
 pub fn used_function() {
@@ -29,12 +29,6 @@ pub fn used_inline_function() {
     use_this_lib_crate();
 }
 
-
-
-
-
-
-
 #[inline(always)]
 pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
     println!("used_only_from_bin_crate_generic_function with {:?}", arg);
@@ -71,6 +65,7 @@ pub fn unused_function() {
 }
 
 #[inline(always)]
+#[allow(dead_code)]
 fn unused_private_function() {
     let is_true = std::env::args().len() == 1;
     let mut countdown = 2;
diff --git a/tests/run-coverage/closure.coverage b/tests/run-coverage/closure.coverage
index 809cf1f4821..930348dc431 100644
--- a/tests/run-coverage/closure.coverage
+++ b/tests/run-coverage/closure.coverage
@@ -1,11 +1,16 @@
    LL|       |#![allow(unused_assignments, unused_variables)]
    LL|       |// compile-flags: -C opt-level=2
-   LL|      1|fn main() { // ^^ fix described in rustc_middle/mir/mono.rs
+   LL|       |
+   LL|       |// This test used to be sensitive to certain coverage-specific hacks in
+   LL|       |// `rustc_middle/mir/mono.rs`, but those hacks were later cleaned up by
+   LL|       |// <https://github.com/rust-lang/rust/pull/83666>.
+   LL|       |
+   LL|      1|fn main() {
    LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
    LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
    LL|      1|    // dependent conditions.
    LL|      1|    let is_true = std::env::args().len() == 1;
-   LL|      1|    let is_false = ! is_true;
+   LL|      1|    let is_false = !is_true;
    LL|      1|
    LL|      1|    let mut some_string = Some(String::from("the string content"));
    LL|      1|    println!(
diff --git a/tests/run-coverage/closure.rs b/tests/run-coverage/closure.rs
index eb3a1ebff88..16a2c4e33bd 100644
--- a/tests/run-coverage/closure.rs
+++ b/tests/run-coverage/closure.rs
@@ -1,11 +1,16 @@
 #![allow(unused_assignments, unused_variables)]
 // compile-flags: -C opt-level=2
-fn main() { // ^^ fix described in rustc_middle/mir/mono.rs
+
+// This test used to be sensitive to certain coverage-specific hacks in
+// `rustc_middle/mir/mono.rs`, but those hacks were later cleaned up by
+// <https://github.com/rust-lang/rust/pull/83666>.
+
+fn main() {
     // Initialize test constants in a way that cannot be determined at compile time, to ensure
     // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
     // dependent conditions.
     let is_true = std::env::args().len() == 1;
-    let is_false = ! is_true;
+    let is_false = !is_true;
 
     let mut some_string = Some(String::from("the string content"));
     println!(
diff --git a/tests/run-coverage/closure_macro_async.coverage b/tests/run-coverage/closure_macro_async.coverage
index 0e4365fc797..018e3160e4f 100644
--- a/tests/run-coverage/closure_macro_async.coverage
+++ b/tests/run-coverage/closure_macro_async.coverage
@@ -42,7 +42,7 @@
    LL|       |
    LL|       |#[no_coverage]
    LL|       |fn main() {
-   LL|       |    executor::block_on(test());
+   LL|       |    executor::block_on(test()).unwrap();
    LL|       |}
    LL|       |
    LL|       |mod executor {
@@ -57,16 +57,12 @@
    LL|       |        let mut future = unsafe { Pin::new_unchecked(&mut future) };
    LL|       |        use std::hint::unreachable_unchecked;
    LL|       |        static VTABLE: RawWakerVTable = RawWakerVTable::new(
-   LL|       |
    LL|       |            #[no_coverage]
    LL|       |            |_| unsafe { unreachable_unchecked() }, // clone
-   LL|       |
    LL|       |            #[no_coverage]
    LL|       |            |_| unsafe { unreachable_unchecked() }, // wake
-   LL|       |
    LL|       |            #[no_coverage]
    LL|       |            |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-   LL|       |
    LL|       |            #[no_coverage]
    LL|       |            |_| (),
    LL|       |        );
diff --git a/tests/run-coverage/closure_macro_async.rs b/tests/run-coverage/closure_macro_async.rs
index e3e89e9c8b3..3d6bdb38a2a 100644
--- a/tests/run-coverage/closure_macro_async.rs
+++ b/tests/run-coverage/closure_macro_async.rs
@@ -41,7 +41,7 @@ pub async fn test() -> Result<(), String> {
 
 #[no_coverage]
 fn main() {
-    executor::block_on(test());
+    executor::block_on(test()).unwrap();
 }
 
 mod executor {
@@ -56,16 +56,12 @@ mod executor {
         let mut future = unsafe { Pin::new_unchecked(&mut future) };
         use std::hint::unreachable_unchecked;
         static VTABLE: RawWakerVTable = RawWakerVTable::new(
-
             #[no_coverage]
             |_| unsafe { unreachable_unchecked() }, // clone
-
             #[no_coverage]
             |_| unsafe { unreachable_unchecked() }, // wake
-
             #[no_coverage]
             |_| unsafe { unreachable_unchecked() }, // wake_by_ref
-
             #[no_coverage]
             |_| (),
         );
diff --git a/tests/run-coverage/conditions.coverage b/tests/run-coverage/conditions.coverage
index 4749c353a64..473335ff641 100644
--- a/tests/run-coverage/conditions.coverage
+++ b/tests/run-coverage/conditions.coverage
@@ -59,7 +59,6 @@
    LL|       |        }
    LL|      0|    }
    LL|       |
-   LL|       |
    LL|      1|    let mut countdown = 0;
    LL|      1|    if true {
    LL|      1|        countdown = 1;
diff --git a/tests/run-coverage/conditions.rs b/tests/run-coverage/conditions.rs
index 057599d1b47..fa7f2a116c2 100644
--- a/tests/run-coverage/conditions.rs
+++ b/tests/run-coverage/conditions.rs
@@ -55,7 +55,6 @@ fn main() {
         }
     }
 
-
     let mut countdown = 0;
     if true {
         countdown = 1;
diff --git a/tests/run-coverage/dead_code.coverage b/tests/run-coverage/dead_code.coverage
index 5074d8b3c37..c4ee9f23f08 100644
--- a/tests/run-coverage/dead_code.coverage
+++ b/tests/run-coverage/dead_code.coverage
@@ -1,4 +1,4 @@
-   LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |#![allow(dead_code, unused_assignments, unused_variables)]
    LL|       |
    LL|      0|pub fn unused_pub_fn_not_in_library() {
    LL|      0|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
diff --git a/tests/run-coverage/dead_code.rs b/tests/run-coverage/dead_code.rs
index a1285df0ec6..3492712a6f9 100644
--- a/tests/run-coverage/dead_code.rs
+++ b/tests/run-coverage/dead_code.rs
@@ -1,4 +1,4 @@
-#![allow(unused_assignments, unused_variables)]
+#![allow(dead_code, unused_assignments, unused_variables)]
 
 pub fn unused_pub_fn_not_in_library() {
     // Initialize test constants in a way that cannot be determined at compile time, to ensure
diff --git a/tests/run-coverage/drop_trait.coverage b/tests/run-coverage/drop_trait.coverage
index c99b980a339..2c9439a93b1 100644
--- a/tests/run-coverage/drop_trait.coverage
+++ b/tests/run-coverage/drop_trait.coverage
@@ -11,7 +11,7 @@
    LL|      2|    }
    LL|       |}
    LL|       |
-   LL|      1|fn main() -> Result<(),u8> {
+   LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let _firecracker = Firework { strength: 1 };
    LL|      1|
    LL|      1|    let _tnt = Firework { strength: 100 };
diff --git a/tests/run-coverage/drop_trait.rs b/tests/run-coverage/drop_trait.rs
index a9b5d1d1e7f..7b062719c6b 100644
--- a/tests/run-coverage/drop_trait.rs
+++ b/tests/run-coverage/drop_trait.rs
@@ -11,7 +11,7 @@ impl Drop for Firework {
     }
 }
 
-fn main() -> Result<(),u8> {
+fn main() -> Result<(), u8> {
     let _firecracker = Firework { strength: 1 };
 
     let _tnt = Firework { strength: 100 };
diff --git a/tests/run-coverage/generics.coverage b/tests/run-coverage/generics.coverage
index 2ff8f917ed7..09839183566 100644
--- a/tests/run-coverage/generics.coverage
+++ b/tests/run-coverage/generics.coverage
@@ -41,7 +41,7 @@
   ------------------
    LL|       |}
    LL|       |
-   LL|      1|fn main() -> Result<(),u8> {
+   LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut firecracker = Firework { strength: 1 };
    LL|      1|    firecracker.set_strength(2);
    LL|      1|
@@ -54,10 +54,6 @@
    LL|      1|        return Err(1);
    LL|      0|    }
    LL|      0|
-   LL|      0|
-   LL|      0|
-   LL|      0|
-   LL|      0|
    LL|      0|    let _ = Firework { strength: 1000 };
    LL|      0|
    LL|      0|    Ok(())
diff --git a/tests/run-coverage/generics.rs b/tests/run-coverage/generics.rs
index 150ffb9db39..bf4c2d8d685 100644
--- a/tests/run-coverage/generics.rs
+++ b/tests/run-coverage/generics.rs
@@ -19,7 +19,7 @@ impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
     }
 }
 
-fn main() -> Result<(),u8> {
+fn main() -> Result<(), u8> {
     let mut firecracker = Firework { strength: 1 };
     firecracker.set_strength(2);
 
@@ -32,10 +32,6 @@ fn main() -> Result<(),u8> {
         return Err(1);
     }
 
-
-
-
-
     let _ = Firework { strength: 1000 };
 
     Ok(())
diff --git a/tests/run-coverage/issue-85461.coverage b/tests/run-coverage/issue-85461.coverage
index f97ab230387..cbc910664d0 100644
--- a/tests/run-coverage/issue-85461.coverage
+++ b/tests/run-coverage/issue-85461.coverage
@@ -5,9 +5,9 @@ $DIR/auxiliary/inline_always_with_dead_code.rs:
    LL|       |
    LL|       |mod foo {
    LL|       |    #[inline(always)]
-   LL|      2|    pub fn called() { }
+   LL|      2|    pub fn called() {}
    LL|       |
-   LL|      0|    fn uncalled() { }
+   LL|      0|    fn uncalled() {}
    LL|       |}
    LL|       |
    LL|       |pub mod bar {
@@ -24,6 +24,7 @@ $DIR/auxiliary/inline_always_with_dead_code.rs:
 
 $DIR/issue-85461.rs:
    LL|       |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
+   LL|       |
    LL|       |// aux-build:inline_always_with_dead_code.rs
    LL|       |extern crate inline_always_with_dead_code;
    LL|       |
diff --git a/tests/run-coverage/issue-85461.rs b/tests/run-coverage/issue-85461.rs
index 6f626b4a65b..9d4c90a827e 100644
--- a/tests/run-coverage/issue-85461.rs
+++ b/tests/run-coverage/issue-85461.rs
@@ -1,4 +1,5 @@
 // Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
+
 // aux-build:inline_always_with_dead_code.rs
 extern crate inline_always_with_dead_code;
 
diff --git a/tests/run-coverage/issue-93054.coverage b/tests/run-coverage/issue-93054.coverage
index 074e6b9835a..15f225326a4 100644
--- a/tests/run-coverage/issue-93054.coverage
+++ b/tests/run-coverage/issue-93054.coverage
@@ -1,29 +1,31 @@
+   LL|       |#![allow(dead_code, unreachable_code)]
+   LL|       |
    LL|       |// Regression test for #93054: Functions using uninhabited types often only have a single,
    LL|       |// unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
    LL|       |// Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
    LL|       |
    LL|       |// compile-flags: --edition=2021
    LL|       |
-   LL|       |enum Never { }
+   LL|       |enum Never {}
    LL|       |
    LL|       |impl Never {
    LL|       |    fn foo(self) {
-   LL|       |        match self { }
-   LL|       |        make().map(|never| match never { });
+   LL|       |        match self {}
+   LL|       |        make().map(|never| match never {});
    LL|       |    }
    LL|       |
    LL|       |    fn bar(&self) {
-   LL|       |        match *self { }
+   LL|       |        match *self {}
    LL|       |    }
    LL|       |}
    LL|       |
    LL|      0|async fn foo2(never: Never) {
-   LL|       |    match never { }
+   LL|       |    match never {}
    LL|       |}
    LL|       |
    LL|      0|fn make() -> Option<Never> {
    LL|      0|    None
    LL|      0|}
    LL|       |
-   LL|      1|fn main() { }
+   LL|      1|fn main() {}
 
diff --git a/tests/run-coverage/issue-93054.rs b/tests/run-coverage/issue-93054.rs
index c160b3db03f..da546cfeef8 100644
--- a/tests/run-coverage/issue-93054.rs
+++ b/tests/run-coverage/issue-93054.rs
@@ -1,28 +1,30 @@
+#![allow(dead_code, unreachable_code)]
+
 // Regression test for #93054: Functions using uninhabited types often only have a single,
 // unreachable basic block which doesn't get instrumented. This should not cause llvm-cov to fail.
 // Since these kinds functions can't be invoked anyway, it's ok to not have coverage data for them.
 
 // compile-flags: --edition=2021
 
-enum Never { }
+enum Never {}
 
 impl Never {
     fn foo(self) {
-        match self { }
-        make().map(|never| match never { });
+        match self {}
+        make().map(|never| match never {});
     }
 
     fn bar(&self) {
-        match *self { }
+        match *self {}
     }
 }
 
 async fn foo2(never: Never) {
-    match never { }
+    match never {}
 }
 
 fn make() -> Option<Never> {
     None
 }
 
-fn main() { }
+fn main() {}
diff --git a/tests/run-coverage/loops_branches.coverage b/tests/run-coverage/loops_branches.coverage
index 148a22377f3..8cd6f1be3f7 100644
--- a/tests/run-coverage/loops_branches.coverage
+++ b/tests/run-coverage/loops_branches.coverage
@@ -9,8 +9,7 @@
    LL|      1|    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    LL|      1|        if true {
    LL|      1|            if false {
-   LL|      0|                while true {
-   LL|      0|                }
+   LL|      0|                while true {}
    LL|      1|            }
    LL|      1|            write!(f, "cool")?;
                                            ^0
diff --git a/tests/run-coverage/loops_branches.rs b/tests/run-coverage/loops_branches.rs
index 7116ce47f4b..f3a343bcc1f 100644
--- a/tests/run-coverage/loops_branches.rs
+++ b/tests/run-coverage/loops_branches.rs
@@ -9,8 +9,7 @@ impl std::fmt::Debug for DebugTest {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         if true {
             if false {
-                while true {
-                }
+                while true {}
             }
             write!(f, "cool")?;
         } else {
diff --git a/tests/run-coverage/match_or_pattern.coverage b/tests/run-coverage/match_or_pattern.coverage
index 0b5a2c03dd3..94c7967215c 100644
--- a/tests/run-coverage/match_or_pattern.coverage
+++ b/tests/run-coverage/match_or_pattern.coverage
@@ -1,5 +1,3 @@
-   LL|       |#![feature(or_patterns)]
-   LL|       |
    LL|      1|fn main() {
    LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
    LL|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
diff --git a/tests/run-coverage/match_or_pattern.rs b/tests/run-coverage/match_or_pattern.rs
index 4c6a8a9b703..ab7aee51d1b 100644
--- a/tests/run-coverage/match_or_pattern.rs
+++ b/tests/run-coverage/match_or_pattern.rs
@@ -1,5 +1,3 @@
-#![feature(or_patterns)]
-
 fn main() {
     // Initialize test constants in a way that cannot be determined at compile time, to ensure
     // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
diff --git a/tests/run-coverage/no_cov_crate.coverage b/tests/run-coverage/no_cov_crate.coverage
index c34dbde888a..73f6fbd0c2b 100644
--- a/tests/run-coverage/no_cov_crate.coverage
+++ b/tests/run-coverage/no_cov_crate.coverage
@@ -12,6 +12,7 @@
    LL|       |}
    LL|       |
    LL|       |#[no_coverage]
+   LL|       |#[allow(dead_code)]
    LL|       |fn do_not_add_coverage_not_called() {
    LL|       |    println!("not called and not covered");
    LL|       |}
@@ -24,6 +25,7 @@
    LL|      1|    println!("called and covered");
    LL|      1|}
    LL|       |
+   LL|       |#[allow(dead_code)]
    LL|      0|fn add_coverage_not_called() {
    LL|      0|    println!("not called but covered");
    LL|      0|}
diff --git a/tests/run-coverage/no_cov_crate.rs b/tests/run-coverage/no_cov_crate.rs
index 0bfbdda2cab..5b748aeefb7 100644
--- a/tests/run-coverage/no_cov_crate.rs
+++ b/tests/run-coverage/no_cov_crate.rs
@@ -12,6 +12,7 @@ fn do_not_add_coverage_2() {
 }
 
 #[no_coverage]
+#[allow(dead_code)]
 fn do_not_add_coverage_not_called() {
     println!("not called and not covered");
 }
@@ -24,6 +25,7 @@ fn add_coverage_2() {
     println!("called and covered");
 }
 
+#[allow(dead_code)]
 fn add_coverage_not_called() {
     println!("not called but covered");
 }
diff --git a/tests/run-coverage/overflow.coverage b/tests/run-coverage/overflow.coverage
index 2d60316e215..cee076e88cd 100644
--- a/tests/run-coverage/overflow.coverage
+++ b/tests/run-coverage/overflow.coverage
@@ -12,7 +12,7 @@
    LL|      4|    result
    LL|      4|}
    LL|       |
-   LL|      1|fn main() -> Result<(),u8> {
+   LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut countdown = 10;
    LL|     11|    while countdown > 0 {
    LL|     11|        if countdown == 1 {
diff --git a/tests/run-coverage/overflow.rs b/tests/run-coverage/overflow.rs
index 7df8de6f3cd..bbb65c1b35d 100644
--- a/tests/run-coverage/overflow.rs
+++ b/tests/run-coverage/overflow.rs
@@ -12,7 +12,7 @@ fn might_overflow(to_add: u32) -> u32 {
     result
 }
 
-fn main() -> Result<(),u8> {
+fn main() -> Result<(), u8> {
     let mut countdown = 10;
     while countdown > 0 {
         if countdown == 1 {
diff --git a/tests/run-coverage/try_error_result.coverage b/tests/run-coverage/try_error_result.coverage
index fcdb7437d00..5d48cbd62f2 100644
--- a/tests/run-coverage/try_error_result.coverage
+++ b/tests/run-coverage/try_error_result.coverage
@@ -1,7 +1,7 @@
    LL|       |#![allow(unused_assignments)]
    LL|       |// failure-status: 1
    LL|       |
-   LL|      6|fn call(return_error: bool) -> Result<(),()> {
+   LL|      6|fn call(return_error: bool) -> Result<(), ()> {
    LL|      6|    if return_error {
    LL|      1|        Err(())
    LL|       |    } else {
@@ -9,7 +9,7 @@
    LL|       |    }
    LL|      6|}
    LL|       |
-   LL|      1|fn test1() -> Result<(),()> {
+   LL|      1|fn test1() -> Result<(), ()> {
    LL|      1|    let mut
    LL|      1|        countdown = 10
    LL|       |    ;
@@ -38,18 +38,18 @@
    LL|       |
    LL|       |struct Thing1;
    LL|       |impl Thing1 {
-   LL|     18|    fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
+   LL|     18|    fn get_thing_2(&self, return_error: bool) -> Result<Thing2, ()> {
    LL|     18|        if return_error {
    LL|      1|            Err(())
    LL|       |        } else {
-   LL|     17|            Ok(Thing2{})
+   LL|     17|            Ok(Thing2 {})
    LL|       |        }
    LL|     18|    }
    LL|       |}
    LL|       |
    LL|       |struct Thing2;
    LL|       |impl Thing2 {
-   LL|     17|    fn call(&self, return_error: bool) -> Result<u32,()> {
+   LL|     17|    fn call(&self, return_error: bool) -> Result<u32, ()> {
    LL|     17|        if return_error {
    LL|      2|            Err(())
    LL|       |        } else {
@@ -58,7 +58,7 @@
    LL|     17|    }
    LL|       |}
    LL|       |
-   LL|      1|fn test2() -> Result<(),()> {
+   LL|      1|fn test2() -> Result<(), ()> {
    LL|      1|    let thing1 = Thing1{};
    LL|      1|    let mut
    LL|      1|        countdown = 10
@@ -115,7 +115,7 @@
    LL|      0|    Ok(())
    LL|      1|}
    LL|       |
-   LL|      1|fn main() -> Result<(),()> {
+   LL|      1|fn main() -> Result<(), ()> {
    LL|      1|    test1().expect_err("test1 should fail");
    LL|      1|    test2()
    LL|      1|    ?
diff --git a/tests/run-coverage/try_error_result.rs b/tests/run-coverage/try_error_result.rs
index 9eb1d2db218..557cbf22bfa 100644
--- a/tests/run-coverage/try_error_result.rs
+++ b/tests/run-coverage/try_error_result.rs
@@ -1,7 +1,7 @@
 #![allow(unused_assignments)]
 // failure-status: 1
 
-fn call(return_error: bool) -> Result<(),()> {
+fn call(return_error: bool) -> Result<(), ()> {
     if return_error {
         Err(())
     } else {
@@ -9,7 +9,7 @@ fn call(return_error: bool) -> Result<(),()> {
     }
 }
 
-fn test1() -> Result<(),()> {
+fn test1() -> Result<(), ()> {
     let mut
         countdown = 10
     ;
@@ -37,18 +37,18 @@ fn test1() -> Result<(),()> {
 
 struct Thing1;
 impl Thing1 {
-    fn get_thing_2(&self, return_error: bool) -> Result<Thing2,()> {
+    fn get_thing_2(&self, return_error: bool) -> Result<Thing2, ()> {
         if return_error {
             Err(())
         } else {
-            Ok(Thing2{})
+            Ok(Thing2 {})
         }
     }
 }
 
 struct Thing2;
 impl Thing2 {
-    fn call(&self, return_error: bool) -> Result<u32,()> {
+    fn call(&self, return_error: bool) -> Result<u32, ()> {
         if return_error {
             Err(())
         } else {
@@ -57,7 +57,7 @@ impl Thing2 {
     }
 }
 
-fn test2() -> Result<(),()> {
+fn test2() -> Result<(), ()> {
     let thing1 = Thing1{};
     let mut
         countdown = 10
@@ -109,7 +109,7 @@ fn test2() -> Result<(),()> {
     Ok(())
 }
 
-fn main() -> Result<(),()> {
+fn main() -> Result<(), ()> {
     test1().expect_err("test1 should fail");
     test2()
     ?
diff --git a/tests/run-coverage/unused.coverage b/tests/run-coverage/unused.coverage
index ba25e34bf86..056ffeb021a 100644
--- a/tests/run-coverage/unused.coverage
+++ b/tests/run-coverage/unused.coverage
@@ -1,3 +1,5 @@
+   LL|       |#![allow(dead_code, unused_assignments, unused_must_use, unused_variables)]
+   LL|       |
    LL|      2|fn foo<T>(x: T) {
    LL|      2|    let mut i = 0;
    LL|     22|    while i < 10 {
diff --git a/tests/run-coverage/unused.rs b/tests/run-coverage/unused.rs
index fb6113eb01c..d985af13547 100644
--- a/tests/run-coverage/unused.rs
+++ b/tests/run-coverage/unused.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code, unused_assignments, unused_must_use, unused_variables)]
+
 fn foo<T>(x: T) {
     let mut i = 0;
     while i < 10 {
diff --git a/tests/run-coverage/unused_mod.coverage b/tests/run-coverage/unused_mod.coverage
index 558dfaa5cff..a8fa24ac6a7 100644
--- a/tests/run-coverage/unused_mod.coverage
+++ b/tests/run-coverage/unused_mod.coverage
@@ -1,4 +1,5 @@
 $DIR/auxiliary/unused_mod_helper.rs:
+   LL|       |#[allow(dead_code)]
    LL|      0|pub fn never_called_function() {
    LL|      0|    println!("I am never called");
    LL|      0|}
diff --git a/tests/run-coverage/uses_crate.coverage b/tests/run-coverage/uses_crate.coverage
index 9da096dbd50..50d92102a10 100644
--- a/tests/run-coverage/uses_crate.coverage
+++ b/tests/run-coverage/uses_crate.coverage
@@ -1,7 +1,9 @@
 $DIR/auxiliary/used_crate.rs:
    LL|       |#![allow(unused_assignments, unused_variables)]
+   LL|       |// Verify that coverage works with optimizations:
    LL|       |// compile-flags: -C opt-level=3
-   LL|       |use std::fmt::Debug; // ^^ validates coverage now works with optimizations
+   LL|       |
+   LL|       |use std::fmt::Debug;
    LL|       |
    LL|      1|pub fn used_function() {
    LL|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
@@ -90,6 +92,7 @@ $DIR/auxiliary/used_crate.rs:
    LL|      0|    }
    LL|      0|}
    LL|       |
+   LL|       |#[allow(dead_code)]
    LL|      0|fn unused_private_function() {
    LL|      0|    let is_true = std::env::args().len() == 1;
    LL|      0|    let mut countdown = 2;
diff --git a/tests/run-coverage/uses_inline_crate.coverage b/tests/run-coverage/uses_inline_crate.coverage
index 48493e2079c..cc0e01ffde1 100644
--- a/tests/run-coverage/uses_inline_crate.coverage
+++ b/tests/run-coverage/uses_inline_crate.coverage
@@ -1,8 +1,8 @@
 $DIR/auxiliary/used_inline_crate.rs:
    LL|       |#![allow(unused_assignments, unused_variables)]
-   LL|       |
+   LL|       |// Verify that coverage works with optimizations:
    LL|       |// compile-flags: -C opt-level=3
-   LL|       |// ^^ validates coverage now works with optimizations
+   LL|       |
    LL|       |use std::fmt::Debug;
    LL|       |
    LL|      1|pub fn used_function() {
@@ -32,12 +32,6 @@ $DIR/auxiliary/used_inline_crate.rs:
    LL|      1|    use_this_lib_crate();
    LL|      1|}
    LL|       |
-   LL|       |
-   LL|       |
-   LL|       |
-   LL|       |
-   LL|       |
-   LL|       |
    LL|       |#[inline(always)]
    LL|      2|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
    LL|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
@@ -120,6 +114,7 @@ $DIR/auxiliary/used_inline_crate.rs:
    LL|      0|}
    LL|       |
    LL|       |#[inline(always)]
+   LL|       |#[allow(dead_code)]
    LL|      0|fn unused_private_function() {
    LL|      0|    let is_true = std::env::args().len() == 1;
    LL|      0|    let mut countdown = 2;
diff --git a/tests/run-coverage/while_early_ret.coverage b/tests/run-coverage/while_early_ret.coverage
index 97808447ab7..49d39d36603 100644
--- a/tests/run-coverage/while_early_ret.coverage
+++ b/tests/run-coverage/while_early_ret.coverage
@@ -1,7 +1,7 @@
    LL|       |#![allow(unused_assignments)]
    LL|       |// failure-status: 1
    LL|       |
-   LL|      1|fn main() -> Result<(),u8> {
+   LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut countdown = 10;
    LL|       |    while
    LL|      7|        countdown
diff --git a/tests/run-coverage/while_early_ret.rs b/tests/run-coverage/while_early_ret.rs
index 1c83c8fc7a8..b2f0eee2cc0 100644
--- a/tests/run-coverage/while_early_ret.rs
+++ b/tests/run-coverage/while_early_ret.rs
@@ -1,7 +1,7 @@
 #![allow(unused_assignments)]
 // failure-status: 1
 
-fn main() -> Result<(),u8> {
+fn main() -> Result<(), u8> {
     let mut countdown = 10;
     while
         countdown
diff --git a/tests/run-coverage/yield.coverage b/tests/run-coverage/yield.coverage
index 383dd991500..90c2641a7d6 100644
--- a/tests/run-coverage/yield.coverage
+++ b/tests/run-coverage/yield.coverage
@@ -7,7 +7,7 @@
    LL|      1|fn main() {
    LL|      1|    let mut generator = || {
    LL|      1|        yield 1;
-   LL|      1|        return "foo"
+   LL|      1|        return "foo";
    LL|      1|    };
    LL|       |
    LL|      1|    match Pin::new(&mut generator).resume(()) {
@@ -23,7 +23,7 @@
    LL|      1|        yield 1;
    LL|      1|        yield 2;
    LL|      0|        yield 3;
-   LL|      0|        return "foo"
+   LL|      0|        return "foo";
    LL|      0|    };
    LL|       |
    LL|      1|    match Pin::new(&mut generator).resume(()) {
diff --git a/tests/run-coverage/yield.rs b/tests/run-coverage/yield.rs
index ff7616656ff..361275c9215 100644
--- a/tests/run-coverage/yield.rs
+++ b/tests/run-coverage/yield.rs
@@ -7,7 +7,7 @@ use std::pin::Pin;
 fn main() {
     let mut generator = || {
         yield 1;
-        return "foo"
+        return "foo";
     };
 
     match Pin::new(&mut generator).resume(()) {
@@ -23,7 +23,7 @@ fn main() {
         yield 1;
         yield 2;
         yield 3;
-        return "foo"
+        return "foo";
     };
 
     match Pin::new(&mut generator).resume(()) {
diff --git a/tests/run-make/issue-88756-default-output/output-default.stdout b/tests/run-make/issue-88756-default-output/output-default.stdout
index b280698230d..de8ff0e5f89 100644
--- a/tests/run-make/issue-88756-default-output/output-default.stdout
+++ b/tests/run-make/issue-88756-default-output/output-default.stdout
@@ -191,6 +191,8 @@ Options:
                         removed, see issue #44136
                         <https://github.com/rust-lang/rust/issues/44136> for
                         more information
+        --html-no-source 
+                        Disable HTML source code pages generation
 
     @path               Read newline separated options from `path`
 
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index 574cc629a04..913d72932b9 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -67,7 +67,7 @@ assert-text: (".sidebar-elems section ul > li:nth-child(5)", "Enums")
 assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Constants")
 assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Traits")
 assert-text: (".sidebar-elems section ul > li:nth-child(8)", "Functions")
-assert-text: (".sidebar-elems section ul > li:nth-child(9)", "Type Definitions")
+assert-text: (".sidebar-elems section ul > li:nth-child(9)", "Type Aliases")
 assert-text: (".sidebar-elems section ul > li:nth-child(10)", "Unions")
 assert-text: (".sidebar-elems section ul > li:nth-child(11)", "Keywords")
 assert-text: ("#structs + .item-table .item-name > a", "Foo")
@@ -102,7 +102,7 @@ assert-text: (".sidebar-elems > section ul.block > li:nth-child(1)", "Modules")
 assert-text: (".sidebar-elems > section ul.block > li:nth-child(2)", "Structs")
 assert-text: (".sidebar-elems > section ul.block > li:nth-child(3)", "Traits")
 assert-text: (".sidebar-elems > section ul.block > li:nth-child(4)", "Functions")
-assert-text: (".sidebar-elems > section ul.block > li:nth-child(5)", "Type Definitions")
+assert-text: (".sidebar-elems > section ul.block > li:nth-child(5)", "Type Aliases")
 assert-text: ("#functions + .item-table .item-name > a", "foobar")
 click: "#functions + .item-table .item-name > a"
 
diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs
index 49484ee0869..38180aef762 100644
--- a/tests/rustdoc-gui/src/test_docs/lib.rs
+++ b/tests/rustdoc-gui/src/test_docs/lib.rs
@@ -65,6 +65,18 @@ impl Foo {
     pub fn must_use(&self) -> bool {
         true
     }
+
+    /// hello
+    ///
+    /// <div id="doc-warning-1" class="warning">this is a warning</div>
+    ///
+    /// done
+    pub fn warning1() {}
+
+    /// Checking there is no bottom margin if "warning" is the last element.
+    ///
+    /// <div id="doc-warning-2" class="warning">this is a warning</div>
+    pub fn warning2() {}
 }
 
 impl AsRef<str> for Foo {
diff --git a/tests/rustdoc-gui/warning-block.goml b/tests/rustdoc-gui/warning-block.goml
new file mode 100644
index 00000000000..2a935bd1a9b
--- /dev/null
+++ b/tests/rustdoc-gui/warning-block.goml
@@ -0,0 +1,45 @@
+// Test to check that the "warning blocks" are displayed as expected.
+go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
+show-text: true
+
+define-function: (
+    "check-warning",
+    (theme, color, border_color, background_color),
+    block {
+        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
+        reload:
+
+        // The IDs are added directly into the DOM to make writing this test easier.
+        assert-css: ("#doc-warning-1", {
+            "margin-bottom": "12px",
+            "color": |color|,
+            "border-left": "2px solid " + |border_color|,
+            "background-color": |background_color|,
+        })
+        assert-css: ("#doc-warning-2", {
+            "margin-bottom": "0px",
+            "color": |color|,
+            "border-left": "2px solid " + |border_color|,
+            "background-color": |background_color|,
+        })
+    },
+)
+
+call-function: ("check-warning", {
+    "theme": "ayu",
+    "color": "rgb(197, 197, 197)",
+    "border_color": "rgb(255, 142, 0)",
+    "background_color": "rgba(0, 0, 0, 0)",
+})
+call-function: ("check-warning", {
+    "theme": "dark",
+    "color": "rgb(221, 221, 221)",
+    "border_color": "rgb(255, 142, 0)",
+    "background_color": "rgba(0, 0, 0, 0)",
+})
+call-function: ("check-warning", {
+    "theme": "light",
+    "color": "rgb(0, 0, 0)",
+    "border_color": "rgb(255, 142, 0)",
+    "background_color": "rgba(0, 0, 0, 0)",
+})
diff --git a/tests/rustdoc-json/fn_pointer/abi.rs b/tests/rustdoc-json/fn_pointer/abi.rs
index 77c0e82330f..dbe316f573d 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.typedef.type.function_pointer.header.abi" \"Rust\"
+// @is "$.index[*][?(@.name=='AbiRust')].inner.type_alias.type.function_pointer.header.abi" \"Rust\"
 pub type AbiRust = fn();
 
-// @is "$.index[*][?(@.name=='AbiC')].inner.typedef.type.function_pointer.header.abi" '{"C": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='AbiC')].inner.type_alias.type.function_pointer.header.abi" '{"C": {"unwind": false}}'
 pub type AbiC = extern "C" fn();
 
-// @is "$.index[*][?(@.name=='AbiSystem')].inner.typedef.type.function_pointer.header.abi" '{"System": {"unwind": false}}'
+// @is "$.index[*][?(@.name=='AbiSystem')].inner.type_alias.type.function_pointer.header.abi" '{"System": {"unwind": false}}'
 pub type AbiSystem = extern "system" fn();
 
-// @is "$.index[*][?(@.name=='AbiCUnwind')].inner.typedef.type.function_pointer.header.abi" '{"C": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='AbiCUnwind')].inner.type_alias.type.function_pointer.header.abi" '{"C": {"unwind": true}}'
 pub type AbiCUnwind = extern "C-unwind" fn();
 
-// @is "$.index[*][?(@.name=='AbiSystemUnwind')].inner.typedef.type.function_pointer.header.abi" '{"System": {"unwind": true}}'
+// @is "$.index[*][?(@.name=='AbiSystemUnwind')].inner.type_alias.type.function_pointer.header.abi" '{"System": {"unwind": true}}'
 pub type AbiSystemUnwind = extern "system-unwind" fn();
 
-// @is "$.index[*][?(@.name=='AbiVecorcall')].inner.typedef.type.function_pointer.header.abi.Other" '"\"vectorcall\""'
+// @is "$.index[*][?(@.name=='AbiVecorcall')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall\""'
 pub type AbiVecorcall = extern "vectorcall" fn();
 
-// @is "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.typedef.type.function_pointer.header.abi.Other" '"\"vectorcall-unwind\""'
+// @is "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.type_alias.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 48672f12da1..3b82561ec7d 100644
--- a/tests/rustdoc-json/fn_pointer/generics.rs
+++ b/tests/rustdoc-json/fn_pointer/generics.rs
@@ -3,11 +3,11 @@
 #![feature(no_core)]
 #![no_core]
 
-// @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": [] } }'
+// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.decl.inputs[*]" 1
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.decl.inputs[0][0]" '"val"'
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.decl.inputs[0][1].borrowed_ref.lifetime" \"\'c\"
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.decl.output.primitive" \"i32\"
+// @count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[*]" 1
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[0].name" \"\'c\"
+// @is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.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 0ab776c21ed..1a62eb2bae8 100644
--- a/tests/rustdoc-json/fn_pointer/qualifiers.rs
+++ b/tests/rustdoc-json/fn_pointer/qualifiers.rs
@@ -1,11 +1,11 @@
 // 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
+// @is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.unsafe" false
+// @is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.const" false
+// @is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.async" false
 pub type FnPointer = fn();
 
-// @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
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.unsafe" true
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.const" false
+// @is "$.index[*][?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.async" false
 pub type UnsafePointer = unsafe fn();
diff --git a/tests/rustdoc-json/primitives/primitive_type.rs b/tests/rustdoc-json/primitives/primitive_type.rs
index 5f251b3b890..89c5d06c0b2 100644
--- a/tests/rustdoc-json/primitives/primitive_type.rs
+++ b/tests/rustdoc-json/primitives/primitive_type.rs
@@ -1,17 +1,17 @@
 #![feature(never_type)]
 
 // @is "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
-// @is "$.index[*][?(@.name=='PrimNever')].inner.typedef.type.primitive" \"never\"
+// @is "$.index[*][?(@.name=='PrimNever')].inner.type_alias.type.primitive" \"never\"
 pub type PrimNever = !;
 
-// @is "$.index[*][?(@.name=='PrimStr')].inner.typedef.type.primitive" \"str\"
+// @is "$.index[*][?(@.name=='PrimStr')].inner.type_alias.type.primitive" \"str\"
 pub type PrimStr = str;
 
-// @is "$.index[*][?(@.name=='PrimBool')].inner.typedef.type.primitive" \"bool\"
+// @is "$.index[*][?(@.name=='PrimBool')].inner.type_alias.type.primitive" \"bool\"
 pub type PrimBool = bool;
 
-// @is "$.index[*][?(@.name=='PrimChar')].inner.typedef.type.primitive" \"char\"
+// @is "$.index[*][?(@.name=='PrimChar')].inner.type_alias.type.primitive" \"char\"
 pub type PrimChar = char;
 
-// @is "$.index[*][?(@.name=='PrimU8')].inner.typedef.type.primitive" \"u8\"
+// @is "$.index[*][?(@.name=='PrimU8')].inner.type_alias.type.primitive" \"u8\"
 pub type PrimU8 = u8;
diff --git a/tests/rustdoc-json/type/dyn.rs b/tests/rustdoc-json/type/dyn.rs
index e5ee60fad59..4db65b61dc6 100644
--- a/tests/rustdoc-json/type/dyn.rs
+++ b/tests/rustdoc-json/type/dyn.rs
@@ -7,40 +7,40 @@ use std::fmt::Debug;
 // @set weird_order  = "$.index[*][?(@.name=='WeirdOrder')].id"
 // @ismany "$.index[*][?(@.name=='dyn')].inner.module.items[*]" $sync_int_gen $ref_fn $weird_order
 
-// @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"}}}'
+// @has    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.generics" '{"params": [], "where_predicates": []}'
+// @has    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.name" \"Box\"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.bindings" []
+// @count "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args" 1
+// @has    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait"
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.lifetime" \"\'static\"
+// @count "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[*]" 3
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].generic_params" []
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].generic_params" []
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].generic_params" []
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.name" '"Fn"'
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].trait.name" '"Send"'
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].trait.name" '"Sync"'
+// @is    "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.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>;
 
-// @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\""
+// @has "$.index[*][?(@.name=='RefFn')].inner.type_alias"
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.generics" '{"params": [{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"}],"where_predicates": []}'
+// @has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref"
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.mutable" 'false'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.lifetime" "\"'a\""
+// @has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait"
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.lifetime" null
+// @count "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[*]" 1
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.name" '"Fn"'
+// @has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref"
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref.lifetime" "\"'b\""
+// @has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.output.borrowed_ref"
+// @is "$.index[*][?(@.name=='RefFn')].inner.type_alias.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.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"'
+// @is    "$.index[*][?(@.name=='WeirdOrder')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.name" '"Send"'
+// @is    "$.index[*][?(@.name=='WeirdOrder')].inner.type_alias.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/fn_lifetime.rs b/tests/rustdoc-json/type/fn_lifetime.rs
index 424c5dce273..4aca303e6dc 100644
--- a/tests/rustdoc-json/type/fn_lifetime.rs
+++ b/tests/rustdoc-json/type/fn_lifetime.rs
@@ -1,26 +1,26 @@
 // ignore-tidy-linelength
 
-// @has "$.index[*][?(@.name=='GenericFn')].inner.typedef"
+// @has "$.index[*][?(@.name=='GenericFn')].inner.type_alias"
 
-// @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\"
+// @ismany "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].name" \"\'a\"
+// @has    "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].kind.lifetime"
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].kind.lifetime.outlives[*]" 0
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.where_predicates[*]" 0
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.generic_params[*]" 0
+// @count  "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.decl.inputs[*]" 1
+// @is     "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.decl.inputs[*][1].borrowed_ref.lifetime" \"\'a\"
+// @is     "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.decl.output.borrowed_ref.lifetime" \"\'a\"
 
 pub type GenericFn<'a> = fn(&'a i32) -> &'a i32;
 
-// @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\"
+// @has    "$.index[*][?(@.name=='ForAll')].inner.type_alias"
+// @count "$.index[*][?(@.name=='ForAll')].inner.type_alias.generics.params[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.type_alias.generics.where_predicates[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*]" 1
+// @is    "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].name" \"\'a\"
+// @has   "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].kind.lifetime"
+// @count "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].kind.lifetime.outlives[*]" 0
+// @count "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.decl.inputs[*]" 1
+// @is    "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.decl.inputs[*][1].borrowed_ref.lifetime" \"\'a\"
+// @is    "$.index[*][?(@.name=='ForAll')].inner.type_alias.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 b4642874532..30817a42e8a 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 {}
 
-// @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\"
+// @has    "$.index[*][?(@.name=='MyResult')].inner.type_alias"
+// @count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.where_predicates[*]" 0
+// @count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[*]" 2
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].name" \"T\"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].name" \"E\"
+// @has   "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type"
+// @has   "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type"
+// @count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type.bounds[*]" 0
+// @count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.bounds[*]" 0
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type.default" null
+// @has    "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path.id" $my_error
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path.name" \"MyError\"
+// @has    "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.id" $result
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.name" \"Result\"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.bindings" []
+// @has    "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.generic"
+// @has    "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[1].type.generic"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.generic" \"T\"
+// @is    "$.index[*][?(@.name=='MyResult')].inner.type_alias.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-ui/lints/redundant_explicit_links-utf8.rs b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs
new file mode 100644
index 00000000000..fecefb7b25f
--- /dev/null
+++ b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+/// [`…foo`] [`…bar`] [`Err`]
+pub struct Broken {}
+
+/// [`…`] [`…`] [`Err`]
+pub struct Broken2 {}
+
+/// [`…`][…] [`…`][…] [`Err`]
+pub struct Broken3 {}
+
+/// […………………………][Broken3]
+pub struct Broken4 {}
+
+/// [Broken3][…………………………]
+pub struct Broken5 {}
+
+pub struct Err;
diff --git a/tests/rustdoc/html-no-source.rs b/tests/rustdoc/html-no-source.rs
new file mode 100644
index 00000000000..25615a73c3f
--- /dev/null
+++ b/tests/rustdoc/html-no-source.rs
@@ -0,0 +1,30 @@
+// compile-flags: -Zunstable-options --html-no-source
+
+// This test ensures that the `--html-no-source` flag disables
+// the creation of the `src` folder.
+
+#![feature(staged_api)]
+#![stable(feature = "bar", since = "1.0")]
+#![crate_name = "foo"]
+
+// Ensures that there is no items in the corresponding "src" folder.
+// @files 'src/foo' '[]'
+
+// @has foo/fn.foo.html
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · '
+// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+#[stable(feature = "bar", since = "1.0")]
+pub fn foo() {}
+
+// @has foo/struct.Bar.html
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · '
+// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+#[stable(feature = "bar", since = "1.0")]
+pub struct Bar;
+
+impl Bar {
+    // @has - '//*[@id="method.bar"]/*[@class="since rightside"]' '2.0'
+    // @!has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0 ·'
+    #[stable(feature = "foobar", since = "2.0")]
+    pub fn bar() {}
+}
diff --git a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs
index 91082483948..5d2c553d8a5 100644
--- a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs
+++ b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs
@@ -8,7 +8,7 @@
 // @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8'
 // We also ensure we don't have another item displayed.
 // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Definitions'
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases'
 // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants'
 
 mod other {
diff --git a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
index b0c22540180..3b836a21931 100644
--- a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
+++ b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
@@ -104,7 +104,7 @@ pub mod glob_reexport {
     // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
     // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
     // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Definitions'
+    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases'
 
     // Now we check we have 1 re-export and 2 inlined items.
     // If not item from a glob re-export is visible, we don't show the re-export.
@@ -135,9 +135,9 @@ pub mod doc_hidden_reexport {
     // @has - '//a[@class="struct"]' 'Reexport'
     // Check that the `#[doc(hidden)]` re-export's attributes are not taken into account.
     // @has - '//*[@class="desc docblock-short"]' 'Visible. Original.'
+    /// Visible.
+    pub use self::Bar3 as Reexport;
     /// Hidden.
     #[doc(hidden)]
     pub use crate::private::Bar3;
-    /// Visible.
-    pub use self::Bar3 as Reexport;
 }
diff --git a/tests/rustdoc/sidebar-all-page.rs b/tests/rustdoc/sidebar-all-page.rs
index 45a6ba8ed2e..4c8a0f543a5 100644
--- a/tests/rustdoc/sidebar-all-page.rs
+++ b/tests/rustdoc/sidebar-all-page.rs
@@ -1,5 +1,4 @@
 #![crate_name = "foo"]
-
 #![feature(rustc_attrs)]
 
 // @has 'foo/all.html'
@@ -9,7 +8,7 @@
 // @has - '//*[@class="sidebar-elems"]//li' 'Functions'
 // @has - '//*[@class="sidebar-elems"]//li' 'Traits'
 // @has - '//*[@class="sidebar-elems"]//li' 'Macros'
-// @has - '//*[@class="sidebar-elems"]//li' 'Type Definitions'
+// @has - '//*[@class="sidebar-elems"]//li' 'Type Aliases'
 // @has - '//*[@class="sidebar-elems"]//li' 'Constants'
 // @has - '//*[@class="sidebar-elems"]//li' 'Statics'
 // @has - '//*[@class="sidebar-elems"]//li' 'Primitive Types'
@@ -26,7 +25,7 @@ pub fn foo() {}
 pub trait Trait {}
 #[macro_export]
 macro_rules! foo {
-    () => {}
+    () => {};
 }
 pub type Type = u8;
 pub const FOO: u8 = 0;
diff --git a/tests/rustdoc/titles.rs b/tests/rustdoc/titles.rs
index e1feb1cd64f..f6a059de620 100644
--- a/tests/rustdoc/titles.rs
+++ b/tests/rustdoc/titles.rs
@@ -30,7 +30,7 @@ pub struct FooStruct;
 // @matches 'foo/enum.FooEnum.html' '//h2[@class="location"]' 'FooEnum'
 pub enum FooEnum {}
 
-// @matches 'foo/type.FooType.html' '//h1' 'Type Definition foo::FooType'
+// @matches 'foo/type.FooType.html' '//h1' 'Type Alias foo::FooType'
 // @matches 'foo/type.FooType.html' '//h2[@class="location"]' 'FooType'
 pub type FooType = FooStruct;
 
diff --git a/tests/ui/abi/explicit_repr_rust.rs b/tests/ui/abi/explicit_repr_rust.rs
new file mode 100644
index 00000000000..4f8cab3bf0e
--- /dev/null
+++ b/tests/ui/abi/explicit_repr_rust.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#[repr(Rust)]
+struct A;
+
+#[repr(Rust, align(16))]
+struct B;
+
+#[repr(Rust, packed)]
+struct C;
+
+fn main() {}
diff --git a/tests/ui/associated-consts/associated-const-array-len.stderr b/tests/ui/associated-consts/associated-const-array-len.stderr
index 86c62e7b7f1..0e0dec35b53 100644
--- a/tests/ui/associated-consts/associated-const-array-len.stderr
+++ b/tests/ui/associated-consts/associated-const-array-len.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/associated-const-array-len.rs:5:16
+  --> $DIR/associated-const-array-len.rs:5:17
    |
 LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2];
-   |                ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
+   |                 ^^^ the trait `Foo` is not implemented for `i32`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
index 40896c32e11..1e0b77b0d3b 100644
--- a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
+++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
@@ -5,6 +5,8 @@ trait Trait {
 impl Trait for () {
     const ASSOC: &dyn Fn(_) = 1i32;
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
+    //~| WARN `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
 fn main() {}
diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
index 993a08faba9..f8c02420f96 100644
--- a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
+++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
@@ -1,9 +1,23 @@
+warning: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:18
+   |
+LL |     const ASSOC: &dyn Fn(_) = 1i32;
+   |                  ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+   = note: `#[warn(elided_lifetimes_in_associated_constant)]` on by default
+help: use the `'static` lifetime
+   |
+LL |     const ASSOC: &'static dyn Fn(_) = 1i32;
+   |                   +++++++
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:26
    |
 LL |     const ASSOC: &dyn Fn(_) = 1i32;
    |                          ^ not allowed in type signatures
 
-error: aborting due to previous error
+error: aborting due to previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0121`.
diff --git a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs
new file mode 100644
index 00000000000..3853bc8594f
--- /dev/null
+++ b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs
@@ -0,0 +1,12 @@
+#![allow(bare_trait_objects)]
+#![feature(associated_type_bounds)]
+trait Item {
+    type Core;
+}
+pub struct Flatten<I> {
+    inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
+    //~^ ERROR E0191
+    //~| ERROR E0223
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
new file mode 100644
index 00000000000..61299550e98
--- /dev/null
+++ b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
@@ -0,0 +1,24 @@
+error[E0191]: the value of the associated types `IntoIter` (from trait `IntoIterator`), `IntoIter` (from trait `IntoIterator`), `Item` (from trait `IntoIterator`), `Item` (from trait `IntoIterator`) must be specified
+  --> $DIR/overlaping-bound-suggestion.rs:7:13
+   |
+LL |     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             |                  |
+   |             |                  associated types `Item`, `IntoIter` must be specified
+   |             associated types `Item`, `IntoIter` must be specified
+
+error[E0223]: ambiguous associated type
+  --> $DIR/overlaping-bound-suggestion.rs:7:13
+   |
+LL |     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `IntoIterator` implemented for `(dyn IntoIterator + 'static)`, you could use the fully-qualified path
+   |
+LL |     inner: <<(dyn IntoIterator + 'static) as Example>::IntoIterator as Item>::Core,
+   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0191, E0223.
+For more information about an error, try `rustc --explain E0191`.
diff --git a/tests/ui/associated-types/issue-44153.stderr b/tests/ui/associated-types/issue-44153.stderr
index 8bddcd95568..73365d64d56 100644
--- a/tests/ui/associated-types/issue-44153.stderr
+++ b/tests/ui/associated-types/issue-44153.stderr
@@ -1,8 +1,8 @@
 error[E0271]: type mismatch resolving `<() as Array>::Element == &()`
-  --> $DIR/issue-44153.rs:18:5
+  --> $DIR/issue-44153.rs:18:6
    |
 LL |     <() as Visit>::visit();
-   |     ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Array>::Element == &()`
+   |      ^^ type mismatch resolving `<() as Array>::Element == &()`
    |
 note: expected this to be `&()`
   --> $DIR/issue-44153.rs:10:20
diff --git a/tests/ui/associated-types/substs-ppaux.normal.stderr b/tests/ui/associated-types/substs-ppaux.normal.stderr
index acdc3be8c67..015b22f790f 100644
--- a/tests/ui/associated-types/substs-ppaux.normal.stderr
+++ b/tests/ui/associated-types/substs-ppaux.normal.stderr
@@ -71,10 +71,10 @@ LL |     let x: () = foo::<'static>();
    |                               ++
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/substs-ppaux.rs:49:5
+  --> $DIR/substs-ppaux.rs:49:6
    |
 LL |     <str as Foo<u8>>::bar;
-   |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |      ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
 note: required for `str` to implement `Foo<'_, '_, u8>`
diff --git a/tests/ui/associated-types/substs-ppaux.verbose.stderr b/tests/ui/associated-types/substs-ppaux.verbose.stderr
index ad67899e6da..484581b1028 100644
--- a/tests/ui/associated-types/substs-ppaux.verbose.stderr
+++ b/tests/ui/associated-types/substs-ppaux.verbose.stderr
@@ -71,10 +71,10 @@ LL |     let x: () = foo::<'static>();
    |                               ++
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/substs-ppaux.rs:49:5
+  --> $DIR/substs-ppaux.rs:49:6
    |
 LL |     <str as Foo<u8>>::bar;
-   |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |      ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
 note: required for `str` to implement `Foo<'?0, '?1, u8>`
diff --git a/tests/ui/backtrace.rs b/tests/ui/backtrace.rs
index 66b378f62d6..95783945529 100644
--- a/tests/ui/backtrace.rs
+++ b/tests/ui/backtrace.rs
@@ -100,14 +100,17 @@ fn runtest(me: &str) {
         let s = str::from_utf8(&out.stderr).unwrap();
         // loosened the following from double::h to double:: due to
         // spurious failures on mac, 32bit, optimized
-        assert!(s.contains("stack backtrace") && contains_verbose_expected(s, "double"),
-                "bad output3: {}", s);
+        assert!(
+            s.contains("stack backtrace") &&
+                s.contains("panic in a destructor during cleanup") &&
+                contains_verbose_expected(s, "double"),
+            "bad output3: {}", s
+        );
 
         // Make sure a stack trace isn't printed too many times
         //
-        // Currently it is printed 3 times ("once", "twice" and "panic in a
-        // function that cannot unwind") but in the future the last one may be
-        // removed.
+        // Currently it is printed 3 times ("once", "twice" and "panic in a destructor during
+        // cleanup") but in the future the last one may be removed.
         let p = template(me).arg("double-fail")
                                     .env("RUST_BACKTRACE", "1").spawn().unwrap();
         let out = p.wait_with_output().unwrap();
diff --git a/tests/ui/borrowck/suggest-mut-iterator.fixed b/tests/ui/borrowck/suggest-mut-iterator.fixed
new file mode 100644
index 00000000000..16512b8a3cd
--- /dev/null
+++ b/tests/ui/borrowck/suggest-mut-iterator.fixed
@@ -0,0 +1,30 @@
+// run-rustfix
+struct Test {
+    a: u32
+}
+
+impl Test {
+    pub fn add(&mut self, value: u32) {
+        self.a += value;
+    }
+
+    pub fn print_value(&self) {
+        println!("Value of a is: {}", self.a);
+    }
+}
+
+fn main() {
+    let mut tests = Vec::new();
+    for i in 0..=10 {
+        tests.push(Test {a: i});
+    }
+    for test in &mut tests {
+        test.add(2); //~ ERROR cannot borrow `*test` as mutable, as it is behind a `&` reference
+    }
+    for test in &mut tests {
+        test.add(2);
+    }
+    for test in &tests {
+        test.print_value();
+    }
+}
diff --git a/tests/ui/borrowck/suggest-mut-iterator.rs b/tests/ui/borrowck/suggest-mut-iterator.rs
new file mode 100644
index 00000000000..276edeccb22
--- /dev/null
+++ b/tests/ui/borrowck/suggest-mut-iterator.rs
@@ -0,0 +1,30 @@
+// run-rustfix
+struct Test {
+    a: u32
+}
+
+impl Test {
+    pub fn add(&mut self, value: u32) {
+        self.a += value;
+    }
+
+    pub fn print_value(&self) {
+        println!("Value of a is: {}", self.a);
+    }
+}
+
+fn main() {
+    let mut tests = Vec::new();
+    for i in 0..=10 {
+        tests.push(Test {a: i});
+    }
+    for test in &tests {
+        test.add(2); //~ ERROR cannot borrow `*test` as mutable, as it is behind a `&` reference
+    }
+    for test in &mut tests {
+        test.add(2);
+    }
+    for test in &tests {
+        test.print_value();
+    }
+}
diff --git a/tests/ui/borrowck/suggest-mut-iterator.stderr b/tests/ui/borrowck/suggest-mut-iterator.stderr
new file mode 100644
index 00000000000..77f991a9a61
--- /dev/null
+++ b/tests/ui/borrowck/suggest-mut-iterator.stderr
@@ -0,0 +1,16 @@
+error[E0596]: cannot borrow `*test` as mutable, as it is behind a `&` reference
+  --> $DIR/suggest-mut-iterator.rs:22:9
+   |
+LL |     for test in &tests {
+   |                 ------ this iterator yields `&` references
+LL |         test.add(2);
+   |         ^^^^ `test` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+   |
+help: use a mutable iterator instead
+   |
+LL |     for test in &mut tests {
+   |                  +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr
index d8eebeb0d21..cb51d9b1ea5 100644
--- a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr
+++ b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `[Adt; std::mem::size_of::<Self::Assoc>()]: Foo` is not satisfied
-  --> $DIR/dont-evaluate-array-len-on-err-1.rs:15:9
+  --> $DIR/dont-evaluate-array-len-on-err-1.rs:15:10
    |
 LL |         <[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar()
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; std::mem::size_of::<Self::Assoc>()]`
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; std::mem::size_of::<Self::Assoc>()]`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/exhaustive-value.stderr b/tests/ui/const-generics/exhaustive-value.stderr
index 4a26e09772d..0828f7896dc 100644
--- a/tests/ui/const-generics/exhaustive-value.stderr
+++ b/tests/ui/const-generics/exhaustive-value.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `(): Foo<N>` is not satisfied
-  --> $DIR/exhaustive-value.rs:262:5
+  --> $DIR/exhaustive-value.rs:262:16
    |
 LL |     <() as Foo<N>>::test()
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
+   |                ^ the trait `Foo<N>` is not implemented for `()`
    |
    = help: the following other types implement trait `Foo<N>`:
              <() as Foo<0>>
diff --git a/tests/ui/const-generics/issues/issue-100313.stderr b/tests/ui/const-generics/issues/issue-100313.stderr
index 42ad4d61c8e..796966b22d5 100644
--- a/tests/ui/const-generics/issues/issue-100313.stderr
+++ b/tests/ui/const-generics/issues/issue-100313.stderr
@@ -4,6 +4,7 @@ error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
 LL |             *(B as *const bool as *mut bool) = false;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
    = note: `#[deny(invalid_reference_casting)]` on by default
 
 error[E0080]: evaluation of constant value failed
diff --git a/tests/ui/consts/assoc-const-elided-lifetime.rs b/tests/ui/consts/assoc-const-elided-lifetime.rs
new file mode 100644
index 00000000000..10cd33a8fed
--- /dev/null
+++ b/tests/ui/consts/assoc-const-elided-lifetime.rs
@@ -0,0 +1,19 @@
+#![deny(elided_lifetimes_in_associated_constant)]
+
+use std::marker::PhantomData;
+
+struct Foo<'a> {
+    x: PhantomData<&'a ()>,
+}
+
+impl<'a> Foo<'a> {
+    const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
+    //~^ ERROR `'_` cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+    const BAR: &() = &();
+    //~^ ERROR `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+}
+
+fn main() {}
diff --git a/tests/ui/consts/assoc-const-elided-lifetime.stderr b/tests/ui/consts/assoc-const-elided-lifetime.stderr
new file mode 100644
index 00000000000..a1eeaff4ba8
--- /dev/null
+++ b/tests/ui/consts/assoc-const-elided-lifetime.stderr
@@ -0,0 +1,33 @@
+error: `'_` cannot be used here
+  --> $DIR/assoc-const-elided-lifetime.rs:10:20
+   |
+LL |     const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
+   |                    ^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+note: the lint level is defined here
+  --> $DIR/assoc-const-elided-lifetime.rs:1:9
+   |
+LL | #![deny(elided_lifetimes_in_associated_constant)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use the `'static` lifetime
+   |
+LL |     const FOO: Foo<'static> = Foo { x: PhantomData::<&()> };
+   |                    ~~~~~~~
+
+error: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/assoc-const-elided-lifetime.rs:14:16
+   |
+LL |     const BAR: &() = &();
+   |                ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+help: use the `'static` lifetime
+   |
+LL |     const BAR: &'static () = &();
+   |                 +++++++
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/consts/const-eval/ub-int-array.64bit.stderr b/tests/ui/consts/const-eval/ub-int-array.64bit.stderr
deleted file mode 100644
index b3df41304ac..00000000000
--- a/tests/ui/consts/const-eval/ub-int-array.64bit.stderr
+++ /dev/null
@@ -1,36 +0,0 @@
-error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-int-array.rs:19:1
-   |
-LL | const UNINIT_INT_0: [u32; 3] = unsafe {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized memory, but expected an integer
-   |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
-   = note: the raw bytes of the constant (size: 12, align: 4) {
-               __ __ __ __ 01 00 00 00 02 00 00 00             │ ░░░░........
-           }
-
-error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-int-array.rs:24:1
-   |
-LL | const UNINIT_INT_1: [u32; 3] = unsafe {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized memory, but expected an integer
-   |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
-   = note: the raw bytes of the constant (size: 12, align: 4) {
-               00 00 00 00 01 __ 01 01 02 02 __ 02             │ .....░....░.
-           }
-
-error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-int-array.rs:42:1
-   |
-LL | const UNINIT_INT_2: [u32; 3] = unsafe {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized memory, but expected an integer
-   |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
-   = note: the raw bytes of the constant (size: 12, align: 4) {
-               00 00 00 00 01 01 01 01 02 02 02 __             │ ...........░
-           }
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-int-array.rs b/tests/ui/consts/const-eval/ub-int-array.rs
index adcf376b9c7..cde0749dc5f 100644
--- a/tests/ui/consts/const-eval/ub-int-array.rs
+++ b/tests/ui/consts/const-eval/ub-int-array.rs
@@ -1,4 +1,3 @@
-// stderr-per-bitwidth
 //! Test the "array of int" fast path in validity checking, and in particular whether it
 //! points at the right array element.
 
@@ -19,7 +18,12 @@ impl<T: Copy> MaybeUninit<T> {
 const UNINIT_INT_0: [u32; 3] = unsafe {
     //~^ ERROR it is undefined behavior to use this value
     //~| invalid value at [0]
-    mem::transmute([MaybeUninit { uninit: () }, MaybeUninit::new(1), MaybeUninit::new(2)])
+    mem::transmute([
+        MaybeUninit { uninit: () },
+        // Constants chosen to achieve endianness-independent hex dump.
+        MaybeUninit::new(0x11111111),
+        MaybeUninit::new(0x22222222),
+    ])
 };
 const UNINIT_INT_1: [u32; 3] = unsafe {
     //~^ ERROR it is undefined behavior to use this value
diff --git a/tests/ui/consts/const-eval/ub-int-array.32bit.stderr b/tests/ui/consts/const-eval/ub-int-array.stderr
index b3df41304ac..c8efd7e1bd3 100644
--- a/tests/ui/consts/const-eval/ub-int-array.32bit.stderr
+++ b/tests/ui/consts/const-eval/ub-int-array.stderr
@@ -1,16 +1,16 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-int-array.rs:19:1
+  --> $DIR/ub-int-array.rs:18:1
    |
 LL | const UNINIT_INT_0: [u32; 3] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered uninitialized memory, but expected an integer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 12, align: 4) {
-               __ __ __ __ 01 00 00 00 02 00 00 00             │ ░░░░........
+               __ __ __ __ 11 11 11 11 22 22 22 22             │ ░░░░....""""
            }
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-int-array.rs:24:1
+  --> $DIR/ub-int-array.rs:28:1
    |
 LL | const UNINIT_INT_1: [u32; 3] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [1]: encountered uninitialized memory, but expected an integer
@@ -21,7 +21,7 @@ LL | const UNINIT_INT_1: [u32; 3] = unsafe {
            }
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-int-array.rs:42:1
+  --> $DIR/ub-int-array.rs:46:1
    |
 LL | const UNINIT_INT_2: [u32; 3] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [2]: encountered uninitialized memory, but expected an integer
diff --git a/tests/ui/consts/missing-larger-array-impl.stderr b/tests/ui/consts/missing-larger-array-impl.stderr
index b8f6cb5ef97..fe9d0f6e6ed 100644
--- a/tests/ui/consts/missing-larger-array-impl.stderr
+++ b/tests/ui/consts/missing-larger-array-impl.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `[X; 35]: Default` is not satisfied
-  --> $DIR/missing-larger-array-impl.rs:7:5
+  --> $DIR/missing-larger-array-impl.rs:7:6
    |
 LL |     <[X; 35] as Default>::default();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[X; 35]`
+   |      ^^^^^^^ the trait `Default` is not implemented for `[X; 35]`
    |
    = help: the following other types implement trait `Default`:
              [T; 0]
diff --git a/tests/ui/consts/std/alloc.32bit.stderr b/tests/ui/consts/std/alloc.32bit.stderr
index 8c83df53dad..da805de451c 100644
--- a/tests/ui/consts/std/alloc.32bit.stderr
+++ b/tests/ui/consts/std/alloc.32bit.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/alloc.rs:12:1
+  --> $DIR/alloc.rs:11:1
    |
 LL | const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x00000000, but expected a valid enum tag
@@ -10,7 +10,7 @@ LL | const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchec
            }
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/alloc.rs:16:1
+  --> $DIR/alloc.rs:15:1
    |
 LL | const LAYOUT_INVALID_THREE: Layout = unsafe { Layout::from_size_align_unchecked(9, 3) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x00000003, but expected a valid enum tag
diff --git a/tests/ui/consts/std/alloc.64bit.stderr b/tests/ui/consts/std/alloc.64bit.stderr
index addedad1704..094503e1039 100644
--- a/tests/ui/consts/std/alloc.64bit.stderr
+++ b/tests/ui/consts/std/alloc.64bit.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/alloc.rs:12:1
+  --> $DIR/alloc.rs:11:1
    |
 LL | const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x0000000000000000, but expected a valid enum tag
@@ -10,7 +10,7 @@ LL | const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchec
            }
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/alloc.rs:16:1
+  --> $DIR/alloc.rs:15:1
    |
 LL | const LAYOUT_INVALID_THREE: Layout = unsafe { Layout::from_size_align_unchecked(9, 3) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x0000000000000003, but expected a valid enum tag
diff --git a/tests/ui/consts/std/alloc.rs b/tests/ui/consts/std/alloc.rs
index 9abf35d63d3..0a2c2f4dec8 100644
--- a/tests/ui/consts/std/alloc.rs
+++ b/tests/ui/consts/std/alloc.rs
@@ -1,5 +1,4 @@
 // stderr-per-bitwidth
-// ignore-debug (the debug assertions change the error)
 // Strip out raw byte dumps to make comparison platform-independent:
 // normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
 // normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
diff --git a/tests/ui/cross-crate/auxiliary/static_init_aux.rs b/tests/ui/cross-crate/auxiliary/static_init_aux.rs
index 3b664f43654..5e172ef3198 100644
--- a/tests/ui/cross-crate/auxiliary/static_init_aux.rs
+++ b/tests/ui/cross-crate/auxiliary/static_init_aux.rs
@@ -1,10 +1,14 @@
 pub static V: &u32 = &X;
 pub static F: fn() = f;
+pub static G: fn() = G0;
 
 static X: u32 = 42;
+static G0: fn() = g;
 
 pub fn v() -> *const u32 {
     V
 }
 
 fn f() {}
+
+fn g() {}
diff --git a/tests/ui/cross-crate/static-init.rs b/tests/ui/cross-crate/static-init.rs
index 2e893c5d9bf..0b50c41fc5e 100644
--- a/tests/ui/cross-crate/static-init.rs
+++ b/tests/ui/cross-crate/static-init.rs
@@ -1,9 +1,11 @@
+// Regression test for #84455 and #115052.
 // run-pass
 // aux-build:static_init_aux.rs
 extern crate static_init_aux as aux;
 
 static V: &u32 = aux::V;
 static F: fn() = aux::F;
+static G: fn() = aux::G;
 
 fn v() -> *const u32 {
     V
@@ -12,4 +14,5 @@ fn v() -> *const u32 {
 fn main() {
     assert_eq!(aux::v(), crate::v());
     F();
+    G();
 }
diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed
index 85e88287094..659b5465522 100644
--- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed
+++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed
@@ -6,4 +6,6 @@ fn main() {
     let _foo = str::trim_start("   aoeu"); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
 
     let _bar = "   aoeu".trim_start(); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+
+    let _baz = ["a", "b"].join(" "); //~ ERROR use of deprecated method `std::slice::<impl [T]>::connect`: renamed to join [deprecated]
 }
diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs
index 246de2f5e4b..cfc6c4450b4 100644
--- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs
+++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs
@@ -6,4 +6,6 @@ fn main() {
     let _foo = str::trim_left("   aoeu"); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
 
     let _bar = "   aoeu".trim_left(); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+
+    let _baz = ["a", "b"].connect(" "); //~ ERROR use of deprecated method `std::slice::<impl [T]>::connect`: renamed to join [deprecated]
 }
diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr
index 3b518d1802b..d1f5ea3602a 100644
--- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr
+++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr
@@ -25,5 +25,16 @@ help: replace the use of the deprecated method
 LL |     let _bar = "   aoeu".trim_start();
    |                          ~~~~~~~~~~
 
-error: aborting due to 2 previous errors
+error: use of deprecated method `std::slice::<impl [T]>::connect`: renamed to join
+  --> $DIR/issue-84637-deprecated-associated-function.rs:10:27
+   |
+LL |     let _baz = ["a", "b"].connect(" ");
+   |                           ^^^^^^^
+   |
+help: replace the use of the deprecated method
+   |
+LL |     let _baz = ["a", "b"].join(" ");
+   |                           ~~~~
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-unnamed_fields.rs b/tests/ui/feature-gates/feature-gate-unnamed_fields.rs
new file mode 100644
index 00000000000..4bbd0c83bfb
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unnamed_fields.rs
@@ -0,0 +1,26 @@
+struct Foo {
+    foo: u8,
+    _: union { //~ ERROR unnamed fields are not yet fully implemented [E0658]
+    //~^ ERROR unnamed fields are not yet fully implemented [E0658]
+    //~| ERROR anonymous unions are unimplemented
+        bar: u8,
+        baz: u16
+    }
+}
+
+union Bar {
+    foobar: u8,
+    _: struct { //~ ERROR unnamed fields are not yet fully implemented [E0658]
+    //~^ ERROR unnamed fields are not yet fully implemented [E0658]
+    //~| ERROR anonymous structs are unimplemented
+        foobaz: u8,
+        barbaz: u16
+    }
+}
+
+struct S;
+struct Baz {
+    _: S //~ ERROR unnamed fields are not yet fully implemented [E0658]
+}
+
+fn main(){}
diff --git a/tests/ui/feature-gates/feature-gate-unnamed_fields.stderr b/tests/ui/feature-gates/feature-gate-unnamed_fields.stderr
new file mode 100644
index 00000000000..f026f2c3600
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unnamed_fields.stderr
@@ -0,0 +1,84 @@
+error[E0658]: unnamed fields are not yet fully implemented
+  --> $DIR/feature-gate-unnamed_fields.rs:3:5
+   |
+LL |     _: union {
+   |     ^
+   |
+   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
+   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
+
+error[E0658]: unnamed fields are not yet fully implemented
+  --> $DIR/feature-gate-unnamed_fields.rs:3:8
+   |
+LL |       _: union {
+   |  ________^
+LL | |
+LL | |
+LL | |         bar: u8,
+LL | |         baz: u16
+LL | |     }
+   | |_____^
+   |
+   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
+   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
+
+error[E0658]: unnamed fields are not yet fully implemented
+  --> $DIR/feature-gate-unnamed_fields.rs:13:5
+   |
+LL |     _: struct {
+   |     ^
+   |
+   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
+   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
+
+error[E0658]: unnamed fields are not yet fully implemented
+  --> $DIR/feature-gate-unnamed_fields.rs:13:8
+   |
+LL |       _: struct {
+   |  ________^
+LL | |
+LL | |
+LL | |         foobaz: u8,
+LL | |         barbaz: u16
+LL | |     }
+   | |_____^
+   |
+   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
+   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
+
+error[E0658]: unnamed fields are not yet fully implemented
+  --> $DIR/feature-gate-unnamed_fields.rs:23:5
+   |
+LL |     _: S
+   |     ^
+   |
+   = note: see issue #49804 <https://github.com/rust-lang/rust/issues/49804> for more information
+   = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable
+
+error: anonymous unions are unimplemented
+  --> $DIR/feature-gate-unnamed_fields.rs:3:8
+   |
+LL |       _: union {
+   |  ________^
+LL | |
+LL | |
+LL | |         bar: u8,
+LL | |         baz: u16
+LL | |     }
+   | |_____^
+
+error: anonymous structs are unimplemented
+  --> $DIR/feature-gate-unnamed_fields.rs:13:8
+   |
+LL |       _: struct {
+   |  ________^
+LL | |
+LL | |
+LL | |         foobaz: u8,
+LL | |         barbaz: u16
+LL | |     }
+   | |_____^
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
index 1fda460372a..2cee53431a4 100644
--- a/tests/ui/generic-const-items/unsatisfied-bounds.stderr
+++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
@@ -27,10 +27,10 @@ LL |     Infallible: From<T>;
    |                 ^^^^^^^ required by this bound in `K`
 
 error[E0277]: the trait bound `Vec<u8>: Copy` is not satisfied
-  --> $DIR/unsatisfied-bounds.rs:32:13
+  --> $DIR/unsatisfied-bounds.rs:32:26
    |
 LL |     let _ = <() as Trait<Vec<u8>>>::A;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
+   |                          ^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
    |
 note: required by a bound in `Trait::A`
   --> $DIR/unsatisfied-bounds.rs:17:12
diff --git a/tests/ui/implied-bounds/implied_bounds_entailment_alias_var.rs b/tests/ui/implied-bounds/implied_bounds_entailment_alias_var.rs
new file mode 100644
index 00000000000..e0df96b0de8
--- /dev/null
+++ b/tests/ui/implied-bounds/implied_bounds_entailment_alias_var.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+trait Data {
+    type Elem;
+}
+
+impl<F, S: Data<Elem = F>> Data for ArrayBase<S> {
+    type Elem = F;
+}
+
+struct DatasetIter<'a, R: Data> {
+    data: &'a R::Elem,
+}
+
+pub struct ArrayBase<S> {
+    data: S,
+}
+
+trait Trait {
+    type Item;
+    fn next() -> Option<Self::Item>;
+}
+
+impl<'a, D: Data> Trait for DatasetIter<'a, ArrayBase<D>> {
+    type Item = ();
+
+    fn next() -> Option<Self::Item> {
+        None
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-39970.stderr b/tests/ui/issues/issue-39970.stderr
index 8344b88c3be..713bc404f67 100644
--- a/tests/ui/issues/issue-39970.stderr
+++ b/tests/ui/issues/issue-39970.stderr
@@ -1,8 +1,8 @@
 error[E0271]: type mismatch resolving `<() as Array<'a>>::Element == ()`
-  --> $DIR/issue-39970.rs:19:5
+  --> $DIR/issue-39970.rs:19:6
    |
 LL |     <() as Visit>::visit();
-   |     ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Array<'a>>::Element == ()`
+   |      ^^ type mismatch resolving `<() as Array<'a>>::Element == ()`
    |
 note: expected this to be `()`
   --> $DIR/issue-39970.rs:10:20
diff --git a/tests/ui/issues/issue-43988.stderr b/tests/ui/issues/issue-43988.stderr
index 02c5dd5bfb7..7bbb8ed2ca9 100644
--- a/tests/ui/issues/issue-43988.stderr
+++ b/tests/ui/issues/issue-43988.stderr
@@ -32,7 +32,7 @@ error[E0552]: unrecognized representation hint
 LL |     #[repr(nothing)]
    |            ^^^^^^^
    |
-   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+   = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error[E0552]: unrecognized representation hint
   --> $DIR/issue-43988.rs:18:12
@@ -40,7 +40,7 @@ error[E0552]: unrecognized representation hint
 LL |     #[repr(something_not_real)]
    |            ^^^^^^^^^^^^^^^^^^
    |
-   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+   = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error[E0518]: attribute should be applied to function or closure
   --> $DIR/issue-43988.rs:30:5
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs
index 6c38bca3daa..92d985948ec 100644
--- a/tests/ui/lint/reference_casting.rs
+++ b/tests/ui/lint/reference_casting.rs
@@ -71,6 +71,11 @@ unsafe fn assign_to_ref() {
     //~^ ERROR assigning to `&T` is undefined behavior
     *std::mem::transmute::<_, *mut i32>(num) += 1;
     //~^ ERROR assigning to `&T` is undefined behavior
+    std::ptr::write(
+    //~^ ERROR assigning to `&T` is undefined behavior
+        std::mem::transmute::<*const i32, *mut i32>(num),
+        -1i32,
+    );
 
     let value = num as *const i32 as *mut i32;
     *value = 1;
@@ -79,6 +84,12 @@ unsafe fn assign_to_ref() {
     //~^ ERROR assigning to `&T` is undefined behavior
     *(num as *const _ as usize as *mut i32) = 2;
     //~^ ERROR assigning to `&T` is undefined behavior
+    std::ptr::write(value, 2);
+    //~^ ERROR assigning to `&T` is undefined behavior
+    std::ptr::write_unaligned(value, 2);
+    //~^ ERROR assigning to `&T` is undefined behavior
+    std::ptr::write_volatile(value, 2);
+    //~^ ERROR assigning to `&T` is undefined behavior
 
     unsafe fn generic_assign_to_ref<T>(this: &T, a: T) {
         *(this as *const _ as *mut _) = a;
diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr
index 7ff9b76a85e..47b95460ec3 100644
--- a/tests/ui/lint/reference_casting.stderr
+++ b/tests/ui/lint/reference_casting.stderr
@@ -4,6 +4,7 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is
 LL |     let _num = &mut *(num as *const i32 as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
    = note: `#[deny(invalid_reference_casting)]` on by default
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
@@ -11,54 +12,72 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is
    |
 LL |     let _num = &mut *(num as *const i32).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:23:16
    |
 LL |     let _num = &mut *std::ptr::from_ref(num).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:25:16
    |
 LL |     let _num = &mut *std::ptr::from_ref({ num }).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:27:16
    |
 LL |     let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:29:16
    |
 LL |     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:31:16
    |
 LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:33:16
    |
 LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_const().cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:35:16
    |
 LL |     let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:37:16
    |
 LL |     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:41:16
@@ -67,6 +86,8 @@ LL |     let deferred = num as *const i32 as *mut i32;
    |                    ----------------------------- casting happend here
 LL |     let _num = &mut *deferred;
    |                ^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:44:16
@@ -75,86 +96,159 @@ LL |     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).ca
    |                    ---------------------------------------------------------------------------- casting happend here
 LL |     let _num = &mut *deferred;
    |                ^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:46:16
    |
 LL |     let _num = &mut *(num as *const _ as usize as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:50:9
    |
 LL |         &mut *((this as *const _) as *mut _)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
   --> $DIR/reference_casting.rs:60:5
    |
 LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
   --> $DIR/reference_casting.rs:62:5
    |
 LL |     *(a as *const _ as *mut String) += " world";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
   --> $DIR/reference_casting.rs:64:5
    |
 LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
   --> $DIR/reference_casting.rs:66:5
    |
 LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
   --> $DIR/reference_casting.rs:68:5
    |
 LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
   --> $DIR/reference_casting.rs:70:5
    |
 LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
   --> $DIR/reference_casting.rs:72:5
    |
 LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:74:5
+   |
+LL | /     std::ptr::write(
+LL | |
+LL | |         std::mem::transmute::<*const i32, *mut i32>(num),
+LL | |         -1i32,
+LL | |     );
+   | |_____^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:76:5
+  --> $DIR/reference_casting.rs:81:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
 LL |     *value = 1;
    |     ^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:78:5
+  --> $DIR/reference_casting.rs:83:5
    |
 LL |     *(num as *const i32).cast::<i32>().cast_mut() = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:80:5
+  --> $DIR/reference_casting.rs:85:5
    |
 LL |     *(num as *const _ as usize as *mut i32) = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:87:5
+   |
+LL |     let value = num as *const i32 as *mut i32;
+   |                 ----------------------------- casting happend here
+...
+LL |     std::ptr::write(value, 2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:84:9
+  --> $DIR/reference_casting.rs:89:5
+   |
+LL |     let value = num as *const i32 as *mut i32;
+   |                 ----------------------------- casting happend here
+...
+LL |     std::ptr::write_unaligned(value, 2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:91:5
+   |
+LL |     let value = num as *const i32 as *mut i32;
+   |                 ----------------------------- casting happend here
+...
+LL |     std::ptr::write_volatile(value, 2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:95:9
    |
 LL |         *(this as *const _ as *mut _) = a;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
-error: aborting due to 25 previous errors
+error: aborting due to 29 previous errors
 
diff --git a/tests/ui/issue-2804.rs b/tests/ui/macros/issue-2804.rs
index 571028c5e40..571028c5e40 100644
--- a/tests/ui/issue-2804.rs
+++ b/tests/ui/macros/issue-2804.rs
diff --git a/tests/ui/panics/panic-in-cleanup.rs b/tests/ui/panics/panic-in-cleanup.rs
new file mode 100644
index 00000000000..a1c797268d1
--- /dev/null
+++ b/tests/ui/panics/panic-in-cleanup.rs
@@ -0,0 +1,22 @@
+// run-fail
+// exec-env:RUST_BACKTRACE=0
+// check-run-results
+// error-pattern: panic in a destructor during cleanup
+// normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> ""
+// normalize-stderr-test: "\n +at [^\n]+" -> ""
+// needs-unwind
+// ignore-emscripten "RuntimeError" junk in output
+// ignore-msvc SEH doesn't do panic-during-cleanup the same way as everyone else
+
+struct Bomb;
+
+impl Drop for Bomb {
+    fn drop(&mut self) {
+        panic!("BOOM");
+    }
+}
+
+fn main() {
+    let _b = Bomb;
+    panic!();
+}
diff --git a/tests/ui/panics/panic-in-cleanup.run.stderr b/tests/ui/panics/panic-in-cleanup.run.stderr
new file mode 100644
index 00000000000..923bac69c50
--- /dev/null
+++ b/tests/ui/panics/panic-in-cleanup.run.stderr
@@ -0,0 +1,10 @@
+thread 'main' panicked at $DIR/panic-in-cleanup.rs:21:5:
+explicit panic
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+thread 'main' panicked at $DIR/panic-in-cleanup.rs:15:9:
+BOOM
+stack backtrace:
+thread 'main' panicked at library/core/src/panicking.rs:126:5:
+panic in a destructor during cleanup
+stack backtrace:
+thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs
new file mode 100644
index 00000000000..da2b24945be
--- /dev/null
+++ b/tests/ui/panics/panic-in-ffi.rs
@@ -0,0 +1,17 @@
+// run-fail
+// exec-env:RUST_BACKTRACE=0
+// check-run-results
+// error-pattern: panic in a function that cannot unwind
+// normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> ""
+// normalize-stderr-test: "\n +at [^\n]+" -> ""
+// needs-unwind
+// ignore-emscripten "RuntimeError" junk in output
+#![feature(c_unwind)]
+
+extern "C" fn panic_in_ffi() {
+    panic!("Test");
+}
+
+fn main() {
+    panic_in_ffi();
+}
diff --git a/tests/ui/panics/panic-in-ffi.run.stderr b/tests/ui/panics/panic-in-ffi.run.stderr
new file mode 100644
index 00000000000..3422f5ccc4d
--- /dev/null
+++ b/tests/ui/panics/panic-in-ffi.run.stderr
@@ -0,0 +1,7 @@
+thread 'main' panicked at $DIR/panic-in-ffi.rs:12:5:
+Test
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+thread 'main' panicked at library/core/src/panicking.rs:126:5:
+panic in a function that cannot unwind
+stack backtrace:
+thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/parser/keyword-union-as-identifier.rs b/tests/ui/parser/keyword-union-as-identifier.rs
new file mode 100644
index 00000000000..7062557d731
--- /dev/null
+++ b/tests/ui/parser/keyword-union-as-identifier.rs
@@ -0,0 +1,72 @@
+// check-pass
+
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+
+mod union {
+    type union = i32;
+
+    pub struct Bar {
+        pub union: union,
+    }
+
+    pub fn union() -> Bar {
+        Bar {
+            union: 5
+        }
+    }
+}
+
+mod struct_union {
+    pub struct union {
+        pub union: u32
+    }
+    static union: union = union { union: 0 };
+
+    impl union {
+        pub fn union<'union>() -> &'union union {
+            &union
+        }
+    }
+    impl union {}
+    trait Foo {}
+    impl Foo for union {}
+    trait Bar {
+        fn bar() {}
+    }
+    impl Bar for union {}
+}
+
+mod union_union {
+    pub union union {
+        pub union: u32
+    }
+    const union: union = union { union: 0 };
+    impl union {
+        pub fn union() -> union {
+            union
+        }
+    }
+}
+
+mod trait_union {
+    pub trait union {
+        fn union() {}
+    }
+    impl union for () {}
+}
+
+macro_rules! ty {
+    ($ty:ty { $($field:ident:$field_ty:ty)* }) => {};
+}
+
+fn main() {
+    let union = union::union();
+    let _ = union.union;
+    let _ = struct_union::union::union().union;
+    let union = union_union::union::union();
+    let _ = unsafe { union.union };
+    <() as trait_union::union>::union();
+    ty!(union {});
+    ty!(union { union: union });
+}
diff --git a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
index 0e0f0c3e11e..df330c60b1e 100644
--- a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
+++ b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
@@ -77,6 +77,8 @@ LL |     m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::
    |        ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
    |
    = note: the matched value is of type `(usize, bool)`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |         match $s { $($t)+ => {}, (_, _) => todo!() }
@@ -131,6 +133,8 @@ LL |     m!((0isize, true), (isize::MIN..5, true)
    |        ^^^^^^^^^^^^^^ pattern `(_, _)` not covered
    |
    = note: the matched value is of type `(isize, bool)`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |         match $s { $($t)+ => {}, (_, _) => todo!() }
diff --git a/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.rs b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.rs
new file mode 100644
index 00000000000..8f58227ee2c
--- /dev/null
+++ b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.rs
@@ -0,0 +1,67 @@
+struct A<T> {
+    a: T,
+}
+
+struct B<T, U>(T, U);
+
+fn main() {
+    match 0 {
+        //~^ ERROR non-exhaustive patterns: `_` not covered [E0004]
+        0 => (),
+        1..=usize::MAX => (),
+    }
+
+    match (0usize, 0usize) {
+        //~^ ERROR non-exhaustive patterns: `(_, _)` not covered [E0004]
+        (0, 0) => (),
+        (1..=usize::MAX, 1..=usize::MAX) => (),
+    }
+
+    match (0isize, 0usize) {
+        //~^ ERROR non-exhaustive patterns: `(_, _)` not covered [E0004]
+        (isize::MIN..=isize::MAX, 0) => (),
+        (isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
+    }
+
+    // Should not report note about usize not having fixed max value
+    match Some(1usize) {
+        //~^ ERROR non-exhaustive patterns: `Some(_)` not covered
+        None => {}
+    }
+
+    match Some(4) {
+        //~^ ERROR non-exhaustive patterns: `Some(_)` not covered
+        Some(0) => (),
+        Some(1..=usize::MAX) => (),
+        None => (),
+    }
+
+    match Some(Some(Some(0))) {
+        //~^ ERROR non-exhaustive patterns: `Some(Some(Some(_)))` not covered
+        Some(Some(Some(0))) => (),
+        Some(Some(Some(1..=usize::MAX))) => (),
+        Some(Some(None)) => (),
+        Some(None) => (),
+        None => (),
+    }
+
+    match (A { a: 0usize }) {
+        //~^ ERROR non-exhaustive patterns: `A { .. }` not covered [E0004]
+        A { a: 0 } => (),
+        A { a: 1..=usize::MAX } => (),
+    }
+
+    match B(0isize, 0usize) {
+        //~^ ERROR non-exhaustive patterns: `B(_, _)` not covered [E0004]
+        B(isize::MIN..=isize::MAX, 0) => (),
+        B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
+    }
+
+    // Should report only the note about usize not having fixed max value and not report
+    // report the note about isize
+    match B(0isize, 0usize) {
+        //~^ ERROR non-exhaustive patterns: `B(_, _)` not covered [E0004]
+        B(_, 0) => (),
+        B(_, 1..=usize::MAX) => (),
+    }
+}
diff --git a/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr
new file mode 100644
index 00000000000..ea1d99e20ae
--- /dev/null
+++ b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr
@@ -0,0 +1,170 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:8:11
+   |
+LL |     match 0 {
+   |           ^ pattern `_` not covered
+   |
+   = note: the matched value is of type `usize`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         1..=usize::MAX => (),
+LL ~         _ => todo!(),
+   |
+
+error[E0004]: non-exhaustive patterns: `(_, _)` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:14:11
+   |
+LL |     match (0usize, 0usize) {
+   |           ^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+   |
+   = note: the matched value is of type `(usize, usize)`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (1..=usize::MAX, 1..=usize::MAX) => (),
+LL ~         (_, _) => todo!(),
+   |
+
+error[E0004]: non-exhaustive patterns: `(_, _)` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:20:11
+   |
+LL |     match (0isize, 0usize) {
+   |           ^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
+   |
+   = note: the matched value is of type `(isize, usize)`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         (isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
+LL ~         (_, _) => todo!(),
+   |
+
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:27:11
+   |
+LL |     match Some(1usize) {
+   |           ^^^^^^^^^^^^ pattern `Some(_)` not covered
+   |
+note: `Option<usize>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<usize>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         None => {},
+LL +         Some(_) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:32:11
+   |
+LL |     match Some(4) {
+   |           ^^^^^^^ pattern `Some(_)` not covered
+   |
+note: `Option<usize>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<usize>`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         None => (),
+LL ~         Some(_) => todo!(),
+   |
+
+error[E0004]: non-exhaustive patterns: `Some(Some(Some(_)))` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:39:11
+   |
+LL |     match Some(Some(Some(0))) {
+   |           ^^^^^^^^^^^^^^^^^^^ pattern `Some(Some(Some(_)))` not covered
+   |
+note: `Option<Option<Option<usize>>>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   |
+   = note: not covered
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<Option<Option<usize>>>`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         None => (),
+LL ~         Some(Some(Some(_))) => todo!(),
+   |
+
+error[E0004]: non-exhaustive patterns: `A { .. }` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:48:11
+   |
+LL |     match (A { a: 0usize }) {
+   |           ^^^^^^^^^^^^^^^^^ pattern `A { .. }` not covered
+   |
+note: `A<usize>` defined here
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:1:8
+   |
+LL | struct A<T> {
+   |        ^
+   = note: the matched value is of type `A<usize>`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         A { a: 1..=usize::MAX } => (),
+LL ~         A { .. } => todo!(),
+   |
+
+error[E0004]: non-exhaustive patterns: `B(_, _)` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:54:11
+   |
+LL |     match B(0isize, 0usize) {
+   |           ^^^^^^^^^^^^^^^^^ pattern `B(_, _)` not covered
+   |
+note: `B<isize, usize>` defined here
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:5:8
+   |
+LL | struct B<T, U>(T, U);
+   |        ^
+   = note: the matched value is of type `B<isize, usize>`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (),
+LL ~         B(_, _) => todo!(),
+   |
+
+error[E0004]: non-exhaustive patterns: `B(_, _)` not covered
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:62:11
+   |
+LL |     match B(0isize, 0usize) {
+   |           ^^^^^^^^^^^^^^^^^ pattern `B(_, _)` not covered
+   |
+note: `B<isize, usize>` defined here
+  --> $DIR/issue-85222-types-containing-non-exhaustive-types.rs:5:8
+   |
+LL | struct B<T, U>(T, U);
+   |        ^
+   = note: the matched value is of type `B<isize, usize>`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         B(_, 1..=usize::MAX) => (),
+LL ~         B(_, _) => todo!(),
+   |
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr b/tests/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
index b8af566de7c..d798ec722dd 100644
--- a/tests/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
+++ b/tests/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
@@ -10,6 +10,8 @@ note: `Foo` defined here
 LL | struct Foo {
    |        ^^^
    = note: the matched value is of type `Foo`
+   = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         Foo { first: false, second: Some([1, 2, 3, 4]) } => (),
diff --git a/tests/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr b/tests/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
index e2a65ff8524..50c7fc889f4 100644
--- a/tests/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
+++ b/tests/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
@@ -10,6 +10,8 @@ note: `Foo` defined here
 LL | struct Foo(isize, isize);
    |        ^^^
    = note: the matched value is of type `Foo`
+   = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
+   = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         Foo(2, b) => println!("{}", b),
diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr
index 48a6af3dd4c..7ffe1287eb3 100644
--- a/tests/ui/repr/invalid_repr_list_help.stderr
+++ b/tests/ui/repr/invalid_repr_list_help.stderr
@@ -4,7 +4,7 @@ error[E0552]: unrecognized representation hint
 LL | #[repr(uwu)]
    |        ^^^
    |
-   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+   = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error[E0552]: unrecognized representation hint
   --> $DIR/invalid_repr_list_help.rs:6:8
@@ -12,7 +12,7 @@ error[E0552]: unrecognized representation hint
 LL | #[repr(uwu = "a")]
    |        ^^^^^^^^^
    |
-   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+   = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error[E0552]: unrecognized representation hint
   --> $DIR/invalid_repr_list_help.rs:9:8
@@ -20,7 +20,7 @@ error[E0552]: unrecognized representation hint
 LL | #[repr(uwu(4))]
    |        ^^^^^^
    |
-   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+   = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error[E0552]: unrecognized representation hint
   --> $DIR/invalid_repr_list_help.rs:14:8
@@ -28,7 +28,7 @@ error[E0552]: unrecognized representation hint
 LL | #[repr(uwu, u8)]
    |        ^^^
    |
-   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+   = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 warning: unknown `doc` attribute `owo`
   --> $DIR/invalid_repr_list_help.rs:20:7
@@ -46,7 +46,7 @@ error[E0552]: unrecognized representation hint
 LL | #[repr(uwu)]
    |        ^^^
    |
-   = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
+   = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
 error: aborting due to 5 previous errors; 1 warning emitted
 
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs
new file mode 100644
index 00000000000..b4eb541398c
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs
@@ -0,0 +1,18 @@
+#![feature(if_let_guard)]
+#![allow(irrefutable_let_patterns)]
+
+fn match_option(x: Option<u32>) {
+    match x {
+        //~^ ERROR non-exhaustive patterns: `None` not covered
+        Some(_) => {}
+        None if let y = x => {}
+    }
+}
+
+fn main() {
+    let x = ();
+    match x {
+        //~^ ERROR non-exhaustive patterns: `()` not covered
+        y if let z = y => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr
new file mode 100644
index 00000000000..ddd08854ff7
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr
@@ -0,0 +1,35 @@
+error[E0004]: non-exhaustive patterns: `None` not covered
+  --> $DIR/exhaustive.rs:5:11
+   |
+LL |     match x {
+   |           ^ pattern `None` not covered
+   |
+note: `Option<u32>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<u32>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         None if let y = x => {},
+LL +         None => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `()` not covered
+  --> $DIR/exhaustive.rs:14:11
+   |
+LL |     match x {
+   |           ^ pattern `()` not covered
+   |
+   = note: the matched value is of type `()`
+   = note: match arms with guards don't count towards exhaustivity
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         y if let z = y => {},
+LL +         () => todo!()
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs
new file mode 100644
index 00000000000..792225e656f
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs
@@ -0,0 +1,15 @@
+// References to by-move bindings in an if-let guard *cannot* be used after the guard.
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let x: Option<Option<String>> = Some(Some(String::new()));
+    match x {
+        Some(mut y) if let Some(ref z) = y => {
+            //~^ ERROR: cannot move out of `x.0` because it is borrowed
+            let _z: &String = z;
+            let _y: Option<String> = y;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr
new file mode 100644
index 00000000000..b8e1bb324b1
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr
@@ -0,0 +1,15 @@
+error[E0505]: cannot move out of `x.0` because it is borrowed
+  --> $DIR/guard-lifetime-1.rs:8:14
+   |
+LL |         Some(mut y) if let Some(ref z) = y => {
+   |              ^^^^^
+   |              |
+   |              move out of `x.0` occurs here
+   |              borrow of `x.0` occurs here
+LL |
+LL |             let _z: &String = z;
+   |                               - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0505`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs
new file mode 100644
index 00000000000..aa2154e3e9e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs
@@ -0,0 +1,16 @@
+// References to by-mutable-ref bindings in an if-let guard *can* be used after the guard.
+
+// check-pass
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let mut x: Option<Option<String>> = Some(Some(String::new()));
+    match x {
+        Some(ref mut y) if let Some(ref z) = *y => {
+            let _z: &String = z;
+            let _y: &mut Option<String> = y;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs
new file mode 100644
index 00000000000..9353c9d92f8
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs
@@ -0,0 +1,14 @@
+// Check mutable bindings cannot be mutated by an if-let guard.
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let x: Option<Option<i32>> = Some(Some(6));
+    match x {
+        Some(mut y) if let Some(ref mut z) = y => {
+            //~^ ERROR cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+            let _: &mut i32 = z;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr
new file mode 100644
index 00000000000..009d153387e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+  --> $DIR/guard-mutability-1.rs:8:33
+   |
+LL |         Some(mut y) if let Some(ref mut z) = y => {
+   |                                 ^^^^^^^^^ cannot borrow as mutable
+   |
+   = note: variables bound in patterns are immutable until the end of the pattern guard
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs
new file mode 100644
index 00000000000..4efa02f57a6
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs
@@ -0,0 +1,14 @@
+// Check mutable reference bindings cannot be mutated by an if-let guard.
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let mut x: Option<Option<i32>> = Some(Some(6));
+    match x {
+        Some(ref mut y) if let Some(ref mut z) = *y => {
+            //~^ ERROR cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+            let _: &mut i32 = z;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr
new file mode 100644
index 00000000000..07e7c6a2c07
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+  --> $DIR/guard-mutability-2.rs:8:37
+   |
+LL |         Some(ref mut y) if let Some(ref mut z) = *y => {
+   |                                     ^^^^^^^^^ cannot borrow as mutable
+   |
+   = note: variables bound in patterns are immutable until the end of the pattern guard
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs
new file mode 100644
index 00000000000..423a2cd53fc
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs
@@ -0,0 +1,16 @@
+// Expression macros can't expand to a let match guard.
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+macro_rules! m {
+    ($e:expr) => { let Some(x) = $e }
+    //~^ ERROR expected expression, found `let` statement
+}
+
+fn main() {
+    match () {
+        () if m!(Some(5)) => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
new file mode 100644
index 00000000000..41a20bf8ae1
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
@@ -0,0 +1,13 @@
+error: expected expression, found `let` statement
+  --> $DIR/macro-expanded.rs:7:20
+   |
+LL |     ($e:expr) => { let Some(x) = $e }
+   |                    ^^^
+...
+LL |         () if m!(Some(5)) => {}
+   |               ----------- 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/rfcs/rfc-2294-if-let-guard/parens.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs
new file mode 100644
index 00000000000..9cb27c73b14
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs
@@ -0,0 +1,27 @@
+// Parenthesised let "expressions" are not allowed in guards
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+#[cfg(FALSE)]
+fn un_cfged() {
+    match () {
+        () if let 0 = 1 => {}
+        () if (let 0 = 1) => {}
+        //~^ ERROR expected expression, found `let` statement
+        () if (((let 0 = 1))) => {}
+        //~^ ERROR expected expression, found `let` statement
+    }
+}
+
+fn main() {
+    match () {
+        () if let 0 = 1 => {}
+        () if (let 0 = 1) => {}
+        //~^ ERROR expected expression, found `let` statement
+        //~| ERROR `let` expressions are not supported here
+        () if (((let 0 = 1))) => {}
+        //~^ ERROR expected expression, found `let` statement
+        //~| ERROR `let` expressions are not supported here
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
new file mode 100644
index 00000000000..85df360daab
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
@@ -0,0 +1,52 @@
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:10:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:12:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:20:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:23:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^
+
+error: `let` expressions are not supported here
+  --> $DIR/parens.rs:20:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/parens.rs:20:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^^^^^^^
+
+error: `let` expressions are not supported here
+  --> $DIR/parens.rs:23:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/parens.rs:23:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs
new file mode 100644
index 00000000000..d91b3a358da
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs
@@ -0,0 +1,18 @@
+// Macros can be used for (parts of) the pattern and expression in an if let guard
+// check-pass
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+macro_rules! m {
+    (pattern $i:ident) => { Some($i) };
+    (expression $e:expr) => { $e };
+}
+
+fn main() {
+    match () {
+        () if let m!(pattern x) = m!(expression Some(4)) => {}
+        () if let [m!(pattern y)] = [Some(8 + m!(expression 4))] => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs
new file mode 100644
index 00000000000..dba292ef9e2
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs
@@ -0,0 +1,23 @@
+// Check shadowing in if let guards works as expected.
+// check-pass
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+fn main() {
+    let x: Option<Option<i32>> = Some(Some(6));
+    match x {
+        Some(x) if let Some(x) = x => {
+            let _: i32 = x;
+        }
+        _ => {}
+    }
+
+    let y: Option<Option<Option<i32>>> = Some(Some(Some(-24)));
+    match y {
+        Some(y) if let Some(y) = y && let Some(y) = y => {
+            let _: i32 = y;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
index 2d9c49af85a..452bf757df7 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
-  --> $DIR/call-const-trait-method-fail.rs:25:7
+  --> $DIR/call-const-trait-method-fail.rs:25:5
    |
 LL |     a.plus(b)
-   |       ^^^^ the trait `Plus` is not implemented for `u32`
+   |     ^ the trait `Plus` is not implemented for `u32`
    |
    = help: the trait `Plus` is implemented for `u32`
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
index e8d0eec020f..c94563d3591 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/trait-where-clause-const.rs:21:5
    |
 LL |     T::b();
-   |     ^^^^ the trait `Bar` is not implemented for `T`
+   |     ^ the trait `Bar` is not implemented for `T`
    |
 note: required by a bound in `Foo::b`
   --> $DIR/trait-where-clause-const.rs:15:24
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 11f0c40160d..255878e1775 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: Bar` is not satisfied
   --> $DIR/trait-where-clause.rs:14:5
    |
 LL |     T::b();
-   |     ^^^^ the trait `Bar` is not implemented for `T`
+   |     ^ the trait `Bar` is not implemented for `T`
    |
 note: required by a bound in `Foo::b`
   --> $DIR/trait-where-clause.rs:8:24
diff --git a/tests/ui/issues/issue-17431-6.rs b/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
index b7e49873da8..b7e49873da8 100644
--- a/tests/ui/issues/issue-17431-6.rs
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
diff --git a/tests/ui/issues/issue-17431-6.stderr b/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
index e0a8225507e..e0a8225507e 100644
--- a/tests/ui/issues/issue-17431-6.stderr
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
diff --git a/tests/ui/issues/issue-17431-7.rs b/tests/ui/structs-enums/enum-rec/issue-17431-7.rs
index 4fd7862781b..4fd7862781b 100644
--- a/tests/ui/issues/issue-17431-7.rs
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-7.rs
diff --git a/tests/ui/issues/issue-17431-7.stderr b/tests/ui/structs-enums/enum-rec/issue-17431-7.stderr
index ecf072b8e8a..ecf072b8e8a 100644
--- a/tests/ui/issues/issue-17431-7.stderr
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-7.stderr
diff --git a/tests/ui/issues/issue-17431-1.rs b/tests/ui/structs-enums/struct-rec/issue-17431-1.rs
index 3b692cc0eeb..3b692cc0eeb 100644
--- a/tests/ui/issues/issue-17431-1.rs
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-1.rs
diff --git a/tests/ui/issues/issue-17431-1.stderr b/tests/ui/structs-enums/struct-rec/issue-17431-1.stderr
index e3af8976cee..e3af8976cee 100644
--- a/tests/ui/issues/issue-17431-1.stderr
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-1.stderr
diff --git a/tests/ui/issues/issue-17431-2.rs b/tests/ui/structs-enums/struct-rec/issue-17431-2.rs
index f7b9c6a55dd..f7b9c6a55dd 100644
--- a/tests/ui/issues/issue-17431-2.rs
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-2.rs
diff --git a/tests/ui/issues/issue-17431-2.stderr b/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr
index 39a99ec1ef7..39a99ec1ef7 100644
--- a/tests/ui/issues/issue-17431-2.stderr
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-2.stderr
diff --git a/tests/ui/issues/issue-17431-3.rs b/tests/ui/structs-enums/struct-rec/issue-17431-3.rs
index 83a63a88b72..83a63a88b72 100644
--- a/tests/ui/issues/issue-17431-3.rs
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-3.rs
diff --git a/tests/ui/issues/issue-17431-3.stderr b/tests/ui/structs-enums/struct-rec/issue-17431-3.stderr
index 394134c7855..394134c7855 100644
--- a/tests/ui/issues/issue-17431-3.stderr
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-3.stderr
diff --git a/tests/ui/issues/issue-17431-4.rs b/tests/ui/structs-enums/struct-rec/issue-17431-4.rs
index 48f0dba2aec..48f0dba2aec 100644
--- a/tests/ui/issues/issue-17431-4.rs
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-4.rs
diff --git a/tests/ui/issues/issue-17431-4.stderr b/tests/ui/structs-enums/struct-rec/issue-17431-4.stderr
index 3d141e44bab..3d141e44bab 100644
--- a/tests/ui/issues/issue-17431-4.stderr
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-4.stderr
diff --git a/tests/ui/issues/issue-17431-5.rs b/tests/ui/structs-enums/struct-rec/issue-17431-5.rs
index 0fd6ee61156..0fd6ee61156 100644
--- a/tests/ui/issues/issue-17431-5.rs
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-5.rs
diff --git a/tests/ui/issues/issue-17431-5.stderr b/tests/ui/structs-enums/struct-rec/issue-17431-5.stderr
index 44a90a6fe38..44a90a6fe38 100644
--- a/tests/ui/issues/issue-17431-5.stderr
+++ b/tests/ui/structs-enums/struct-rec/issue-17431-5.stderr
diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs
index 61b9137eadd..97bd7789a63 100644
--- a/tests/ui/track-diagnostics/track.rs
+++ b/tests/ui/track-diagnostics/track.rs
@@ -6,6 +6,11 @@
 // normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
 // normalize-stderr-test "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET"
 
+// The test becomes too flaky if we care about exact args. If `-Z ui-testing`
+// from compiletest and `-Z track-diagnostics` from `// compile-flags` at the
+// top of this file are present, then assume all args are present.
+// normalize-stderr-test "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics"
+
 fn main() {
     break rust
 }
diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr
index 8256c1f5f0f..60254dc475b 100644
--- a/tests/ui/track-diagnostics/track.stderr
+++ b/tests/ui/track-diagnostics/track.stderr
@@ -20,6 +20,8 @@ note: we would appreciate a joke overview: https://github.com/rust-lang/rust/iss
 
 note: rustc $VERSION running on $TARGET
 
+note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics
+
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0268, E0425.
diff --git a/tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs
new file mode 100644
index 00000000000..91525bc90c4
--- /dev/null
+++ b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.rs
@@ -0,0 +1,6 @@
+// Regression test for one part of issue #105306.
+
+fn main() {
+    let _ = Option::<[u8]>::None;
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+}
diff --git a/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr
new file mode 100644
index 00000000000..32f6b00b20c
--- /dev/null
+++ b/tests/ui/trait-bounds/enum-unit-variant-trait-bound.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/enum-unit-variant-trait-bound.rs:4:22
+   |
+LL |     let _ = Option::<[u8]>::None;
+   |                      ^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `None`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-66768.rs b/tests/ui/traits/issue-66768.rs
index ce42c8b01cc..ce42c8b01cc 100644
--- a/tests/ui/issues/issue-66768.rs
+++ b/tests/ui/traits/issue-66768.rs
diff --git a/tests/ui/traits/suggest-where-clause.stderr b/tests/ui/traits/suggest-where-clause.stderr
index f3a4c689033..5a539884873 100644
--- a/tests/ui/traits/suggest-where-clause.stderr
+++ b/tests/ui/traits/suggest-where-clause.stderr
@@ -38,10 +38,10 @@ LL + fn check<T: Iterator, U>() {
    |
 
 error[E0277]: the trait bound `u64: From<T>` is not satisfied
-  --> $DIR/suggest-where-clause.rs:15:5
+  --> $DIR/suggest-where-clause.rs:15:18
    |
 LL |     <u64 as From<T>>::from;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `u64`
+   |                  ^ the trait `From<T>` is not implemented for `u64`
    |
 help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
@@ -49,10 +49,10 @@ LL | fn check<T: Iterator, U: ?Sized>() where u64: From<T> {
    |                                    ++++++++++++++++++
 
 error[E0277]: the trait bound `u64: From<<T as Iterator>::Item>` is not satisfied
-  --> $DIR/suggest-where-clause.rs:18:5
+  --> $DIR/suggest-where-clause.rs:18:18
    |
 LL |     <u64 as From<<T as Iterator>::Item>>::from;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
+   |                  ^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
    |
 help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
    |
@@ -60,10 +60,10 @@ LL | fn check<T: Iterator, U: ?Sized>() where u64: From<<T as Iterator>::Item> {
    |                                    ++++++++++++++++++++++++++++++++++++++
 
 error[E0277]: the trait bound `Misc<_>: From<T>` is not satisfied
-  --> $DIR/suggest-where-clause.rs:23:5
+  --> $DIR/suggest-where-clause.rs:23:22
    |
 LL |     <Misc<_> as From<T>>::from;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `Misc<_>`
+   |                      ^ the trait `From<T>` is not implemented for `Misc<_>`
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
   --> $DIR/suggest-where-clause.rs:28:20
diff --git a/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs
new file mode 100644
index 00000000000..54a22510066
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs
@@ -0,0 +1,21 @@
+// crate foo
+
+#![feature(type_alias_impl_trait)]
+
+type Tait = impl Sized;
+fn _constrain() -> Tait {}
+
+struct WrapperWithDrop<T>(T);
+impl<T> Drop for WrapperWithDrop<T> {
+    fn drop(&mut self) {}
+}
+
+pub struct Foo(WrapperWithDrop<Tait>);
+
+trait Id {
+    type Id: ?Sized;
+}
+impl<T: ?Sized> Id for T {
+    type Id = T;
+}
+pub struct Bar(WrapperWithDrop<<Tait as Id>::Id>);
diff --git a/tests/ui/type-alias-impl-trait/drop-shim-relates-opaque-issue-114375.rs b/tests/ui/type-alias-impl-trait/drop-shim-relates-opaque-issue-114375.rs
new file mode 100644
index 00000000000..51d28704972
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/drop-shim-relates-opaque-issue-114375.rs
@@ -0,0 +1,10 @@
+// aux-build:drop-shim-relates-opaque-aux.rs
+// compile-flags: -Zvalidate-mir --crate-type=lib
+// build-pass
+
+extern crate drop_shim_relates_opaque_aux;
+
+pub fn drop_foo(_: drop_shim_relates_opaque_aux::Foo) {}
+pub fn drop_bar(_: drop_shim_relates_opaque_aux::Bar) {}
+
+fn main() {}
diff --git a/tests/ui/issues/auxiliary/issue-29181.rs b/tests/ui/typeck/auxiliary/issue-29181.rs
index bd1a9be4ef1..bd1a9be4ef1 100644
--- a/tests/ui/issues/auxiliary/issue-29181.rs
+++ b/tests/ui/typeck/auxiliary/issue-29181.rs
diff --git a/tests/ui/issues/issue-29181.rs b/tests/ui/typeck/issue-29181.rs
index 70e5bc01920..70e5bc01920 100644
--- a/tests/ui/issues/issue-29181.rs
+++ b/tests/ui/typeck/issue-29181.rs
diff --git a/tests/ui/issues/issue-29181.stderr b/tests/ui/typeck/issue-29181.stderr
index 53addf2fe4d..53addf2fe4d 100644
--- a/tests/ui/issues/issue-29181.stderr
+++ b/tests/ui/typeck/issue-29181.stderr
diff --git a/tests/ui/unevaluated_fixed_size_array_len.stderr b/tests/ui/unevaluated_fixed_size_array_len.stderr
index 5e67b2c44f2..b04a7b7f2f1 100644
--- a/tests/ui/unevaluated_fixed_size_array_len.stderr
+++ b/tests/ui/unevaluated_fixed_size_array_len.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied
-  --> $DIR/unevaluated_fixed_size_array_len.rs:12:5
+  --> $DIR/unevaluated_fixed_size_array_len.rs:12:6
    |
 LL |     <[(); 0] as Foo>::foo()
-   |     ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
+   |      ^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
    |
    = help: the trait `Foo` is implemented for `[(); 1]`
 
diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs b/tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs
new file mode 100644
index 00000000000..192bbba5a5b
--- /dev/null
+++ b/tests/ui/union/unnamed-fields/restrict_anonymous_structs.rs
@@ -0,0 +1,37 @@
+#![allow(incomplete_features)]
+#![feature(unnamed_fields)]
+
+struct F {
+    field: struct { field: u8 }, //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
+    //~^ ERROR anonymous structs are unimplemented
+    _: struct { field: u8 },
+    //~^ ERROR anonymous structs are unimplemented
+}
+
+struct G {
+    _: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
+}
+
+union H {
+    field: struct { field: u8 }, //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
+    //~^ ERROR anonymous structs are unimplemented
+    _: struct { field: u8 },
+    //~^ ERROR anonymous structs are unimplemented
+}
+
+union I {
+    _: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
+}
+
+enum K {
+    M {
+        _ : struct { field: u8 }, //~ ERROR anonymous structs are not allowed outside of unnamed struct or union fields
+        //~^ ERROR unnamed fields are not allowed outside of structs or unions
+        //~| ERROR anonymous structs are unimplemented
+    },
+    N {
+        _ : u8, //~ ERROR unnamed fields are not allowed outside of structs or unions
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr b/tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr
new file mode 100644
index 00000000000..fd731766c01
--- /dev/null
+++ b/tests/ui/union/unnamed-fields/restrict_anonymous_structs.stderr
@@ -0,0 +1,78 @@
+error: anonymous structs are not allowed outside of unnamed struct or union fields
+  --> $DIR/restrict_anonymous_structs.rs:5:12
+   |
+LL |     field: struct { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
+
+error: unnamed fields can only have struct or union types
+  --> $DIR/restrict_anonymous_structs.rs:12:5
+   |
+LL |     _: (u8, u8),
+   |     ^  -------- not a struct or union
+
+error: anonymous structs are not allowed outside of unnamed struct or union fields
+  --> $DIR/restrict_anonymous_structs.rs:16:12
+   |
+LL |     field: struct { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
+
+error: unnamed fields can only have struct or union types
+  --> $DIR/restrict_anonymous_structs.rs:23:5
+   |
+LL |     _: (u8, u8),
+   |     ^  -------- not a struct or union
+
+error: unnamed fields are not allowed outside of structs or unions
+  --> $DIR/restrict_anonymous_structs.rs:28:9
+   |
+LL |         _ : struct { field: u8 },
+   |         -^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         unnamed field declared here
+
+error: anonymous structs are not allowed outside of unnamed struct or union fields
+  --> $DIR/restrict_anonymous_structs.rs:28:13
+   |
+LL |         _ : struct { field: u8 },
+   |             ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
+
+error: unnamed fields are not allowed outside of structs or unions
+  --> $DIR/restrict_anonymous_structs.rs:33:9
+   |
+LL |         _ : u8,
+   |         -^^^^^
+   |         |
+   |         unnamed field declared here
+
+error: anonymous structs are unimplemented
+  --> $DIR/restrict_anonymous_structs.rs:5:12
+   |
+LL |     field: struct { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error: anonymous structs are unimplemented
+  --> $DIR/restrict_anonymous_structs.rs:7:8
+   |
+LL |     _: struct { field: u8 },
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: anonymous structs are unimplemented
+  --> $DIR/restrict_anonymous_structs.rs:16:12
+   |
+LL |     field: struct { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error: anonymous structs are unimplemented
+  --> $DIR/restrict_anonymous_structs.rs:18:8
+   |
+LL |     _: struct { field: u8 },
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: anonymous structs are unimplemented
+  --> $DIR/restrict_anonymous_structs.rs:28:13
+   |
+LL |         _ : struct { field: u8 },
+   |             ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs b/tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs
new file mode 100644
index 00000000000..c69266089bb
--- /dev/null
+++ b/tests/ui/union/unnamed-fields/restrict_anonymous_unions.rs
@@ -0,0 +1,37 @@
+#![allow(incomplete_features)]
+#![feature(unnamed_fields)]
+
+struct F {
+    field: union { field: u8 }, //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
+    //~^ ERROR anonymous unions are unimplemented
+    _: union { field: u8 },
+    //~^ ERROR anonymous unions are unimplemented
+}
+
+struct G {
+    _: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
+}
+
+union H {
+    field: union { field: u8 }, //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
+    //~^ ERROR anonymous unions are unimplemented
+    _: union { field: u8 },
+    //~^ ERROR anonymous unions are unimplemented
+}
+
+union I {
+    _: (u8, u8), //~ ERROR unnamed fields can only have struct or union types
+}
+
+enum K {
+    M {
+        _ : union { field: u8 }, //~ ERROR anonymous unions are not allowed outside of unnamed struct or union fields
+        //~^ ERROR unnamed fields are not allowed outside of structs or unions
+        //~| ERROR anonymous unions are unimplemented
+    },
+    N {
+        _ : u8, //~ ERROR unnamed fields are not allowed outside of structs or unions
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr b/tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr
new file mode 100644
index 00000000000..c65cad775a9
--- /dev/null
+++ b/tests/ui/union/unnamed-fields/restrict_anonymous_unions.stderr
@@ -0,0 +1,78 @@
+error: anonymous unions are not allowed outside of unnamed struct or union fields
+  --> $DIR/restrict_anonymous_unions.rs:5:12
+   |
+LL |     field: union { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
+
+error: unnamed fields can only have struct or union types
+  --> $DIR/restrict_anonymous_unions.rs:12:5
+   |
+LL |     _: (u8, u8),
+   |     ^  -------- not a struct or union
+
+error: anonymous unions are not allowed outside of unnamed struct or union fields
+  --> $DIR/restrict_anonymous_unions.rs:16:12
+   |
+LL |     field: union { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
+
+error: unnamed fields can only have struct or union types
+  --> $DIR/restrict_anonymous_unions.rs:23:5
+   |
+LL |     _: (u8, u8),
+   |     ^  -------- not a struct or union
+
+error: unnamed fields are not allowed outside of structs or unions
+  --> $DIR/restrict_anonymous_unions.rs:28:9
+   |
+LL |         _ : union { field: u8 },
+   |         -^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         unnamed field declared here
+
+error: anonymous unions are not allowed outside of unnamed struct or union fields
+  --> $DIR/restrict_anonymous_unions.rs:28:13
+   |
+LL |         _ : union { field: u8 },
+   |             ^^^^^^^^^^^^^^^^^^^ anonymous union declared here
+
+error: unnamed fields are not allowed outside of structs or unions
+  --> $DIR/restrict_anonymous_unions.rs:33:9
+   |
+LL |         _ : u8,
+   |         -^^^^^
+   |         |
+   |         unnamed field declared here
+
+error: anonymous unions are unimplemented
+  --> $DIR/restrict_anonymous_unions.rs:5:12
+   |
+LL |     field: union { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^
+
+error: anonymous unions are unimplemented
+  --> $DIR/restrict_anonymous_unions.rs:7:8
+   |
+LL |     _: union { field: u8 },
+   |        ^^^^^^^^^^^^^^^^^^^
+
+error: anonymous unions are unimplemented
+  --> $DIR/restrict_anonymous_unions.rs:16:12
+   |
+LL |     field: union { field: u8 },
+   |            ^^^^^^^^^^^^^^^^^^^
+
+error: anonymous unions are unimplemented
+  --> $DIR/restrict_anonymous_unions.rs:18:8
+   |
+LL |     _: union { field: u8 },
+   |        ^^^^^^^^^^^^^^^^^^^
+
+error: anonymous unions are unimplemented
+  --> $DIR/restrict_anonymous_unions.rs:28:13
+   |
+LL |         _ : union { field: u8 },
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr b/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr
index aa73b824a57..32f8d2f45dc 100644
--- a/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr
+++ b/tests/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr
@@ -1,18 +1,18 @@
 error: unknown lint: `test_unstable_lint`
    |
    = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
    = note: requested on the command line with `-D unknown-lints`
 
 error: unknown lint: `test_unstable_lint`
    |
    = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
 
 error: unknown lint: `test_unstable_lint`
    |
    = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr
index 82851c80064..dd9ecf02fa6 100644
--- a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr
+++ b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr
@@ -1,18 +1,18 @@
 warning: unknown lint: `test_unstable_lint`
    |
    = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
    = note: requested on the command line with `-W unknown-lints`
 
 warning: unknown lint: `test_unstable_lint`
    |
    = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
 
 warning: unknown lint: `test_unstable_lint`
    |
    = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = help: add `-Zcrate-attr="feature(test_unstable_lint)"` to the command-line options to enable
 
 warning: 3 warnings emitted
 
diff --git a/triagebot.toml b/triagebot.toml
index a06195cc334..aef5b5bb8dc 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -177,6 +177,98 @@ exclude_labels = [
     "T-*",
 ]
 
+[autolabel."O-android"]
+trigger_files = [
+    "library/std/src/os/android"
+]
+
+[autolabel."O-fuchsia"]
+trigger_files = [
+    "library/std/src/os/fuchsia"
+]
+
+[autolabel."O-hermit"]
+trigger_files = [
+    "library/std/src/sys/hermit",
+    "library/std/src/os/hermit"
+]
+
+[autolabel."O-ios"]
+trigger_files = [
+    "library/std/src/os/ios"
+]
+
+[autolabel."O-itron"]
+trigger_files = [
+    "library/std/src/sys/itron"
+]
+
+[autolabel."O-linux"]
+trigger_files = [
+    "library/std/src/os/linux"
+]
+
+[autolabel."O-macos"]
+trigger_files = [
+    "library/std/src/os/macos"
+]
+
+[autolabel."O-netbsd"]
+trigger_files = [
+    "library/std/src/os/netbsd"
+]
+
+[autolabel."O-redox"]
+trigger_files = [
+    "library/std/src/os/redox"
+]
+
+[autolabel."O-SGX"]
+trigger_files = [
+    "library/std/src/sys/sgx",
+    "library/std/src/os/fortanix_sgx"
+]
+
+[autolabel."O-solaris"]
+trigger_files = [
+    "library/std/src/os/solaris"
+]
+
+[autolabel."O-solid"]
+trigger_files = [
+    "library/std/src/sys/solid",
+    "library/std/src/os/solid"
+]
+
+[autolabel."O-unix"]
+trigger_files = [
+    "library/std/src/sys/unix",
+    "library/std/src/os/unix"
+]
+
+[autolabel."O-wasi"]
+trigger_files = [
+    "library/std/src/sys/wasi",
+    "library/std/src/os/wasi"
+]
+
+[autolabel."O-wasm"]
+trigger_files = [
+    "library/std/src/sys/wasm",
+    "library/std/src/os/wasm"
+]
+
+[autolabel."O-watchos"]
+trigger_files = [
+    "library/std/src/os/watchos"
+]
+
+[autolabel."O-windows"]
+trigger_files = [
+    "library/std/src/sys/windows",
+    "library/std/src/os/windows"
+]
+
 [autolabel."T-bootstrap"]
 trigger_files = [
     "x.py",
@@ -470,6 +562,10 @@ Otherwise, you can ignore this comment.
 [mentions."src/tools/x"]
 message = "`src/tools/x` was changed. Bump version of Cargo.toml in `src/tools/x` so tidy will suggest installing the new version."
 
+[mentions."src/tools/tidy/src/deps.rs"]
+message = "Third-party dependency whitelist may have been modified! You must ensure that any new dependencies have compatible licenses before merging."
+cc = ["@davidtwco", "@wesleywiser"]
+
 [mentions."src/bootstrap/defaults/config.compiler.toml"]
 message = "This PR changes src/bootstrap/defaults/config.compiler.toml. If appropriate, please also update `config.codegen.toml` so the defaults are in sync."
 [mentions."src/bootstrap/defaults/config.codegen.toml"]
@@ -505,7 +601,6 @@ compiler-team-contributors = [
     "@TaKO8Ki",
     "@WaffleLapkin",
     "@b-naber",
-    "@fee1-dead",
 ]
 compiler = [
     "compiler-team",