about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-20 02:19:41 +0000
committerbors <bors@rust-lang.org>2022-02-20 02:19:41 +0000
commit25ad89e47b5a04bdcdd36069ae12f02cc848e553 (patch)
tree01d95cce6d471bbb63cec92ac498dde3ebc6105a
parent26904687275a55864f32f3a7ba87b7711d063fd5 (diff)
parentf2d6770f779051f1f5a28451b68784d2103bca32 (diff)
downloadrust-25ad89e47b5a04bdcdd36069ae12f02cc848e553.tar.gz
rust-25ad89e47b5a04bdcdd36069ae12f02cc848e553.zip
Auto merge of #94174 - matthiaskrgr:rollup-snyrlhy, r=matthiaskrgr
Rollup of 14 pull requests

Successful merges:

 - #93580 (Stabilize pin_static_ref.)
 - #93639 (Release notes for 1.59)
 - #93686 (core: Implement ASCII trim functions on byte slices)
 - #94002 (rustdoc: Avoid duplicating macros in sidebar)
 - #94019 (removing architecture requirements for RustyHermit)
 - #94023 (adapt static-nobundle test to use llvm-nm)
 - #94091 (Fix rustdoc const computed value)
 - #94093 (Fix pretty printing of enums without variants)
 - #94097 (Add module-level docs for `rustc_middle::query`)
 - #94112 (Optimize char_try_from_u32)
 - #94113 (document rustc_middle::mir::Field)
 - #94122 (Fix miniz_oxide types showing up in std docs)
 - #94142 (rustc_typeck: adopt let else in more places)
 - #94146 (Adopt let else in more places)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock15
-rw-r--r--RELEASES.md165
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs5
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs10
-rw-r--r--compiler/rustc_ast_passes/src/show_span.rs5
-rw-r--r--compiler/rustc_attr/src/builtin.rs24
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs25
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs11
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs10
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs5
-rw-r--r--compiler/rustc_borrowck/src/lib.rs5
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs12
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs76
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_accessible.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/compile_error.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs23
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs15
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs21
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs21
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs32
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs15
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs4
-rw-r--r--compiler/rustc_data_structures/src/binary_search_util/mod.rs5
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/transitive_relation.rs12
-rw-r--r--compiler/rustc_driver/src/lib.rs6
-rw-r--r--compiler/rustc_errors/src/emitter.rs10
-rw-r--r--compiler/rustc_expand/src/base.rs23
-rw-r--r--compiler/rustc_expand/src/config.rs27
-rw-r--r--compiler/rustc_expand/src/expand.rs10
-rw-r--r--compiler/rustc_expand/src/module.rs31
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs5
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs48
-rw-r--r--compiler/rustc_index/src/interval.rs18
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs31
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs15
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs10
-rw-r--r--compiler/rustc_interface/src/queries.rs5
-rw-r--r--compiler/rustc_interface/src/util.rs5
-rw-r--r--compiler/rustc_lint/src/context.rs5
-rw-r--r--compiler/rustc_lint/src/internal.rs5
-rw-r--r--compiler/rustc_lint/src/levels.rs6
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs5
-rw-r--r--compiler/rustc_lint/src/types.rs9
-rw-r--r--compiler/rustc_metadata/src/creader.rs10
-rw-r--r--compiler/rustc_metadata/src/foreign_modules.rs5
-rw-r--r--compiler/rustc_metadata/src/locator.rs13
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs27
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs5
-rw-r--r--compiler/rustc_middle/src/middle/region.rs5
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs5
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs9
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs10
-rw-r--r--compiler/rustc_middle/src/query/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs7
-rw-r--r--compiler/rustc_middle/src/ty/context.rs10
-rw-r--r--compiler/rustc_middle/src/ty/error.rs9
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs15
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs12
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs5
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs17
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs16
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs15
-rw-r--r--compiler/rustc_mir_dataflow/src/drop_flag_effects.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/mod.rs20
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs5
-rw-r--r--compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs5
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs9
-rw-r--r--compiler/rustc_mir_transform/src/deaggregator.rs7
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs9
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs22
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs5
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs9
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs5
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs5
-rw-r--r--compiler/rustc_mir_transform/src/nrvo.rs9
-rw-r--r--compiler/rustc_mir_transform/src/remove_zsts.rs5
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs5
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs10
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs10
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs16
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs5
-rw-r--r--compiler/rustc_parse/src/parser/item.rs5
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs5
-rw-r--r--compiler/rustc_passes/src/check_attr.rs21
-rw-r--r--compiler/rustc_passes/src/intrinsicck.rs61
-rw-r--r--compiler/rustc_passes/src/liveness.rs5
-rw-r--r--compiler/rustc_passes/src/reachable.rs5
-rw-r--r--compiler/rustc_passes/src/stability.rs10
-rw-r--r--compiler/rustc_resolve/src/imports.rs19
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs9
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs24
-rw-r--r--compiler/rustc_resolve/src/lib.rs7
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs5
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs18
-rw-r--r--compiler/rustc_serialize/src/json.rs5
-rw-r--r--compiler/rustc_serialize/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/options.rs18
-rw-r--r--compiler/rustc_span/src/lib.rs11
-rw-r--r--compiler/rustc_target/src/abi/mod.rs9
-rw-r--r--compiler/rustc_target/src/lib.rs1
-rw-r--r--compiler/rustc_traits/src/chalk/db.rs5
-rw-r--r--compiler/rustc_traits/src/lib.rs1
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs1
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs5
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs9
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs11
-rw-r--r--compiler/rustc_typeck/src/check/cast.rs10
-rw-r--r--compiler/rustc_typeck/src/check/check.rs16
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs9
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs21
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs45
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs15
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs17
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs5
-rw-r--r--compiler/rustc_typeck/src/check/method/confirm.rs18
-rw-r--r--compiler/rustc_typeck/src/check/method/mod.rs15
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs5
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs22
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs10
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs23
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls.rs7
-rw-r--r--compiler/rustc_typeck/src/coherence/orphan.rs5
-rw-r--r--compiler/rustc_typeck/src/collect.rs56
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs9
-rw-r--r--compiler/rustc_typeck/src/mem_categorization.rs27
-rw-r--r--compiler/rustc_typeck/src/outlives/outlives_bounds.rs9
-rw-r--r--library/core/src/char/convert.rs17
-rw-r--r--library/core/src/pin.rs4
-rw-r--r--library/core/src/slice/ascii.rs78
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/src/lib.rs5
-rw-r--r--library/std/src/sys/hermit/fd.rs2
-rw-r--r--src/bootstrap/dist.rs1
-rw-r--r--src/librustdoc/clean/utils.rs6
-rw-r--r--src/librustdoc/html/render/context.rs17
-rw-r--r--src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff95
-rw-r--r--src/test/mir-opt/const_prop/invalid_constant.rs41
-rw-r--r--src/test/run-make-fulldeps/static-nobundle/Makefile6
-rw-r--r--src/test/rustdoc-gui/duplicate-macro-reexport.goml14
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs3
-rw-r--r--src/test/rustdoc-gui/src/test_docs/macros.rs4
-rw-r--r--src/test/rustdoc/const-value-display.rs9
177 files changed, 1105 insertions, 1196 deletions
diff --git a/Cargo.lock b/Cargo.lock
index fd65ed8d4a2..152689953b8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -154,7 +154,7 @@ version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
 dependencies = [
- "hermit-abi",
+ "hermit-abi 0.1.19",
  "libc",
  "winapi",
 ]
@@ -1611,6 +1611,15 @@ version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
 dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ab7905ea95c6d9af62940f9d7dd9596d54c334ae2c15300c482051292d5637f"
+dependencies = [
  "compiler_builtins",
  "libc",
  "rustc-std-workspace-core",
@@ -2396,7 +2405,7 @@ version = "1.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
 dependencies = [
- "hermit-abi",
+ "hermit-abi 0.1.19",
  "libc",
 ]
 
@@ -4782,7 +4791,7 @@ dependencies = [
  "dlmalloc",
  "fortanix-sgx-abi",
  "hashbrown 0.12.0",
- "hermit-abi",
+ "hermit-abi 0.2.0",
  "libc",
  "miniz_oxide",
  "object 0.26.2",
diff --git a/RELEASES.md b/RELEASES.md
index a9422fa103e..96da1660c0f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,168 @@
+Version 1.59.0 (2022-02-24)
+==========================
+
+Language
+--------
+
+- [Stabilize default arguments for const generics][90207]
+- [Stabilize destructuring assignment][90521]
+- [Relax private in public lint on generic bounds and where clauses of trait impls][90586]
+- [Stabilize asm! and global_asm! for x86, x86_64, ARM, Aarch64, and RISC-V][91728]
+
+Compiler
+--------
+
+- [Stabilize new symbol mangling format, leaving it opt-in (-Csymbol-mangling-version=v0)][90128]
+- [Emit LLVM optimization remarks when enabled with `-Cremark`][90833]
+- [Fix sparc64 ABI for aggregates with floating point members][91003]
+- [Warn when a `#[test]`-like built-in attribute macro is present multiple times.][91172]
+- [Add support for riscv64gc-unknown-freebsd][91284]
+- [Stabilize `-Z emit-future-incompat` as `--json future-incompat`][91535]
+
+Libraries
+---------
+
+- [Remove unnecessary bounds for some Hash{Map,Set} methods][91593]
+
+Stabilized APIs
+---------------
+
+- [`std::thread::available_parallelism`][available_parallelism]
+- [`Result::copied`][result-copied]
+- [`Result::cloned`][result-cloned]
+- [`arch::asm!`][asm]
+- [`arch::global_asm!`][global_asm]
+- [`ops::ControlFlow::is_break`][is_break]
+- [`ops::ControlFlow::is_continue`][is_continue]
+- [`TryFrom<char> for u8`][try_from_char_u8]
+- [`char::TryFromCharError`][try_from_char_err]
+  implementing `Clone`, `Debug`, `Display`, `PartialEq`, `Copy`, `Eq`, `Error`
+- [`iter::zip`][zip]
+- [`NonZeroU8::is_power_of_two`][is_power_of_two8]
+- [`NonZeroU16::is_power_of_two`][is_power_of_two16]
+- [`NonZeroU32::is_power_of_two`][is_power_of_two32]
+- [`NonZeroU64::is_power_of_two`][is_power_of_two64]
+- [`NonZeroU128::is_power_of_two`][is_power_of_two128]
+- [`DoubleEndedIterator for ToLowercase`][lowercase]
+- [`DoubleEndedIterator for ToUppercase`][uppercase]
+- [`TryFrom<&mut [T]> for [T; N]`][tryfrom_ref_arr]
+- [`UnwindSafe for Once`][unwindsafe_once]
+- [`RefUnwindSafe for Once`][refunwindsafe_once]
+- [armv8 neon intrinsics for aarch64][stdarch/1266]
+
+Const-stable:
+
+- [`mem::MaybeUninit::as_ptr`][muninit_ptr]
+- [`mem::MaybeUninit::assume_init`][muninit_init]
+- [`mem::MaybeUninit::assume_init_ref`][muninit_init_ref]
+- [`ffi::CStr::from_bytes_with_nul_unchecked`][cstr_from_bytes]
+
+Cargo
+-----
+
+- [Stabilize the `strip` profile option][cargo/10088]
+- [Stabilize future-incompat-report][cargo/10165]
+- [Support abbreviating `--release` as `-r`][cargo/10133]
+- [Support `term.quiet` configuration][cargo/10152]
+- [Remove `--host` from cargo {publish,search,login}][cargo/10145]
+
+Compatibility Notes
+-------------------
+
+- [Refactor weak symbols in std::sys::unix][90846]
+  This may add new, versioned, symbols when building with a newer glibc, as the
+  standard library uses weak linkage rather than dynamically attempting to load
+  certain symbols at runtime.
+- [Deprecate crate_type and crate_name nested inside `#![cfg_attr]`][83744]
+  This adds a future compatibility lint to supporting the use of cfg_attr
+  wrapping either crate_type or crate_name specification within Rust files;
+  it is recommended that users migrate to setting the equivalent command line
+  flags.
+- [Remove effect of `#[no_link]` attribute on name resolution][92034]
+  This may expose new names, leading to conflicts with preexisting names in a
+  given namespace and a compilation failure.
+- [Cargo will document libraries before binaries.][cargo/10172]
+- [Respect doc=false in dependencies, not just the root crate][cargo/10201]
+- [Weaken guarantee around advancing underlying iterators in zip][83791]
+- [Make split_inclusive() on an empty slice yield an empty output][89825]
+- [Update std::env::temp_dir to use GetTempPath2 on Windows when available.][89999]
+
+Internal Changes
+----------------
+
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc
+and related tools.
+
+- [Fix many cases of normalization-related ICEs][91255]
+- [Replace dominators algorithm with simple Lengauer-Tarjan][85013]
+- [Store liveness in interval sets for region inference][90637]
+
+- [Remove `in_band_lifetimes` from the compiler and standard library, in preparation for removing this
+  unstable feature.][91867]
+
+[91867]: https://github.com/rust-lang/rust/issues/91867
+[83744]: https://github.com/rust-lang/rust/pull/83744/
+[83791]: https://github.com/rust-lang/rust/pull/83791/
+[85013]: https://github.com/rust-lang/rust/pull/85013/
+[89825]: https://github.com/rust-lang/rust/pull/89825/
+[89999]: https://github.com/rust-lang/rust/pull/89999/
+[90128]: https://github.com/rust-lang/rust/pull/90128/
+[90207]: https://github.com/rust-lang/rust/pull/90207/
+[90521]: https://github.com/rust-lang/rust/pull/90521/
+[90586]: https://github.com/rust-lang/rust/pull/90586/
+[90637]: https://github.com/rust-lang/rust/pull/90637/
+[90833]: https://github.com/rust-lang/rust/pull/90833/
+[90846]: https://github.com/rust-lang/rust/pull/90846/
+[91003]: https://github.com/rust-lang/rust/pull/91003/
+[91172]: https://github.com/rust-lang/rust/pull/91172/
+[91255]: https://github.com/rust-lang/rust/pull/91255/
+[91284]: https://github.com/rust-lang/rust/pull/91284/
+[91535]: https://github.com/rust-lang/rust/pull/91535/
+[91593]: https://github.com/rust-lang/rust/pull/91593/
+[91728]: https://github.com/rust-lang/rust/pull/91728/
+[91878]: https://github.com/rust-lang/rust/pull/91878/
+[91896]: https://github.com/rust-lang/rust/pull/91896/
+[91926]: https://github.com/rust-lang/rust/pull/91926/
+[91984]: https://github.com/rust-lang/rust/pull/91984/
+[92020]: https://github.com/rust-lang/rust/pull/92020/
+[92034]: https://github.com/rust-lang/rust/pull/92034/
+[92483]: https://github.com/rust-lang/rust/pull/92483/
+[cargo/10088]: https://github.com/rust-lang/cargo/pull/10088/
+[cargo/10133]: https://github.com/rust-lang/cargo/pull/10133/
+[cargo/10145]: https://github.com/rust-lang/cargo/pull/10145/
+[cargo/10152]: https://github.com/rust-lang/cargo/pull/10152/
+[cargo/10165]: https://github.com/rust-lang/cargo/pull/10165/
+[cargo/10172]: https://github.com/rust-lang/cargo/pull/10172/
+[cargo/10201]: https://github.com/rust-lang/cargo/pull/10201/
+[cargo/10269]: https://github.com/rust-lang/cargo/pull/10269/
+
+[cstr_from_bytes]: https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.from_bytes_with_nul_unchecked
+[muninit_ptr]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_ptr
+[muninit_init]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init
+[muninit_init_ref]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
+[unwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-UnwindSafe
+[refunwindsafe_once]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#impl-RefUnwindSafe
+[tryfrom_ref_arr]: https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html#impl-TryFrom%3C%26%27_%20mut%20%5BT%5D%3E
+[lowercase]: https://doc.rust-lang.org/stable/std/char/struct.ToLowercase.html#impl-DoubleEndedIterator
+[uppercase]: https://doc.rust-lang.org/stable/std/char/struct.ToUppercase.html#impl-DoubleEndedIterator
+[try_from_char_err]: https://doc.rust-lang.org/stable/std/char/struct.TryFromCharError.html
+[available_parallelism]: https://doc.rust-lang.org/stable/std/thread/fn.available_parallelism.html
+[result-copied]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.copied
+[result-cloned]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.cloned
+[asm]: https://doc.rust-lang.org/stable/core/arch/macro.asm.html
+[global_asm]: https://doc.rust-lang.org/stable/core/arch/macro.global_asm.html
+[is_break]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_break
+[is_continue]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html#method.is_continue
+[try_from_char_u8]: https://doc.rust-lang.org/stable/std/primitive.char.html#impl-TryFrom%3Cchar%3E
+[zip]: https://doc.rust-lang.org/stable/std/iter/fn.zip.html
+[is_power_of_two8]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU8.html#method.is_power_of_two
+[is_power_of_two16]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU16.html#method.is_power_of_two
+[is_power_of_two32]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU32.html#method.is_power_of_two
+[is_power_of_two64]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU64.html#method.is_power_of_two
+[is_power_of_two128]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroU128.html#method.is_power_of_two
+[stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266
+
 Version 1.58.1 (2022-01-19)
 ===========================
 
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 18fcc99ffba..0211d7b3367 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -339,9 +339,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                                     let idx2 = *o.get();
                                     let &(ref op2, op_sp2) = &operands[idx2];
-                                    let reg2 = match op2.reg() {
-                                        Some(asm::InlineAsmRegOrRegClass::Reg(r)) => r,
-                                        _ => unreachable!(),
+                                    let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg() else {
+                                        unreachable!();
                                     };
 
                                     let msg = format!(
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index d48ff10b97d..d64f1a05712 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -330,9 +330,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         args: Vec<AstP<Expr>>,
         legacy_args_idx: &[usize],
     ) -> hir::ExprKind<'hir> {
-        let path = match f.kind {
-            ExprKind::Path(None, ref mut path) => path,
-            _ => unreachable!(),
+        let ExprKind::Path(None, ref mut path) = f.kind else {
+            unreachable!();
         };
 
         // Split the arguments into const generics and normal arguments
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 6489c729cfe..e230b2dd49f 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1376,9 +1376,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
         // where clauses for `?Sized`.
         for pred in &generics.where_clause.predicates {
-            let bound_pred = match *pred {
-                WherePredicate::BoundPredicate(ref bound_pred) => bound_pred,
-                _ => continue,
+            let WherePredicate::BoundPredicate(ref bound_pred) = *pred else {
+                continue;
             };
             let compute_is_param = || {
                 // Check if the where clause type is a plain type parameter.
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index eb7c75cac05..20caed1b230 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -482,9 +482,8 @@ impl<'a> AstValidator<'a> {
     }
 
     fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
-        let body = match body {
-            None => return,
-            Some(body) => body,
+        let Some(body) = body else {
+            return;
         };
         self.err_handler()
             .struct_span_err(ident.span, &format!("incorrect `{}` inside `extern` block", kind))
@@ -504,9 +503,8 @@ impl<'a> AstValidator<'a> {
 
     /// An `fn` in `extern { ... }` cannot have a body `{ ... }`.
     fn check_foreign_fn_bodyless(&self, ident: Ident, body: Option<&Block>) {
-        let body = match body {
-            None => return,
-            Some(body) => body,
+        let Some(body) = body else {
+            return;
         };
         self.err_handler()
             .struct_span_err(ident.span, "incorrect function inside `extern` block")
diff --git a/compiler/rustc_ast_passes/src/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs
index 6cef26a13e6..27637e311f4 100644
--- a/compiler/rustc_ast_passes/src/show_span.rs
+++ b/compiler/rustc_ast_passes/src/show_span.rs
@@ -57,9 +57,8 @@ impl<'a> Visitor<'a> for ShowSpanVisitor<'a> {
 }
 
 pub fn run(span_diagnostic: &rustc_errors::Handler, mode: &str, krate: &ast::Crate) {
-    let mode = match mode.parse().ok() {
-        Some(mode) => mode,
-        None => return,
+    let Ok(mode) = mode.parse() else {
+        return;
     };
     let mut v = ShowSpanVisitor { span_diagnostic, mode };
     visit::walk_crate(&mut v, krate);
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 49043e9f5f9..8d6c8c24785 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -556,17 +556,14 @@ pub fn eval_condition(
                     return false;
                 }
             };
-            let min_version = match parse_version(min_version.as_str(), false) {
-                Some(ver) => ver,
-                None => {
-                    sess.span_diagnostic
-                        .struct_span_warn(
-                            *span,
-                            "unknown version literal format, assuming it refers to a future version",
-                        )
-                        .emit();
-                    return false;
-                }
+            let Some(min_version) = parse_version(min_version.as_str(), false) else {
+                sess.span_diagnostic
+                    .struct_span_warn(
+                        *span,
+                        "unknown version literal format, assuming it refers to a future version",
+                    )
+                    .emit();
+                return false;
             };
             let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap();
 
@@ -669,9 +666,8 @@ where
             break;
         }
 
-        let meta = match attr.meta() {
-            Some(meta) => meta,
-            None => continue,
+        let Some(meta) = attr.meta() else {
+            continue;
         };
         let mut since = None;
         let mut note = None;
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index fce5ed0ef42..6988fbf8336 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2071,11 +2071,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         ) = rvalue
                         {
                             for operand in operands {
-                                let assigned_from = match operand {
-                                    Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
-                                        assigned_from
-                                    }
-                                    _ => continue,
+                                let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else {
+                                    continue;
                                 };
                                 debug!(
                                     "annotate_argument_and_return_for_borrow: assigned_from={:?}",
@@ -2083,10 +2080,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                 );
 
                                 // Find the local from the operand.
-                                let assigned_from_local = match assigned_from.local_or_deref_local()
-                                {
-                                    Some(local) => local,
-                                    None => continue,
+                                let Some(assigned_from_local) = assigned_from.local_or_deref_local() else {
+                                    continue;
                                 };
 
                                 if assigned_from_local != target {
@@ -2138,10 +2133,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         );
 
                         // Find the local from the rvalue.
-                        let assigned_from_local = match assigned_from.local_or_deref_local() {
-                            Some(local) => local,
-                            None => continue,
-                        };
+                        let Some(assigned_from_local) = assigned_from.local_or_deref_local() else { continue };
                         debug!(
                             "annotate_argument_and_return_for_borrow: \
                              assigned_from_local={:?}",
@@ -2189,11 +2181,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         assigned_to, args
                     );
                     for operand in args {
-                        let assigned_from = match operand {
-                            Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
-                                assigned_from
-                            }
-                            _ => continue,
+                        let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand else {
+                            continue;
                         };
                         debug!(
                             "annotate_argument_and_return_for_borrow: assigned_from={:?}",
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index db8268c8e2e..b1e5a211cf1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -650,13 +650,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
                 // The only kind of statement that we care about is assignments...
                 if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind {
-                    let into = match place.local_or_deref_local() {
-                        Some(into) => into,
-                        None => {
-                            // Continue at the next location.
-                            queue.push(current_location.successor_within_block());
-                            continue;
-                        }
+                    let Some(into) = place.local_or_deref_local() else {
+                        // Continue at the next location.
+                        queue.push(current_location.successor_within_block());
+                        continue;
                     };
 
                     match rvalue {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 73b0d398285..5f533ddcb82 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -444,10 +444,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     debug!("borrowed_content_source: init={:?}", init);
                     // We're only interested in statements that initialized a value, not the
                     // initializations from arguments.
-                    let loc = match init.location {
-                        InitLocation::Statement(stmt) => stmt,
-                        _ => continue,
-                    };
+                    let InitLocation::Statement(loc) = init.location else { continue };
 
                     let bbd = &self.body[loc.block];
                     let is_terminator = bbd.statements.len() == loc.statement_index;
@@ -787,9 +784,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     ) -> UseSpans<'tcx> {
         use self::UseSpans::*;
 
-        let stmt = match self.body[location.block].statements.get(location.statement_index) {
-            Some(stmt) => stmt,
-            None => return OtherUse(self.body.source_info(location).span),
+        let Some(stmt) = self.body[location.block].statements.get(location.statement_index) else {
+            return OtherUse(self.body.source_info(location).span);
         };
 
         debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index cc6566882ad..d4f238ff71f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -188,10 +188,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             }
             // Error with the pattern
             LookupResult::Exact(_) => {
-                let mpi = match self.move_data.rev_lookup.find(move_from.as_ref()) {
-                    LookupResult::Parent(Some(mpi)) => mpi,
+                let LookupResult::Parent(Some(mpi)) = self.move_data.rev_lookup.find(move_from.as_ref()) else {
                     // move_from should be a projection from match_place.
-                    _ => unreachable!("Probably not unreachable..."),
+                    unreachable!("Probably not unreachable...");
                 };
                 for ge in &mut *grouped_errors {
                     if let GroupedMoveError::MovesFromValue {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 459b03b0fad..719862e67c8 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1914,10 +1914,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             // without going over a Deref.
             let mut shortest_uninit_seen = None;
             for prefix in this.prefixes(base, PrefixSet::Shallow) {
-                let mpi = match this.move_path_for_place(prefix) {
-                    Some(mpi) => mpi,
-                    None => continue,
-                };
+                let Some(mpi) = this.move_path_for_place(prefix) else { continue };
 
                 if maybe_uninits.contains(mpi) {
                     debug!(
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index abd6a15334c..b99fb00599e 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -913,9 +913,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test;
 
         let generic_ty = generic_kind.to_ty(tcx);
-        let subject = match self.try_promote_type_test_subject(infcx, generic_ty) {
-            Some(s) => s,
-            None => return false,
+        let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
+            return false;
         };
 
         // For each region outlived by lower_bound find a non-local,
@@ -1623,15 +1622,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // If we have some bound universal region `'a`, then the only
         // elements it can contain is itself -- we don't know anything
         // else about it!
-        let error_element = match {
+        let Some(error_element) = ({
             self.scc_values.elements_contained_in(longer_fr_scc).find(|element| match element {
                 RegionElement::Location(_) => true,
                 RegionElement::RootUniversalRegion(_) => true,
                 RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1,
             })
-        } {
-            Some(v) => v,
-            None => return,
+        }) else {
+            return;
         };
         debug!("check_bound_universal_region: error_element = {:?}", error_element);
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index a5824090096..89b14129d01 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -810,13 +810,12 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                 ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
                 ty::Generator(def_id, substs, _) => {
                     let mut variants = substs.as_generator().state_tys(def_id, tcx);
-                    let mut variant = match variants.nth(variant_index.into()) {
-                        Some(v) => v,
-                        None => bug!(
+                    let Some(mut variant) = variants.nth(variant_index.into()) else {
+                        bug!(
                             "variant_index of generator out of range: {:?}/{:?}",
                             variant_index,
                             substs.as_generator().state_tys(def_id, tcx).count()
-                        ),
+                        );
                     };
                     return match variant.nth(field.index()) {
                         Some(ty) => Ok(ty),
@@ -2178,35 +2177,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
 
                     CastKind::Pointer(PointerCast::MutToConstPointer) => {
-                        let ty_from = match op.ty(body, tcx).kind() {
-                            ty::RawPtr(ty::TypeAndMut {
-                                ty: ty_from,
-                                mutbl: hir::Mutability::Mut,
-                            }) => ty_from,
-                            _ => {
-                                span_mirbug!(
-                                    self,
-                                    rvalue,
-                                    "unexpected base type for cast {:?}",
-                                    ty,
-                                );
-                                return;
-                            }
+                        let ty::RawPtr(ty::TypeAndMut {
+                            ty: ty_from,
+                            mutbl: hir::Mutability::Mut,
+                        }) = op.ty(body, tcx).kind() else {
+                            span_mirbug!(
+                                self,
+                                rvalue,
+                                "unexpected base type for cast {:?}",
+                                ty,
+                            );
+                            return;
                         };
-                        let ty_to = match ty.kind() {
-                            ty::RawPtr(ty::TypeAndMut {
-                                ty: ty_to,
-                                mutbl: hir::Mutability::Not,
-                            }) => ty_to,
-                            _ => {
-                                span_mirbug!(
-                                    self,
-                                    rvalue,
-                                    "unexpected target type for cast {:?}",
-                                    ty,
-                                );
-                                return;
-                            }
+                        let ty::RawPtr(ty::TypeAndMut {
+                            ty: ty_to,
+                            mutbl: hir::Mutability::Not,
+                        }) = ty.kind() else {
+                            span_mirbug!(
+                                self,
+                                rvalue,
+                                "unexpected target type for cast {:?}",
+                                ty,
+                            );
+                            return;
                         };
                         if let Err(terr) = self.sub_types(
                             *ty_from,
@@ -2238,17 +2231,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             _ => None,
                         };
 
-                        let (ty_elem, ty_mut) = match opt_ty_elem_mut {
-                            Some(ty_elem_mut) => ty_elem_mut,
-                            None => {
-                                span_mirbug!(
-                                    self,
-                                    rvalue,
-                                    "ArrayToPointer cast from unexpected type {:?}",
-                                    ty_from,
-                                );
-                                return;
-                            }
+                        let Some((ty_elem, ty_mut)) = opt_ty_elem_mut else {
+                            span_mirbug!(
+                                self,
+                                rvalue,
+                                "ArrayToPointer cast from unexpected type {:?}",
+                                ty_from,
+                            );
+                            return;
                         };
 
                         let (ty_to, ty_to_mut) = match ty.kind() {
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 72de3805467..33e65439fd7 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -641,9 +641,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 let (&output, tuplized_inputs) =
                     inputs_and_output.skip_binder().split_last().unwrap();
                 assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs");
-                let inputs = match tuplized_inputs[0].kind() {
-                    ty::Tuple(inputs) => inputs,
-                    _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]),
+                let ty::Tuple(inputs) = tuplized_inputs[0].kind() else {
+                    bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]);
                 };
 
                 ty::Binder::bind_with_vars(
diff --git a/compiler/rustc_builtin_macros/src/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
index 09ed1af3456..7b7db3eaea6 100644
--- a/compiler/rustc_builtin_macros/src/cfg_accessible.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
@@ -44,9 +44,8 @@ impl MultiItemModifier for Expander {
             template,
         );
 
-        let path = match validate_input(ecx, meta_item) {
-            Some(path) => path,
-            None => return ExpandResult::Ready(Vec::new()),
+        let Some(path) = validate_input(ecx, meta_item) else {
+            return ExpandResult::Ready(Vec::new());
         };
 
         match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs
index f5955604e5f..990b8829569 100644
--- a/compiler/rustc_builtin_macros/src/compile_error.rs
+++ b/compiler/rustc_builtin_macros/src/compile_error.rs
@@ -9,9 +9,8 @@ pub fn expand_compile_error<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
-    let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
-        None => return DummyResult::any(sp),
-        Some(v) => v,
+    let Some(var) = get_single_str_from_tts(cx, sp, tts, "compile_error!") else {
+        return DummyResult::any(sp);
     };
 
     cx.span_err(sp, &var);
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index 59361510a67..a23dd1d1213 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -10,9 +10,8 @@ pub fn expand_concat(
     sp: rustc_span::Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
-    let es = match base::get_exprs_from_tts(cx, sp, tts) {
-        Some(e) => e,
-        None => return DummyResult::any(sp),
+    let Some(es) = base::get_exprs_from_tts(cx, sp, tts) else {
+        return DummyResult::any(sp);
     };
     let mut accumulator = String::new();
     let mut missing_literal = vec![];
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index c06af5206d5..a1afec410c1 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -121,9 +121,8 @@ pub fn expand_concat_bytes(
     sp: rustc_span::Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
-    let es = match base::get_exprs_from_tts(cx, sp, tts) {
-        Some(e) => e,
-        None => return DummyResult::any(sp),
+    let Some(es) = base::get_exprs_from_tts(cx, sp, tts) else {
+        return DummyResult::any(sp);
     };
     let mut accumulator = Vec::new();
     let mut missing_literals = vec![];
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index 2e5ad66c60b..fd26a376f91 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -196,12 +196,11 @@ fn cs_clone(
             let fields = all_fields
                 .iter()
                 .map(|field| {
-                    let ident = match field.name {
-                        Some(i) => i,
-                        None => cx.span_bug(
+                    let Some(ident) = field.name else {
+                        cx.span_bug(
                             trait_span,
                             &format!("unnamed field in normal struct in `derive({})`", name,),
-                        ),
+                        );
                     };
                     let call = subcall(cx, field);
                     cx.field_imm(field.span, ident, call)
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index f84e6e07620..2b3ac0a86c1 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -83,9 +83,8 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<
             // }
 
             let new = {
-                let other_f = match other_fs {
-                    [o_f] => o_f,
-                    _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
+                let [other_f] = other_fs else {
+                    cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`");
                 };
 
                 let args =
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 8e9f15743cc..eead8b37024 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -26,9 +26,8 @@ pub fn expand_deriving_partial_eq(
         base: bool,
     ) -> P<Expr> {
         let op = |cx: &mut ExtCtxt<'_>, span: Span, self_f: P<Expr>, other_fs: &[P<Expr>]| {
-            let other_f = match other_fs {
-                [o_f] => o_f,
-                _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`"),
+            let [other_f] = other_fs else {
+                cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`");
             };
 
             cx.expr_binary(span, op, self_f, other_f.clone())
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 151a919e029..d28ac822a1e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -86,9 +86,8 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
             // }
 
             let new = {
-                let other_f = match other_fs {
-                    [o_f] => o_f,
-                    _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
+                let [other_f] = other_fs else {
+                    cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`");
                 };
 
                 let args =
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 1d1eee88a68..ca83941f600 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -101,9 +101,8 @@ fn default_enum_substructure(
     trait_span: Span,
     enum_def: &EnumDef,
 ) -> P<Expr> {
-    let default_variant = match extract_default_variant(cx, enum_def, trait_span) {
-        Ok(value) => value,
-        Err(()) => return DummyResult::raw_expr(trait_span, true),
+    let Ok(default_variant) = extract_default_variant(cx, enum_def, trait_span) else {
+        return DummyResult::raw_expr(trait_span, true);
     };
 
     // At this point, we know that there is exactly one variant with a `#[default]` attribute. The
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 7114b987680..f1d46f03bad 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -48,9 +48,8 @@ pub fn expand_deriving_hash(
 }
 
 fn hash_substructure(cx: &mut ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>) -> P<Expr> {
-    let state_expr = match substr.nonself_args {
-        [o_f] => o_f,
-        _ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`"),
+    let [state_expr] = substr.nonself_args else {
+        cx.span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`");
     };
     let call_hash = |span, thing_expr| {
         let hash_path = {
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index 0ca7988ca15..812d86af6e8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -116,9 +116,8 @@ fn inject_impl_of_structural_trait(
     structural_path: generic::ty::Path,
     push: &mut dyn FnMut(Annotatable),
 ) {
-    let item = match *item {
-        Annotatable::Item(ref item) => item,
-        _ => unreachable!(),
+    let Annotatable::Item(ref item) = *item else {
+        unreachable!();
     };
 
     let generics = match item.kind {
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 285027fc632..66ee93ce3c9 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -16,9 +16,8 @@ pub fn expand_option_env<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
-    let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
-        None => return DummyResult::any(sp),
-        Some(v) => v,
+    let Some(var) = get_single_str_from_tts(cx, sp, tts, "option_env!") else {
+        return DummyResult::any(sp);
     };
 
     let sp = cx.with_def_site_ctxt(sp);
@@ -62,9 +61,8 @@ pub fn expand_env<'cx>(
         Some(exprs) => exprs.into_iter(),
     };
 
-    let var = match expr_to_string(cx, exprs.next().unwrap(), "expected string literal") {
-        None => return DummyResult::any(sp),
-        Some((v, _style)) => v,
+    let Some((var, _style)) = expr_to_string(cx, exprs.next().unwrap(), "expected string literal") else {
+        return DummyResult::any(sp);
     };
     let msg = match exprs.next() {
         None => Symbol::intern(&format!("environment variable `{}` not defined", var)),
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index c9dd114047b..407ca2301e1 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -103,11 +103,9 @@ impl<'a> CollectProcMacros<'a> {
     }
 
     fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
-        let (trait_name, proc_attrs) =
-            match parse_macro_name_and_helper_attrs(self.handler, attr, "derive") {
-                Some(name_and_attrs) => name_and_attrs,
-                None => return,
-            };
+        let Some((trait_name, proc_attrs)) = parse_macro_name_and_helper_attrs(self.handler, attr, "derive") else {
+            return;
+        };
 
         if self.in_root && item.vis.kind.is_pub() {
             self.macros.push(ProcMacro::Derive(ProcMacroDerive {
@@ -219,15 +217,12 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
             }
         }
 
-        let attr = match found_attr {
-            None => {
-                self.check_not_pub_in_root(&item.vis, self.source_map.guess_head_span(item.span));
-                let prev_in_root = mem::replace(&mut self.in_root, false);
-                visit::walk_item(self, item);
-                self.in_root = prev_in_root;
-                return;
-            }
-            Some(attr) => attr,
+        let Some(attr) = found_attr else {
+            self.check_not_pub_in_root(&item.vis, self.source_map.guess_head_span(item.span));
+            let prev_in_root = mem::replace(&mut self.in_root, false);
+            visit::walk_item(self, item);
+            self.in_root = prev_in_root;
+            return;
         };
 
         if !is_fn {
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 1ea2c8843d6..bbc8e62d68f 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -98,9 +98,8 @@ pub fn expand_include<'cx>(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     let sp = cx.with_def_site_ctxt(sp);
-    let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
-        Some(f) => f,
-        None => return DummyResult::any(sp),
+    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include!") else {
+        return DummyResult::any(sp);
     };
     // The file will be added to the code map by the parser
     let file = match cx.resolve_path(file, sp) {
@@ -169,9 +168,8 @@ pub fn expand_include_str(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
-        Some(f) => f,
-        None => return DummyResult::any(sp),
+    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else {
+        return DummyResult::any(sp);
     };
     let file = match cx.resolve_path(file, sp) {
         Ok(f) => f,
@@ -204,9 +202,8 @@ pub fn expand_include_bytes(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
-        Some(f) => f,
-        None => return DummyResult::any(sp),
+    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else {
+        return DummyResult::any(sp);
     };
     let file = match cx.resolve_path(file, sp) {
         Ok(f) => f,
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 21bd1dae7ac..1a2cec2a0d9 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -310,10 +310,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
             if let Some(archive) = self.src_archive() {
                 for child in archive.iter() {
                     let child = child.map_err(string_to_io_error)?;
-                    let child_name = match child.name() {
-                        Some(s) => s,
-                        None => continue,
-                    };
+                    let Some(child_name) = child.name() else { continue };
                     if removals.iter().any(|r| r == child_name) {
                         continue;
                     }
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 384596dfff5..e60ad170434 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -826,20 +826,14 @@ pub(crate) unsafe fn codegen(
                 let input =
                     unsafe { slice::from_raw_parts(input_ptr as *const u8, input_len as usize) };
 
-                let input = match str::from_utf8(input) {
-                    Ok(s) => s,
-                    Err(_) => return 0,
-                };
+                let Ok(input) = str::from_utf8(input) else { return 0 };
 
                 let output = unsafe {
                     slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
                 };
                 let mut cursor = io::Cursor::new(output);
 
-                let demangled = match rustc_demangle::try_demangle(input) {
-                    Ok(d) => d,
-                    Err(_) => return 0,
-                };
+                let Ok(demangled) = rustc_demangle::try_demangle(input) else { return 0 };
 
                 if write!(cursor, "{:#}", demangled).is_err() {
                     // Possible only if provided buffer is not big enough
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 7b6ce5ea89b..e15b86aa84f 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -138,10 +138,7 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
 }
 
 pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
-    let sect = match attrs.link_section {
-        Some(name) => name,
-        None => return,
-    };
+    let Some(sect) = attrs.link_section else { return };
     unsafe {
         let buf = SmallCStr::new(sect.as_str());
         llvm::LLVMSetSection(llval, buf.as_ptr());
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 6707de93352..51223697dbd 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -369,10 +369,9 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
         unsafe {
             let attrs = self.tcx.codegen_fn_attrs(def_id);
 
-            let (v, alloc) = match codegen_static_initializer(self, def_id) {
-                Ok(v) => v,
+            let Ok((v, alloc)) = codegen_static_initializer(self, def_id) else {
                 // Error has already been reported
-                Err(_) => return,
+                return;
             };
 
             let g = self.get_static(def_id);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 1abc3fb523d..fd1e61f2b8a 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -766,18 +766,15 @@ pub fn type_metadata<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll
 
         if already_stored_in_typemap {
             // Also make sure that we already have a `TypeMap` entry for the unique type ID.
-            let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
-                Some(metadata) => metadata,
-                None => {
-                    bug!(
-                        "expected type metadata for unique \
-                               type ID '{}' to already be in \
-                               the `debuginfo::TypeMap` but it \
-                               was not. (Ty = {})",
-                        type_map.get_unique_type_id_as_string(unique_type_id),
-                        t
-                    );
-                }
+            let Some(metadata_for_uid) = type_map.find_metadata_for_unique_id(unique_type_id) else {
+                bug!(
+                    "expected type metadata for unique \
+                            type ID '{}' to already be in \
+                            the `debuginfo::TypeMap` but it \
+                            was not. (Ty = {})",
+                    type_map.get_unique_type_id_as_string(unique_type_id),
+                    t
+                );
             };
 
             match type_map.find_metadata_for_type(t) {
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index cfd23f5c24e..f471f461e86 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -88,9 +88,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
         let tcx = self.tcx;
         let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
 
-        let (def_id, substs) = match *callee_ty.kind() {
-            ty::FnDef(def_id, substs) => (def_id, substs),
-            _ => bug!("expected fn item type, found {}", callee_ty),
+        let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
+            bug!("expected fn item type, found {}", callee_ty);
         };
 
         let sig = callee_ty.fn_sig(tcx);
@@ -1000,9 +999,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
                 }
             })
             .collect();
-        let indices = match indices {
-            Some(i) => i,
-            None => return Ok(bx.const_null(llret_ty)),
+        let Some(indices) = indices else {
+            return Ok(bx.const_null(llret_ty));
         };
 
         return Ok(bx.shuffle_vector(
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index fafb9a6dbde..dc2df8849f8 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -339,9 +339,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
             _ => {}
         }
 
-        let (a, b) = match self.abi {
-            Abi::ScalarPair(a, b) => (a, b),
-            _ => bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self),
+        let Abi::ScalarPair(a, b) = self.abi else {
+            bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self);
         };
         let scalar = [a, b][index];
 
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 58e0667d678..5a07b23f3f9 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -674,9 +674,8 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
     loop {
         i += 1;
         prog = sess.time("run_linker", || exec_linker(sess, &cmd, out_filename, tmpdir));
-        let output = match prog {
-            Ok(ref output) => output,
-            Err(_) => break,
+        let Ok(ref output) = prog else {
+            break;
         };
         if output.status.success() {
             break;
@@ -2025,9 +2024,8 @@ fn add_local_native_libraries(
     let search_path = OnceCell::new();
     let mut last = (NativeLibKind::Unspecified, None);
     for lib in relevant_libs {
-        let name = match lib.name {
-            Some(l) => l,
-            None => continue,
+        let Some(name) = lib.name else {
+            continue;
         };
 
         // Skip if this library is the same as the last.
@@ -2382,9 +2380,8 @@ fn add_upstream_native_libraries(
     let mut last = (NativeLibKind::Unspecified, None);
     for &cnum in &codegen_results.crate_info.used_crates {
         for lib in codegen_results.crate_info.native_libraries[&cnum].iter() {
-            let name = match lib.name {
-                Some(l) => l,
-                None => continue,
+            let Some(name) = lib.name else {
+                continue;
             };
             if !relevant_lib(sess, &lib) {
                 continue;
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 9ebbcac76a2..39d39ad1365 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -79,15 +79,14 @@ fn search_for_metadata<'a>(
     bytes: &'a [u8],
     section: &str,
 ) -> Result<&'a [u8], String> {
-    let file = match object::File::parse(bytes) {
-        Ok(f) => f,
+    let Ok(file) = object::File::parse(bytes) else {
         // The parse above could fail for odd reasons like corruption, but for
         // now we just interpret it as this target doesn't support metadata
         // emission in object files so the entire byte slice itself is probably
         // a metadata file. Ideally though if necessary we could at least check
         // the prefix of bytes to see if it's an actual metadata object and if
         // not forward the error along here.
-        Err(_) => return Ok(bytes),
+        return Ok(bytes);
     };
     file.section_by_name(section)
         .ok_or_else(|| format!("no `{}` section in '{}'", section, path.display()))?
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index aeddd926896..8191d8b5e49 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -448,10 +448,7 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, S
     let mut ret = FxHashMap::default();
     for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
         let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
-        let module = match module {
-            Some(s) => s,
-            None => continue,
-        };
+        let Some(module) = module else { continue };
         ret.extend(lib.foreign_items.iter().map(|id| {
             assert_eq!(id.krate, cnum);
             (*id, module.to_string())
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 4a5eabc8755..ed6c156547e 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -409,18 +409,15 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         // listing.
         let main_ret_ty = cx.tcx().erase_regions(main_ret_ty.no_bound_vars().unwrap());
 
-        let llfn = match cx.declare_c_main(llfty) {
-            Some(llfn) => llfn,
-            None => {
-                // FIXME: We should be smart and show a better diagnostic here.
-                let span = cx.tcx().def_span(rust_main_def_id);
-                cx.sess()
-                    .struct_span_err(span, "entry symbol `main` declared multiple times")
-                    .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead")
-                    .emit();
-                cx.sess().abort_if_errors();
-                bug!();
-            }
+        let Some(llfn) = cx.declare_c_main(llfty) else {
+            // FIXME: We should be smart and show a better diagnostic here.
+            let span = cx.tcx().def_span(rust_main_def_id);
+            cx.sess()
+                .struct_span_err(span, "entry symbol `main` declared multiple times")
+                .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead")
+                .emit();
+            cx.sess().abort_if_errors();
+            bug!();
         };
 
         // `main` should respect same config for frame pointer elimination as rest of code
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index 2df58ecc9f6..ae54442e884 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -202,11 +202,8 @@ pub fn asm_const_to_str<'tcx>(
     const_value: ConstValue<'tcx>,
     ty_and_layout: TyAndLayout<'tcx>,
 ) -> String {
-    let scalar = match const_value {
-        ConstValue::Scalar(s) => s,
-        _ => {
-            span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value)
-        }
+    let ConstValue::Scalar(scalar) = const_value else {
+        span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value)
     };
     let value = scalar.assert_bits(ty_and_layout.size);
     match ty_and_layout.ty.kind() {
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 5cdf131b0b6..479b2b05f43 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -67,9 +67,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     .map(|field| {
                         if let Some(prim) = field.val().try_to_scalar() {
                             let layout = bx.layout_of(field_ty);
-                            let scalar = match layout.abi {
-                                Abi::Scalar(x) => x,
-                                _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
+                            let Abi::Scalar(scalar) = layout.abi else {
+                                bug!("from_const: invalid ByVal layout: {:#?}", layout);
                             };
                             bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
                         } else {
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index c710fcc2c1d..bb53c722a24 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -258,14 +258,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let vars = vars.iter().copied().chain(fallback_var);
 
         for var in vars {
-            let dbg_var = match var.dbg_var {
-                Some(dbg_var) => dbg_var,
-                None => continue,
-            };
-            let dbg_loc = match self.dbg_loc(var.source_info) {
-                Some(dbg_loc) => dbg_loc,
-                None => continue,
-            };
+            let Some(dbg_var) = var.dbg_var else { continue };
+            let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
 
             let mut direct_offset = Size::ZERO;
             // FIXME(eddyb) use smallvec here.
@@ -410,10 +404,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
                 mir::VarDebugInfoContents::Const(c) => {
                     if let Some(dbg_var) = dbg_var {
-                        let dbg_loc = match self.dbg_loc(var.source_info) {
-                            Some(dbg_loc) => dbg_loc,
-                            None => continue,
-                        };
+                        let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
 
                         if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) {
                             let base = Self::spill_operand_to_stack(
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index c654232c10a..f15c469ae57 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -58,9 +58,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     ) {
         let callee_ty = instance.ty(bx.tcx(), ty::ParamEnv::reveal_all());
 
-        let (def_id, substs) = match *callee_ty.kind() {
-            ty::FnDef(def_id, substs) => (def_id, substs),
-            _ => bug!("expected fn item type, found {}", callee_ty),
+        let ty::FnDef(def_id, substs) = *callee_ty.kind() else {
+            bug!("expected fn item type, found {}", callee_ty);
         };
 
         let sig = callee_ty.fn_sig(bx.tcx());
@@ -338,21 +337,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     );
                     return;
                 }
-                let (_width, signed) = match int_type_width_signed(ret_ty, bx.tcx()) {
-                    Some(pair) => pair,
-                    None => {
-                        span_invalid_monomorphization_error(
-                            bx.tcx().sess,
-                            span,
-                            &format!(
-                                "invalid monomorphization of `float_to_int_unchecked` \
-                                      intrinsic:  expected basic integer type, \
-                                      found `{}`",
-                                ret_ty
-                            ),
-                        );
-                        return;
-                    }
+                let Some((_width, signed)) = int_type_width_signed(ret_ty, bx.tcx()) else {
+                    span_invalid_monomorphization_error(
+                        bx.tcx().sess,
+                        span,
+                        &format!(
+                            "invalid monomorphization of `float_to_int_unchecked` \
+                                    intrinsic:  expected basic integer type, \
+                                    found `{}`",
+                            ret_ty
+                        ),
+                    );
+                    return;
                 };
                 if signed {
                     bx.fptosi(args[0].immediate(), llret_ty)
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 4f05d02526e..adb856ef42e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -285,9 +285,8 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 // individual LLVM function arguments.
 
                 let arg_ty = fx.monomorphize(arg_decl.ty);
-                let tupled_arg_tys = match arg_ty.kind() {
-                    ty::Tuple(tys) => tys,
-                    _ => bug!("spread argument isn't a tuple?!"),
+                let ty::Tuple(tupled_arg_tys) = arg_ty.kind() else {
+                    bug!("spread argument isn't a tuple?!");
                 };
 
                 let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty));
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 0c526ff13f2..66be58cf62c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -78,17 +78,15 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
 
         let val = match val {
             ConstValue::Scalar(x) => {
-                let scalar = match layout.abi {
-                    Abi::Scalar(x) => x,
-                    _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
+                let Abi::Scalar(scalar) = layout.abi else {
+                    bug!("from_const: invalid ByVal layout: {:#?}", layout);
                 };
                 let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
                 OperandValue::Immediate(llval)
             }
             ConstValue::Slice { data, start, end } => {
-                let a_scalar = match layout.abi {
-                    Abi::ScalarPair(a, _) => a,
-                    _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout),
+                let Abi::ScalarPair(a_scalar, _) = layout.abi else {
+                    bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
                 };
                 let a = Scalar::from_pointer(
                     Pointer::new(bx.tcx().create_memory_alloc(data), Size::from_bytes(start)),
@@ -307,9 +305,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
                 bx.store_with_flags(val, dest.llval, dest.align, flags);
             }
             OperandValue::Pair(a, b) => {
-                let (a_scalar, b_scalar) = match dest.layout.abi {
-                    Abi::ScalarPair(a, b) => (a, b),
-                    _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout),
+                let Abi::ScalarPair(a_scalar, b_scalar) = dest.layout.abi else {
+                    bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout);
                 };
                 let ty = bx.backend_type(dest.layout);
                 let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index ba1d5f45bbb..724f92243d0 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -147,6 +147,10 @@ pub(crate) fn try_destructure_const<'tcx>(
     // We go to `usize` as we cannot allocate anything bigger anyway.
     let (field_count, variant, down) = match val.ty().kind() {
         ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
+        // Checks if we have any variants, to avoid downcasting to a non-existing variant (when
+        // there are no variants `read_discriminant` successfully returns a non-existing variant
+        // index).
+        ty::Adt(def, _) if def.variants.is_empty() => throw_ub!(Unreachable),
         ty::Adt(def, _) => {
             let variant = ecx.read_discriminant(&op)?.1;
             let down = ecx.operand_downcast(&op, variant)?;
diff --git a/compiler/rustc_data_structures/src/binary_search_util/mod.rs b/compiler/rustc_data_structures/src/binary_search_util/mod.rs
index bf09b2f8eef..d40172a2e2f 100644
--- a/compiler/rustc_data_structures/src/binary_search_util/mod.rs
+++ b/compiler/rustc_data_structures/src/binary_search_util/mod.rs
@@ -10,9 +10,8 @@ pub fn binary_search_slice<'d, E, K>(data: &'d [E], key_fn: impl Fn(&E) -> K, ke
 where
     K: Ord,
 {
-    let mid = match data.binary_search_by_key(key, &key_fn) {
-        Ok(mid) => mid,
-        Err(_) => return &[],
+    let Ok(mid) = data.binary_search_by_key(key, &key_fn) else {
+        return &[];
     };
     let size = data.len();
 
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 80f83140f4b..ea02a73c422 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -14,6 +14,7 @@
 #![feature(control_flow_enum)]
 #![feature(core_intrinsics)]
 #![feature(extend_one)]
+#![feature(let_else)]
 #![feature(hash_raw_entry)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
diff --git a/compiler/rustc_data_structures/src/transitive_relation.rs b/compiler/rustc_data_structures/src/transitive_relation.rs
index ccf8bd69ebd..0af571610fe 100644
--- a/compiler/rustc_data_structures/src/transitive_relation.rs
+++ b/compiler/rustc_data_structures/src/transitive_relation.rs
@@ -190,11 +190,8 @@ impl<T: Eq + Hash> TransitiveRelation<T> {
     ///
     /// Note that this set can, in principle, have any size.
     pub fn minimal_upper_bounds(&self, a: &T, b: &T) -> Vec<&T> {
-        let (mut a, mut b) = match (self.index(a), self.index(b)) {
-            (Some(a), Some(b)) => (a, b),
-            (None, _) | (_, None) => {
-                return vec![];
-            }
+        let (Some(mut a), Some(mut b)) = (self.index(a), self.index(b)) else {
+            return vec![];
         };
 
         // in some cases, there are some arbitrary choices to be made;
@@ -294,9 +291,8 @@ impl<T: Eq + Hash> TransitiveRelation<T> {
     /// then `parents(a)` returns `[b, c]`. The `postdom_parent` function
     /// would further reduce this to just `f`.
     pub fn parents(&self, a: &T) -> Vec<&T> {
-        let a = match self.index(a) {
-            Some(a) => a,
-            None => return vec![],
+        let Some(a) = self.index(a) else {
+            return vec![];
         };
 
         // Steal the algorithm for `minimal_upper_bounds` above, but
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 85826cfbf01..563ec8b0e3a 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -6,6 +6,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(nll)]
+#![feature(let_else)]
 #![feature(once_cell)]
 #![recursion_limit = "256"]
 #![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]
@@ -203,10 +204,7 @@ fn run_compiler(
     let args = args::arg_expand_all(at_args);
 
     let diagnostic_output = emitter.map_or(DiagnosticOutput::Default, DiagnosticOutput::Raw);
-    let matches = match handle_options(&args) {
-        Some(matches) => matches,
-        None => return Ok(()),
-    };
+    let Some(matches) = handle_options(&args) else { return Ok(()) };
 
     let sopts = config::build_session_options(&matches);
 
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index f90f4d46a9a..bfed9211cec 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -1138,9 +1138,8 @@ impl EmitterWriter {
     }
 
     fn get_multispan_max_line_num(&mut self, msp: &MultiSpan) -> usize {
-        let sm = match self.sm {
-            Some(ref sm) => sm,
-            None => return 0,
+        let Some(ref sm) = self.sm else {
+            return 0;
         };
 
         let mut max = 0;
@@ -1590,9 +1589,8 @@ impl EmitterWriter {
         level: &Level,
         max_line_num_len: usize,
     ) -> io::Result<()> {
-        let sm = match self.sm {
-            Some(ref sm) => sm,
-            None => return Ok(()),
+        let Some(ref sm) = self.sm else {
+            return Ok(());
         };
 
         // Render the replacements for each suggestion
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 258320aeb63..2bdf3b39126 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1299,20 +1299,16 @@ pub fn parse_macro_name_and_helper_attrs(
     // Once we've located the `#[proc_macro_derive]` attribute, verify
     // that it's of the form `#[proc_macro_derive(Foo)]` or
     // `#[proc_macro_derive(Foo, attributes(A, ..))]`
-    let list = match attr.meta_item_list() {
-        Some(list) => list,
-        None => return None,
+    let Some(list) = attr.meta_item_list() else {
+        return None;
     };
     if list.len() != 1 && list.len() != 2 {
         diag.span_err(attr.span, "attribute must have either one or two arguments");
         return None;
     }
-    let trait_attr = match list[0].meta_item() {
-        Some(meta_item) => meta_item,
-        _ => {
-            diag.span_err(list[0].span(), "not a meta item");
-            return None;
-        }
+    let Some(trait_attr) = list[0].meta_item() else {
+        diag.span_err(list[0].span(), "not a meta item");
+        return None;
     };
     let trait_ident = match trait_attr.ident() {
         Some(trait_ident) if trait_attr.is_word() => trait_ident,
@@ -1341,12 +1337,9 @@ pub fn parse_macro_name_and_helper_attrs(
             })
             .iter()
             .filter_map(|attr| {
-                let attr = match attr.meta_item() {
-                    Some(meta_item) => meta_item,
-                    _ => {
-                        diag.span_err(attr.span(), "not a meta item");
-                        return None;
-                    }
+                let Some(attr) = attr.meta_item() else {
+                    diag.span_err(attr.span(), "not a meta item");
+                    return None;
                 };
 
                 let ident = match attr.ident() {
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 5fa7ffd554e..c0d7bc359bf 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -79,9 +79,8 @@ fn get_features(
             continue;
         }
 
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
+        let Some(list) = attr.meta_item_list() else {
+            continue;
         };
 
         for mi in list {
@@ -112,9 +111,8 @@ fn get_features(
             continue;
         }
 
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
+        let Some(list) = attr.meta_item_list() else {
+            continue;
         };
 
         let bad_input = |span| {
@@ -340,10 +338,9 @@ impl<'a> StripUnconfigured<'a> {
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
     crate fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec<Attribute> {
-        let (cfg_predicate, expanded_attrs) =
-            match rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) {
-                None => return vec![],
-                Some(r) => r,
+        let Some((cfg_predicate, expanded_attrs)) =
+            rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) else {
+                return vec![];
             };
 
         // Lint on zero attributes in source.
@@ -389,18 +386,16 @@ impl<'a> StripUnconfigured<'a> {
         // Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token
         // for `attr` when we expand it to `#[attr]`
         let mut orig_trees = orig_tokens.trees();
-        let pound_token = match orig_trees.next().unwrap() {
-            TokenTree::Token(token @ Token { kind: TokenKind::Pound, .. }) => token,
-            _ => panic!("Bad tokens for attribute {:?}", attr),
+        let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }) = orig_trees.next().unwrap() else {
+            panic!("Bad tokens for attribute {:?}", attr);
         };
         let pound_span = pound_token.span;
 
         let mut trees = vec![(AttrAnnotatedTokenTree::Token(pound_token), Spacing::Alone)];
         if attr.style == AttrStyle::Inner {
             // For inner attributes, we do the same thing for the `!` in `#![some_attr]`
-            let bang_token = match orig_trees.next().unwrap() {
-                TokenTree::Token(token @ Token { kind: TokenKind::Not, .. }) => token,
-                _ => panic!("Bad tokens for attribute {:?}", attr),
+            let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }) = orig_trees.next().unwrap() else {
+                panic!("Bad tokens for attribute {:?}", attr);
             };
             trees.push((AttrAnnotatedTokenTree::Token(bang_token), Spacing::Alone));
         }
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 9a4daa6d750..bdc9c064a6f 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -641,9 +641,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         ExpandResult::Ready(match invoc.kind {
             InvocationKind::Bang { mac, .. } => match ext {
                 SyntaxExtensionKind::Bang(expander) => {
-                    let tok_result = match expander.expand(self.cx, span, mac.args.inner_tokens()) {
-                        Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
-                        Ok(ts) => ts,
+                    let Ok(tok_result) = expander.expand(self.cx, span, mac.args.inner_tokens()) else {
+                        return ExpandResult::Ready(fragment_kind.dummy(span));
                     };
                     self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
                 }
@@ -698,9 +697,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         self.cx.span_err(span, "key-value macro attributes are not supported");
                     }
                     let inner_tokens = attr_item.args.inner_tokens();
-                    let tok_result = match expander.expand(self.cx, span, inner_tokens, tokens) {
-                        Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
-                        Ok(ts) => ts,
+                    let Ok(tok_result) = expander.expand(self.cx, span, inner_tokens, tokens) else {
+                        return ExpandResult::Ready(fragment_kind.dummy(span));
                     };
                     self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
                 }
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index e9532dbe2ce..aa54bdbd3a7 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -170,23 +170,20 @@ fn mod_file_path_from_attr(
 ) -> Option<PathBuf> {
     // Extract path string from first `#[path = "path_string"]` attribute.
     let first_path = attrs.iter().find(|at| at.has_name(sym::path))?;
-    let path_sym = match first_path.value_str() {
-        Some(s) => s,
-        None => {
-            // This check is here mainly to catch attempting to use a macro,
-            // such as #[path = concat!(...)]. This isn't currently supported
-            // because otherwise the InvocationCollector would need to defer
-            // loading a module until the #[path] attribute was expanded, and
-            // it doesn't support that (and would likely add a bit of
-            // complexity). Usually bad forms are checked in AstValidator (via
-            // `check_builtin_attribute`), but by the time that runs the macro
-            // is expanded, and it doesn't give an error.
-            validate_attr::emit_fatal_malformed_builtin_attribute(
-                &sess.parse_sess,
-                first_path,
-                sym::path,
-            );
-        }
+    let Some(path_sym) = first_path.value_str() else {
+        // This check is here mainly to catch attempting to use a macro,
+        // such as #[path = concat!(...)]. This isn't currently supported
+        // because otherwise the InvocationCollector would need to defer
+        // loading a module until the #[path] attribute was expanded, and
+        // it doesn't support that (and would likely add a bit of
+        // complexity). Usually bad forms are checked in AstValidator (via
+        // `check_builtin_attribute`), but by the time that runs the macro
+        // is expanded, and it doesn't give an error.
+        validate_attr::emit_fatal_malformed_builtin_attribute(
+            &sess.parse_sess,
+            first_path,
+            sym::path,
+        );
     };
 
     let path_str = path_sym.as_str();
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index efbe0b65715..99a945b1c91 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -596,9 +596,8 @@ impl server::Literal for Rustc<'_, '_> {
         let minus_present = parser.eat(&token::BinOp(token::Minus));
 
         let lit_span = parser.token.span.data();
-        let mut lit = match parser.token.kind {
-            token::Literal(lit) => lit,
-            _ => return Err(()),
+        let token::Literal(mut lit) = parser.token.kind else {
+            return Err(());
         };
 
         // Check no comment or whitespace surrounding the (possibly negative)
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 0961d0131d0..255e661652d 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -635,9 +635,8 @@ pub struct WhereBoundPredicate<'hir> {
 impl<'hir> WhereBoundPredicate<'hir> {
     /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
     pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
-        let path = match self.bounded_ty.kind {
-            TyKind::Path(QPath::Resolved(None, path)) => path,
-            _ => return false,
+        let TyKind::Path(QPath::Resolved(None, path)) = self.bounded_ty.kind else {
+            return false;
         };
         match path.res {
             Res::Def(DefKind::TyParam, def_id)
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index f1d62d03cbc..ba3eeb91fe9 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -5,6 +5,7 @@
 #![feature(associated_type_defaults)]
 #![feature(const_btree_new)]
 #![feature(crate_visibility_modifier)]
+#![feature(let_else)]
 #![feature(once_cell)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 94c149dd23e..8a4ed02f6ae 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -368,9 +368,8 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
     fn check_item(&mut self, item_id: LocalDefId, item_span: Span) {
         let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id());
         for attr in self.tcx.get_attrs(item_id.to_def_id()).iter() {
-            let assertion = match self.assertion_maybe(item_id, attr) {
-                Some(a) => a,
-                None => continue,
+            let Some(assertion) = self.assertion_maybe(item_id, attr) else {
+                continue;
             };
             self.checked_attrs.insert(attr.id);
             for label in assertion.clean {
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index a49a1554d5b..a6da4b0bab6 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -421,9 +421,8 @@ fn copy_files(sess: &Session, target_dir: &Path, source_dir: &Path) -> Result<bo
         return Err(());
     };
 
-    let source_dir_iterator = match source_dir.read_dir() {
-        Ok(it) => it,
-        Err(_) => return Err(()),
+    let Ok(source_dir_iterator) = source_dir.read_dir() else {
+        return Err(());
     };
 
     let mut files_linked = 0;
@@ -700,12 +699,9 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
     let mut lock_files = FxHashSet::default();
 
     for dir_entry in crate_directory.read_dir()? {
-        let dir_entry = match dir_entry {
-            Ok(dir_entry) => dir_entry,
-            _ => {
-                // Ignore any errors
-                continue;
-            }
+        let Ok(dir_entry) = dir_entry else {
+            // Ignore any errors
+            continue;
         };
 
         let entry_name = dir_entry.file_name();
@@ -740,16 +736,13 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
     // be some kind of leftover
     for (lock_file_name, directory_name) in &lock_file_to_session_dir {
         if directory_name.is_none() {
-            let timestamp = match extract_timestamp_from_session_dir(lock_file_name) {
-                Ok(timestamp) => timestamp,
-                Err(()) => {
-                    debug!(
-                        "found lock-file with malformed timestamp: {}",
-                        crate_directory.join(&lock_file_name).display()
-                    );
-                    // Ignore it
-                    continue;
-                }
+            let Ok(timestamp) = extract_timestamp_from_session_dir(lock_file_name) else {
+                debug!(
+                    "found lock-file with malformed timestamp: {}",
+                    crate_directory.join(&lock_file_name).display()
+                );
+                // Ignore it
+                continue;
             };
 
             let lock_file_path = crate_directory.join(&**lock_file_name);
@@ -798,16 +791,13 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
     for (lock_file_name, directory_name) in &lock_file_to_session_dir {
         debug!("garbage_collect_session_directories() - inspecting: {}", directory_name);
 
-        let timestamp = match extract_timestamp_from_session_dir(directory_name) {
-            Ok(timestamp) => timestamp,
-            Err(()) => {
-                debug!(
-                    "found session-dir with malformed timestamp: {}",
-                    crate_directory.join(directory_name).display()
-                );
-                // Ignore it
-                continue;
-            }
+        let Ok(timestamp) = extract_timestamp_from_session_dir(directory_name) else {
+            debug!(
+                "found session-dir with malformed timestamp: {}",
+                crate_directory.join(directory_name).display()
+            );
+            // Ignore it
+            continue;
         };
 
         if is_finalized(directory_name) {
diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs
index 6da95053b11..ed504938e8a 100644
--- a/compiler/rustc_index/src/interval.rs
+++ b/compiler/rustc_index/src/interval.rs
@@ -136,12 +136,9 @@ impl<I: Idx> IntervalSet<I> {
 
     pub fn contains(&self, needle: I) -> bool {
         let needle = needle.index() as u32;
-        let last = match self.map.partition_point(|r| r.0 <= needle).checked_sub(1) {
-            Some(idx) => idx,
-            None => {
-                // All ranges in the map start after the new range's end
-                return false;
-            }
+        let Some(last) = self.map.partition_point(|r| r.0 <= needle).checked_sub(1) else {
+            // All ranges in the map start after the new range's end
+            return false;
         };
         let (_, prev_end) = &self.map[last];
         needle <= *prev_end
@@ -170,12 +167,9 @@ impl<I: Idx> IntervalSet<I> {
         if start > end {
             return None;
         }
-        let last = match self.map.partition_point(|r| r.0 <= end).checked_sub(1) {
-            Some(idx) => idx,
-            None => {
-                // All ranges in the map start after the new range's end
-                return None;
-            }
+        let Some(last) = self.map.partition_point(|r| r.0 <= end).checked_sub(1) else {
+            // All ranges in the map start after the new range's end
+            return None;
         };
         let (_, prev_end) = &self.map[last];
         if start <= *prev_end { Some(I::new(std::cmp::min(*prev_end, end) as usize)) } else { None }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
index ef4c9c24f3e..2bc2f78261d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
@@ -18,16 +18,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         let error = self.error.as_ref()?;
         debug!("try_report_mismatched_static_lifetime {:?}", error);
 
-        let (origin, sub, sup) = match error.clone() {
-            RegionResolutionError::ConcreteFailure(origin, sub, sup) => (origin, sub, sup),
-            _ => return None,
+        let RegionResolutionError::ConcreteFailure(origin, sub, sup) = error.clone() else {
+            return None;
         };
         if !sub.is_static() {
             return None;
         }
-        let cause = match origin {
-            SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) => cause,
-            _ => return None,
+        let SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) = origin else {
+            return None;
         };
         // If we added a "points at argument expression" obligation, we remove it here, we care
         // about the original obligation only.
@@ -35,13 +33,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => &*parent_code,
             _ => cause.code(),
         };
-        let (parent, impl_def_id) = match code {
-            ObligationCauseCode::MatchImpl(parent, impl_def_id) => (parent, impl_def_id),
-            _ => return None,
+        let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else {
+            return None;
         };
-        let binding_span = match *parent.code() {
-            ObligationCauseCode::BindingObligation(_def_id, binding_span) => binding_span,
-            _ => return None,
+        let ObligationCauseCode::BindingObligation(_def_id, binding_span) = *parent.code() else {
+            return None;
         };
         let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type");
         // FIXME: we should point at the lifetime
@@ -55,12 +51,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             // be as helpful as possible with implicit lifetimes.
 
             // First, let's get the hir self type of the impl
-            let impl_self_ty = match impl_node {
-                hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Impl(hir::Impl { self_ty, .. }),
-                    ..
-                }) => self_ty,
-                _ => bug!("Node not an impl."),
+            let hir::Node::Item(hir::Item {
+                kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, .. }),
+                ..
+            }) = impl_node else {
+                bug!("Node not an impl.");
             };
 
             // Next, let's figure out the set of trait objects with implict static bounds
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 625fd864218..8601180842c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -490,14 +490,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         let tcx = self.tcx();
 
         // Find the method being called.
-        let instance = match ty::Instance::resolve(
+        let Ok(Some(instance)) = ty::Instance::resolve(
             tcx,
             ctxt.param_env,
             ctxt.assoc_item.def_id,
             self.infcx.resolve_vars_if_possible(ctxt.substs),
-        ) {
-            Ok(Some(instance)) => instance,
-            _ => return false,
+        ) else {
+            return false;
         };
 
         let mut v = TraitObjectVisitor(FxHashSet::default());
@@ -505,11 +504,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
 
         // Get the `Ident` of the method being called and the corresponding `impl` (to point at
         // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
-        let (ident, self_ty) =
-            match self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0) {
-                Some((ident, self_ty)) => (ident, self_ty),
-                None => return false,
-            };
+        let Some((ident, self_ty)) = self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0) else {
+            return false;
+        };
 
         // Find the trait object types in the argument, so we point at *only* the trait object.
         self.suggest_constrain_dyn_trait_in_impl(err, &v.0, ident, self_ty)
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 4e50585ff52..c7b4a96fb78 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -263,9 +263,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
 
         while let Some(vid) = changes.pop() {
             constraints[vid].retain(|&(a_vid, b_vid)| {
-                let a_region = match *var_values.value(a_vid) {
-                    VarValue::ErrorValue => return false,
-                    VarValue::Value(a_region) => a_region,
+                let VarValue::Value(a_region) = *var_values.value(a_vid) else {
+                    return false;
                 };
                 let b_data = var_values.value_mut(b_vid);
                 if self.expand_node(a_region, b_vid, b_data) {
@@ -485,9 +484,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                     let a_data = var_data.value_mut(a_vid);
                     debug!("contraction: {:?} == {:?}, {:?}", a_vid, a_data, b_region);
 
-                    let a_region = match *a_data {
-                        VarValue::ErrorValue => continue,
-                        VarValue::Value(a_region) => a_region,
+                    let VarValue::Value(a_region) = *a_data else {
+                        continue;
                     };
 
                     // Do not report these errors immediately:
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 89390ee1d6c..4af69f7cd2e 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -259,10 +259,7 @@ impl<'tcx> Queries<'tcx> {
     /// to write UI tests that actually test that compilation succeeds without reporting
     /// an error.
     fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
-        let def_id = match tcx.entry_fn(()) {
-            Some((def_id, _)) => def_id,
-            _ => return,
-        };
+        let Some((def_id, _)) = tcx.entry_fn(()) else { return };
 
         let attrs = &*tcx.get_attrs(def_id);
         let attrs = attrs.iter().filter(|attr| attr.has_name(sym::rustc_error));
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 46964f52685..83b54810db2 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -430,10 +430,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
     ];
     for entry in d.filter_map(|e| e.ok()) {
         let path = entry.path();
-        let filename = match path.file_name().and_then(|s| s.to_str()) {
-            Some(s) => s,
-            None => continue,
-        };
+        let Some(filename) = path.file_name().and_then(|s| s.to_str()) else { continue };
         if !(filename.starts_with(DLL_PREFIX) && filename.ends_with(DLL_SUFFIX)) {
             continue;
         }
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index d2d853efda2..e9996a7ef14 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -278,9 +278,8 @@ impl LintStore {
     /// This lint has been renamed; warn about using the new name and apply the lint.
     #[track_caller]
     pub fn register_renamed(&mut self, old_name: &str, new_name: &str) {
-        let target = match self.by_name.get(new_name) {
-            Some(&Id(lint_id)) => lint_id,
-            _ => bug!("invalid lint renaming of {} to {}", old_name, new_name),
+        let Some(&Id(target)) = self.by_name.get(new_name) else {
+            bug!("invalid lint renaming of {} to {}", old_name, new_name);
         };
         self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
     }
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 944a0996427..5078c240ec7 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -23,10 +23,7 @@ declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
 
 impl LateLintPass<'_> for DefaultHashTypes {
     fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
-        let def_id = match path.res {
-            Res::Def(rustc_hir::def::DefKind::Struct, id) => id,
-            _ => return,
-        };
+        let Res::Def(rustc_hir::def::DefKind::Struct, def_id) = path.res else { return };
         if matches!(cx.tcx.hir().get(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
             // don't lint imports, only actual usages
             return;
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 8afbd462c14..35c7d885e1d 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -95,9 +95,9 @@ impl<'s> LintLevelsBuilder<'s> {
             let orig_level = level;
             let lint_flag_val = Symbol::intern(lint_name);
 
-            let ids = match store.find_lints(&lint_name) {
-                Ok(ids) => ids,
-                Err(_) => continue, // errors handled in check_lint_name_cmdline above
+            let Ok(ids) = store.find_lints(&lint_name) else {
+                // errors handled in check_lint_name_cmdline above
+                continue
             };
             for id in ids {
                 // ForceWarn and Forbid cannot be overriden
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index 2dd6dbd67a8..264a80339cc 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -301,10 +301,7 @@ impl EarlyLintPass for NonAsciiIdents {
                     BTreeMap::new();
 
                 'outerloop: for (augment_script_set, usage) in script_states {
-                    let (mut ch_list, sp) = match usage {
-                        ScriptSetUsage::Verified => continue,
-                        ScriptSetUsage::Suspicious(ch_list, sp) => (ch_list, sp),
-                    };
+                    let ScriptSetUsage::Suspicious(mut ch_list, sp) = usage else { continue };
 
                     if augment_script_set.is_all() {
                         continue;
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index fc88e8cd912..5cd3791583f 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1331,14 +1331,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
         if let hir::ItemKind::Enum(ref enum_definition, _) = it.kind {
             let t = cx.tcx.type_of(it.def_id);
             let ty = cx.tcx.erase_regions(t);
-            let layout = match cx.layout_of(ty) {
-                Ok(layout) => layout,
-                Err(
-                    ty::layout::LayoutError::Unknown(_)
-                    | ty::layout::LayoutError::SizeOverflow(_)
-                    | ty::layout::LayoutError::NormalizationFailure(_, _),
-                ) => return,
-            };
+            let Ok(layout) = cx.layout_of(ty) else { return };
             let Variants::Multiple {
                     tag_encoding: TagEncoding::Direct, tag, ref variants, ..
                 } = &layout.variants else {
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 36a1798cd6a..7343f1465f6 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -475,9 +475,8 @@ impl<'a> CrateLoader<'a> {
         locator.triple = TargetTriple::from_triple(config::host_triple());
         locator.filesearch = self.sess.host_filesearch(path_kind);
 
-        let host_result = match self.load(locator)? {
-            Some(host_result) => host_result,
-            None => return Ok(None),
+        let Some(host_result) = self.load(locator)? else {
+            return Ok(None);
         };
 
         Ok(Some(if self.sess.opts.debugging_opts.dual_proc_macros {
@@ -574,9 +573,8 @@ impl<'a> CrateLoader<'a> {
     }
 
     fn load(&self, locator: &mut CrateLocator<'_>) -> Result<Option<LoadResult>, CrateError> {
-        let library = match locator.maybe_load_library_crate()? {
-            Some(library) => library,
-            None => return Ok(None),
+        let Some(library) = locator.maybe_load_library_crate()? else {
+            return Ok(None);
         };
 
         // In the case that we're loading a crate, but not matching
diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs
index c70a6914520..c4ee1e19128 100644
--- a/compiler/rustc_metadata/src/foreign_modules.rs
+++ b/compiler/rustc_metadata/src/foreign_modules.rs
@@ -15,9 +15,8 @@ struct Collector {
 
 impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
     fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
-        let items = match it.kind {
-            hir::ItemKind::ForeignMod { items, .. } => items,
-            _ => return,
+        let hir::ItemKind::ForeignMod { items, .. } = it.kind else {
+            return;
         };
 
         let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect();
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 550b22a2a3c..2204b44e3a1 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -690,14 +690,11 @@ impl<'a> CrateLocator<'a> {
                     loc.original().clone(),
                 ));
             }
-            let file = match loc.original().file_name().and_then(|s| s.to_str()) {
-                Some(file) => file,
-                None => {
-                    return Err(CrateError::ExternLocationNotFile(
-                        self.crate_name,
-                        loc.original().clone(),
-                    ));
-                }
+            let Some(file) = loc.original().file_name().and_then(|s| s.to_str()) else {
+                return Err(CrateError::ExternLocationNotFile(
+                    self.crate_name,
+                    loc.original().clone(),
+                ));
             };
 
             if file.starts_with("lib") && (file.ends_with(".rlib") || file.ends_with(".rmeta"))
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 88292a44224..0f10c269a04 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -33,9 +33,8 @@ struct Collector<'tcx> {
 
 impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
     fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
-        let (abi, foreign_mod_items) = match it.kind {
-            hir::ItemKind::ForeignMod { abi, items } => (abi, items),
-            _ => return,
+        let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else {
+            return;
         };
 
         if abi == Abi::Rust || abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
@@ -45,9 +44,8 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
         // Process all of the #[link(..)]-style arguments
         let sess = &self.tcx.sess;
         for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) {
-            let items = match m.meta_item_list() {
-                Some(item) => item,
-                None => continue,
+            let Some(items) = m.meta_item_list() else {
+                continue;
             };
             let mut lib = NativeLib {
                 name: None,
@@ -63,9 +61,8 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
             for item in items.iter() {
                 if item.has_name(sym::kind) {
                     kind_specified = true;
-                    let kind = match item.value_str() {
-                        Some(name) => name,
-                        None => continue, // skip like historical compilers
+                    let Some(kind) = item.value_str() else {
+                        continue; // skip like historical compilers
                     };
                     lib.kind = match kind.as_str() {
                         "static" => NativeLibKind::Static { bundle: None, whole_archive: None },
@@ -101,9 +98,8 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> {
                 } else if item.has_name(sym::name) {
                     lib.name = item.value_str();
                 } else if item.has_name(sym::cfg) {
-                    let cfg = match item.meta_item_list() {
-                        Some(list) => list,
-                        None => continue, // skip like historical compilers
+                    let Some(cfg) = item.meta_item_list() else {
+                        continue; // skip like historical compilers
                     };
                     if cfg.is_empty() {
                         sess.span_err(item.span(), "`cfg()` must have an argument");
@@ -262,11 +258,8 @@ impl Collector<'_> {
         }
         // this just unwraps lib.name; we already established that it isn't empty above.
         if let (NativeLibKind::RawDylib, Some(lib_name)) = (lib.kind, lib.name) {
-            let span = match span {
-                Some(s) => s,
-                None => {
-                    bug!("raw-dylib libraries are not supported on the command line");
-                }
+            let Some(span) = span else {
+                bug!("raw-dylib libraries are not supported on the command line");
             };
 
             if !self.tcx.sess.target.options.is_like_windows {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 7708b5193f4..ce61fd20a7b 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -249,9 +249,8 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
                 .iter()
                 .filter(|lib| native_libs::relevant_lib(&tcx.sess, lib))
                 .find(|lib| {
-                    let fm_id = match lib.foreign_module {
-                        Some(id) => id,
-                        None => return false,
+                    let Some(fm_id) = lib.foreign_module else {
+                        return false;
                     };
                     let map = tcx.foreign_modules(id.krate);
                     map.get(&fm_id)
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 75dd223d014..6124d140702 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -173,9 +173,8 @@ impl Scope {
     /// returned span may not correspond to the span of any `NodeId` in
     /// the AST.
     pub fn span(&self, tcx: TyCtxt<'_>, scope_tree: &ScopeTree) -> Span {
-        let hir_id = match self.hir_id(scope_tree) {
-            Some(hir_id) => hir_id,
-            None => return DUMMY_SP,
+        let Some(hir_id) = self.hir_id(scope_tree) else {
+            return DUMMY_SP;
         };
         let span = tcx.hir().span(hir_id);
         if let ScopeData::Remainder(first_statement_index) = self.data {
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index cc31d8c2c18..aa8730bf9cd 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -456,6 +456,11 @@ impl<'tcx, Tag: Provenance> Scalar<Tag> {
         // Going through `u64` to check size and truncation.
         Ok(Double::from_bits(self.to_u64()?.into()))
     }
+
+    // FIXME: Replace current `impl Display for Scalar` with `impl LowerHex`.
+    pub fn rustdoc_display(&self) -> String {
+        if let Scalar::Int(int) = self { int.to_string() } else { self.to_string() }
+    }
 }
 
 #[derive(Clone, Copy, Eq, PartialEq, TyEncodable, TyDecodable, HashStable, Hash)]
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 7e5f8018dfc..5642d01de5d 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1841,6 +1841,15 @@ static_assert_size!(PlaceElem<'_>, 24);
 pub type ProjectionKind = ProjectionElem<(), ()>;
 
 rustc_index::newtype_index! {
+    /// A [newtype'd][wrapper] index type in the MIR [control-flow graph][CFG]
+    ///
+    /// A field (e.g., `f` in `_1.f`) is one variant of [`ProjectionElem`]. Conceptually,
+    /// rustc can identify that a field projection refers to either two different regions of memory
+    /// or the same one between the base and the 'projection element'.
+    /// Read more about projections in the [rustc-dev-guide][mir-datatypes]
+    /// [wrapper]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#newtype
+    /// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
+    /// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types
     pub struct Field {
         derive [HashStable]
         DEBUG_FORMAT = "field[{}]"
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 784babffeff..7894c7fec44 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -89,9 +89,8 @@ pub fn dump_mir<'tcx, F>(
 }
 
 pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) -> bool {
-    let filters = match tcx.sess.opts.debugging_opts.dump_mir {
-        None => return false,
-        Some(ref filters) => filters,
+    let Some(ref filters) = tcx.sess.opts.debugging_opts.dump_mir else {
+        return false;
     };
     let node_path = ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 below
@@ -586,9 +585,8 @@ fn write_scope_tree(
         )?;
     }
 
-    let children = match scope_tree.get(&parent) {
-        Some(children) => children,
-        None => return Ok(()),
+    let Some(children) = scope_tree.get(&parent) else {
+        return Ok(());
     };
 
     for &child in children {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 43cfe6f3b8a..be86f1e9274 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1,3 +1,9 @@
+//! Defines the various compiler queries.
+//!
+//! For more information on the query system, see
+//! ["Queries: demand-driven compilation"](https://rustc-dev-guide.rust-lang.org/query.html).
+//! This chapter includes instructions for adding new queries.
+
 // Each of these queries corresponds to a function pointer field in the
 // `Providers` struct for requesting a value of that type, and a method
 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index ca1db2fd551..72623ba54ee 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -384,3 +384,10 @@ impl fmt::UpperHex for ScalarInt {
         write!(f, "{:01$X}", { self.data }, self.size as usize * 2)
     }
 }
+
+impl fmt::Display for ScalarInt {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.check_data();
+        write!(f, "{}", { self.data })
+    }
+}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 41145d25017..bb8566ea4df 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1123,9 +1123,8 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) {
         let attrs = self.get_attrs(def_id);
         let get = |name| {
-            let attr = match attrs.iter().find(|a| a.has_name(name)) {
-                Some(attr) => attr,
-                None => return Bound::Unbounded,
+            let Some(attr) = attrs.iter().find(|a| a.has_name(name)) else {
+                return Bound::Unbounded;
             };
             debug!("layout_scalar_valid_range: attr={:?}", attr);
             if let Some(
@@ -1513,9 +1512,8 @@ impl<'tcx> TyCtxt<'tcx> {
         scope_def_id: LocalDefId,
     ) -> Vec<&'tcx hir::Ty<'tcx>> {
         let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
-        let hir_output = match self.hir().fn_decl_by_hir_id(hir_id) {
-            Some(hir::FnDecl { output: hir::FnRetTy::Return(ty), .. }) => ty,
-            _ => return vec![],
+        let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) else {
+            return vec![];
         };
 
         let mut v = TraitObjectVisitor(vec![], self.hir());
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 2ccfeba2b66..5ceabf99eda 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -861,11 +861,10 @@ fn foo(&self) -> Self::T { String::new() }
         body_owner_def_id: DefId,
         found: Ty<'tcx>,
     ) -> bool {
-        let hir_id =
-            match body_owner_def_id.as_local().map(|id| self.hir().local_def_id_to_hir_id(id)) {
-                Some(hir_id) => hir_id,
-                None => return false,
-            };
+        let Some(hir_id) = body_owner_def_id.as_local() else {
+            return false;
+        };
+        let hir_id = self.hir().local_def_id_to_hir_id(hir_id);
         // When `body_owner` is an `impl` or `trait` item, look in its associated types for
         // `expected` and point at it.
         let parent_id = self.hir().get_parent_item(hir_id);
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 6d4178c3e75..4996a13bd8c 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1319,9 +1319,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     // Try to use a ScalarPair for all tagged enums.
                     let mut common_prim = None;
                     for (field_layouts, layout_variant) in iter::zip(&variants, &layout_variants) {
-                        let offsets = match layout_variant.fields {
-                            FieldsShape::Arbitrary { ref offsets, .. } => offsets,
-                            _ => bug!(),
+                        let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
+                            bug!();
                         };
                         let mut fields =
                             iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst());
@@ -1571,9 +1570,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         let tcx = self.tcx;
         let subst_field = |ty: Ty<'tcx>| ty.subst(tcx, substs);
 
-        let info = match tcx.generator_layout(def_id) {
-            None => return Err(LayoutError::Unknown(ty)),
-            Some(info) => info,
+        let Some(info) = tcx.generator_layout(def_id) else {
+            return Err(LayoutError::Unknown(ty));
         };
         let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info);
 
@@ -1676,9 +1674,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 )?;
                 variant.variants = Variants::Single { index };
 
-                let (offsets, memory_index) = match variant.fields {
-                    FieldsShape::Arbitrary { offsets, memory_index } => (offsets, memory_index),
-                    _ => bug!(),
+                let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else {
+                    bug!();
                 };
 
                 // Now, stitch the promoted and variant-only fields back together in
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index bf7370c9e0e..fbf30b58818 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -415,9 +415,8 @@ pub trait PrettyPrinter<'tcx>:
             cur_def_key = self.tcx().def_key(parent);
         }
 
-        let visible_parent = match visible_parent_map.get(&def_id).cloned() {
-            Some(parent) => parent,
-            None => return Ok((self, false)),
+        let Some(visible_parent) = visible_parent_map.get(&def_id).cloned() else {
+            return Ok((self, false));
         };
 
         let actual_parent = self.tcx().parent(def_id);
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index ce848773b10..da9c4b930df 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -126,11 +126,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         candidate: &Candidate<'pat, 'tcx>,
         variants: &mut BitSet<VariantIdx>,
     ) -> bool {
-        let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
-            Some(match_pair) => match_pair,
-            _ => {
-                return false;
-            }
+        let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
+            return false;
         };
 
         match *match_pair.pattern.kind {
@@ -421,9 +418,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
         }
 
-        let deref_ty = match *ty.kind() {
-            ty::Ref(_, deref_ty, _) => deref_ty,
-            _ => bug!("non_scalar_compare called on non-reference type: {}", ty),
+        let ty::Ref(_, deref_ty, _) = *ty.kind() else {
+            bug!("non_scalar_compare called on non-reference type: {}", ty);
         };
 
         let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, None);
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index fb403615e57..f2f85043df2 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -266,9 +266,8 @@ fn liberated_closure_env_ty(
 ) -> Ty<'_> {
     let closure_ty = tcx.typeck_body(body_id).node_type(closure_expr_id);
 
-    let (closure_def_id, closure_substs) = match *closure_ty.kind() {
-        ty::Closure(closure_def_id, closure_substs) => (closure_def_id, closure_substs),
-        _ => bug!("closure expr does not have closure type: {:?}", closure_ty),
+    let ty::Closure(closure_def_id, closure_substs) = *closure_ty.kind() else {
+        bug!("closure expr does not have closure type: {:?}", closure_ty);
     };
 
     let bound_vars =
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index ec2ff3c37ab..72c0985a63c 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -62,10 +62,7 @@ fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> Option<ConstVa
     use rustc_apfloat::ieee::{Double, Single};
     let scalar = match fty {
         ty::FloatTy::F32 => {
-            let rust_f = match num.parse::<f32>() {
-                Ok(f) => f,
-                Err(_) => return None,
-            };
+            let Ok(rust_f) = num.parse::<f32>() else { return None };
             let mut f = num.parse::<Single>().unwrap_or_else(|e| {
                 panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
             });
@@ -85,10 +82,7 @@ fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> Option<ConstVa
             Scalar::from_f32(f)
         }
         ty::FloatTy::F64 => {
-            let rust_f = match num.parse::<f64>() {
-                Ok(f) => f,
-                Err(_) => return None,
-            };
+            let Ok(rust_f) = num.parse::<f64>() else { return None };
             let mut f = num.parse::<Double>().unwrap_or_else(|e| {
                 panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
             });
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 829dec74803..5a7e1d88dd0 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -503,13 +503,12 @@ impl<'tcx> Cx<'tcx> {
                                 InlineAsmOperand::Const { value, span }
                             }
                             hir::InlineAsmOperand::Sym { ref expr } => {
-                                let qpath = match expr.kind {
-                                    hir::ExprKind::Path(ref qpath) => qpath,
-                                    _ => span_bug!(
+                                let hir::ExprKind::Path(ref qpath) = expr.kind else {
+                                    span_bug!(
                                         expr.span,
                                         "asm `sym` operand should be a path, found {:?}",
                                         expr.kind
-                                    ),
+                                    );
                                 };
                                 let temp_lifetime =
                                     self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
@@ -577,9 +576,8 @@ impl<'tcx> Cx<'tcx> {
             // Now comes the rote stuff:
             hir::ExprKind::Repeat(ref v, _) => {
                 let ty = self.typeck_results().expr_ty(expr);
-                let count = match ty.kind() {
-                    ty::Array(_, ct) => ct,
-                    _ => span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty),
+                let ty::Array(_, count) = ty.kind() else {
+                    span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
                 };
 
                 ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
@@ -1007,9 +1005,8 @@ impl<'tcx> Cx<'tcx> {
         // Reconstruct the output assuming it's a reference with the
         // same region and mutability as the receiver. This holds for
         // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
-        let (region, mutbl) = match *self.thir[args[0]].ty.kind() {
-            ty::Ref(region, _, mutbl) => (region, mutbl),
-            _ => span_bug!(span, "overloaded_place: receiver is not a reference"),
+        let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
+            span_bug!(span, "overloaded_place: receiver is not a reference");
         };
         let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut { ty: place_ty, mutbl });
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index e4d9bd9c237..1d31516e246 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -560,9 +560,9 @@ impl SplitVarLenSlice {
 
     /// Pass a set of slices relative to which to split this one.
     fn split(&mut self, slices: impl Iterator<Item = SliceKind>) {
-        let (max_prefix_len, max_suffix_len) = match &mut self.max_slice {
-            VarLen(prefix, suffix) => (prefix, suffix),
-            FixedLen(_) => return, // No need to split
+        let VarLen(max_prefix_len, max_suffix_len) = &mut self.max_slice else {
+            // No need to split
+            return;
         };
         // We grow `self.max_slice` to be larger than all slices encountered, as described above.
         // For diagnostics, we keep the prefix and suffix lengths separate, but grow them so that
@@ -1181,10 +1181,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
         ty: Ty<'tcx>,
         variant: &'a VariantDef,
     ) -> impl Iterator<Item = (Field, Ty<'tcx>)> + Captures<'a> + Captures<'p> {
-        let (adt, substs) = match ty.kind() {
-            ty::Adt(adt, substs) => (adt, substs),
-            _ => bug!(),
-        };
+        let ty::Adt(adt, substs) = ty.kind() else { bug!() };
         // Whether we must not match the fields of this variant exhaustively.
         let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
 
@@ -1578,9 +1575,8 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
                 match self_slice.kind {
                     FixedLen(_) => bug!("{:?} doesn't cover {:?}", self_slice, other_slice),
                     VarLen(prefix, suffix) => {
-                        let inner_ty = match *self.ty.kind() {
-                            ty::Slice(ty) | ty::Array(ty, _) => ty,
-                            _ => bug!("bad slice pattern {:?} {:?}", self.ctor, self.ty),
+                        let (ty::Slice(inner_ty) | ty::Array(inner_ty, _)) = *self.ty.kind() else {
+                            bug!("bad slice pattern {:?} {:?}", self.ctor, self.ty);
                         };
                         let prefix = &self.fields.fields[..prefix];
                         let suffix = &self.fields.fields[self_slice.arity() - suffix..];
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index ddf39fb824c..0c1daa519ab 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -245,9 +245,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             }
 
             hir::PatKind::Tuple(ref pats, ddpos) => {
-                let tys = match ty.kind() {
-                    ty::Tuple(ref tys) => tys,
-                    _ => span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty),
+                let ty::Tuple(ref tys) = ty.kind() else {
+                    span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty);
                 };
                 let subpatterns = self.lower_tuple_subpats(pats, tys.len(), ddpos);
                 PatKind::Leaf { subpatterns }
@@ -294,9 +293,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
             hir::PatKind::TupleStruct(ref qpath, ref pats, ddpos) => {
                 let res = self.typeck_results.qpath_res(qpath, pat.hir_id);
-                let adt_def = match ty.kind() {
-                    ty::Adt(adt_def, _) => adt_def,
-                    _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", ty),
+                let ty::Adt(adt_def, _) = ty.kind() else {
+                    span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", ty);
                 };
                 let variant_def = adt_def.variant_of_res(res);
                 let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields.len(), ddpos);
@@ -576,9 +574,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             }
             hir::ExprKind::Lit(ref lit) => (lit, false),
             hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => {
-                let lit = match expr.kind {
-                    hir::ExprKind::Lit(ref lit) => lit,
-                    _ => span_bug!(expr.span, "not a literal: {:?}", expr),
+                let hir::ExprKind::Lit(ref lit) = expr.kind else {
+                    span_bug!(expr.span, "not a literal: {:?}", expr);
                 };
                 (lit, true)
             }
diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
index e2269562b3d..f102872cd2d 100644
--- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
+++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
@@ -243,9 +243,8 @@ pub(crate) fn on_all_inactive_variants<'tcx>(
     active_variant: VariantIdx,
     mut handle_inactive_variant: impl FnMut(MovePathIndex),
 ) {
-    let enum_mpi = match move_data.rev_lookup.find(enum_place.as_ref()) {
-        LookupResult::Exact(mpi) => mpi,
-        LookupResult::Parent(_) => return,
+    let LookupResult::Exact(enum_mpi) = move_data.rev_lookup.find(enum_place.as_ref()) else {
+        return;
     };
 
     let enum_path = &move_data.move_paths[enum_mpi];
@@ -256,9 +255,8 @@ pub(crate) fn on_all_inactive_variants<'tcx>(
         let (downcast, base_proj) = variant_path.place.projection.split_last().unwrap();
         assert_eq!(enum_place.projection.len(), base_proj.len());
 
-        let variant_idx = match *downcast {
-            mir::ProjectionElem::Downcast(_, idx) => idx,
-            _ => unreachable!(),
+        let mir::ProjectionElem::Downcast(_, variant_idx) = *downcast else {
+            unreachable!();
         };
 
         if variant_idx != active_variant {
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index e8a6d8dad43..e20358ba989 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -274,11 +274,9 @@ where
     use std::io::{self, Write};
 
     let def_id = body.source.def_id();
-    let attrs = match RustcMirAttrs::parse(tcx, def_id) {
-        Ok(attrs) => attrs,
-
+    let Ok(attrs) = RustcMirAttrs::parse(tcx, def_id) else {
         // Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse`
-        Err(()) => return Ok(()),
+        return Ok(());
     };
 
     let mut file = match attrs.output_path(A::NAME) {
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index 34bc157a744..599b4087c78 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -628,9 +628,8 @@ where
         ret
     });
 
-    let mut html_diff = match html_diff {
-        Cow::Borrowed(_) => return raw_diff,
-        Cow::Owned(s) => s,
+    let Cow::Owned(mut html_diff) = html_diff else {
+        return raw_diff;
     };
 
     if inside_font_tag {
diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs
index 5dc8a003b47..63d935db8ca 100644
--- a/compiler/rustc_mir_dataflow/src/impls/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs
@@ -385,16 +385,14 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
             switch_on_enum_discriminant(self.tcx, &self.body, &self.body[block], discr)
         });
 
-        let (enum_place, enum_def) = match enum_ {
-            Some(x) => x,
-            None => return,
+        let Some((enum_place, enum_def)) = enum_ else {
+            return;
         };
 
         let mut discriminants = enum_def.discriminants(self.tcx);
         edge_effects.apply(|trans, edge| {
-            let value = match edge.value {
-                Some(x) => x,
-                None => return,
+            let Some(value) = edge.value else {
+                return;
             };
 
             // MIR building adds discriminants to the `values` array in the same order as they
@@ -507,16 +505,14 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
             switch_on_enum_discriminant(self.tcx, &self.body, &self.body[block], discr)
         });
 
-        let (enum_place, enum_def) = match enum_ {
-            Some(x) => x,
-            None => return,
+        let Some((enum_place, enum_def)) = enum_ else {
+            return;
         };
 
         let mut discriminants = enum_def.discriminants(self.tcx);
         edge_effects.apply(|trans, edge| {
-            let value = match edge.value {
-                Some(x) => x,
-                None => return,
+            let Some(value) = edge.value else {
+                return;
             };
 
             // MIR building adds discriminants to the `values` array in the same order as they
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index 1abb64219f6..757dc093755 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -66,10 +66,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
             if block.is_cleanup {
                 continue;
             }
-            let terminator = match &block.terminator {
-                Some(terminator) => terminator,
-                None => continue,
-            };
+            let Some(terminator) = &block.terminator else { continue };
             let span = terminator.source_info.span;
 
             let call_can_unwind = match &terminator.kind {
diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
index 9eaf2b6a211..8de0aad041c 100644
--- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
@@ -84,9 +84,8 @@ fn add_move_for_packed_drop<'tcx>(
     is_cleanup: bool,
 ) {
     debug!("add_move_for_packed_drop({:?} @ {:?})", terminator, loc);
-    let (place, target, unwind) = match terminator.kind {
-        TerminatorKind::Drop { ref place, target, unwind } => (place, target, unwind),
-        _ => unreachable!(),
+    let TerminatorKind::Drop { ref place, target, unwind } = terminator.kind else {
+        unreachable!();
     };
 
     let source_info = terminator.source_info;
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index fd93744d400..704f0901b95 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -410,12 +410,9 @@ fn check_unused_unsafe(
 ) {
     let body_id = tcx.hir().maybe_body_owned_by(tcx.hir().local_def_id_to_hir_id(def_id));
 
-    let body_id = match body_id {
-        Some(body) => body,
-        None => {
-            debug!("check_unused_unsafe({:?}) - no body found", def_id);
-            return;
-        }
+    let Some(body_id) = body_id else {
+        debug!("check_unused_unsafe({:?}) - no body found", def_id);
+        return;
     };
     let body = tcx.hir().body(body_id);
     debug!("check_unused_unsafe({:?}, body={:?}, used_unsafe={:?})", def_id, body, used_unsafe);
diff --git a/compiler/rustc_mir_transform/src/deaggregator.rs b/compiler/rustc_mir_transform/src/deaggregator.rs
index a5491f0ef4e..44753c5f631 100644
--- a/compiler/rustc_mir_transform/src/deaggregator.rs
+++ b/compiler/rustc_mir_transform/src/deaggregator.rs
@@ -26,11 +26,8 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
 
                 let stmt = stmt.replace_nop();
                 let source_info = stmt.source_info;
-                let (lhs, kind, operands) = match stmt.kind {
-                    StatementKind::Assign(box (lhs, Rvalue::Aggregate(kind, operands))) => {
-                        (lhs, kind, operands)
-                    }
-                    _ => bug!(),
+                let StatementKind::Assign(box (lhs, Rvalue::Aggregate(kind, operands))) = stmt.kind else {
+                    bug!();
                 };
 
                 Some(expand_aggregate(
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 7320b2738a7..a4b1d86ff61 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -98,12 +98,9 @@ fn find_dead_unwinds<'tcx>(
 
         debug!("find_dead_unwinds @ {:?}: {:?}", bb, bb_data);
 
-        let path = match env.move_data.rev_lookup.find(place.as_ref()) {
-            LookupResult::Exact(e) => e,
-            LookupResult::Parent(..) => {
-                debug!("find_dead_unwinds: has parent; skipping");
-                continue;
-            }
+        let LookupResult::Exact(path) = env.move_data.rev_lookup.find(place.as_ref()) else {
+            debug!("find_dead_unwinds: has parent; skipping");
+            continue;
         };
 
         flow_inits.seek_before_primary_effect(body.terminator_loc(bb));
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 05de52458ad..388bb7d3436 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1413,22 +1413,16 @@ impl EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
 
 impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
     fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
-        let lhs = match self.assigned_local {
-            Some(l) => l,
-            None => {
-                // This visitor only invokes `visit_place` for the right-hand side of an assignment
-                // and only after setting `self.assigned_local`. However, the default impl of
-                // `Visitor::super_body` may call `visit_place` with a `NonUseContext` for places
-                // with debuginfo. Ignore them here.
-                assert!(!context.is_use());
-                return;
-            }
+        let Some(lhs) = self.assigned_local else {
+            // This visitor only invokes `visit_place` for the right-hand side of an assignment
+            // and only after setting `self.assigned_local`. However, the default impl of
+            // `Visitor::super_body` may call `visit_place` with a `NonUseContext` for places
+            // with debuginfo. Ignore them here.
+            assert!(!context.is_use());
+            return;
         };
 
-        let rhs = match self.saved_local_for_direct_place(*place) {
-            Some(l) => l,
-            None => return,
-        };
+        let Some(rhs) = self.saved_local_for_direct_place(*place) else { return };
 
         if !self.storage_conflicts.contains(lhs, rhs) {
             bug!(
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 55ce5910c81..a00262a2201 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -118,9 +118,8 @@ impl<'tcx> Inliner<'tcx> {
                 continue;
             }
 
-            let callsite = match self.resolve_callsite(caller_body, bb, bb_data) {
-                None => continue,
-                Some(it) => it,
+            let Some(callsite) = self.resolve_callsite(caller_body, bb, bb_data) else {
+                continue;
             };
 
             let span = trace_span!("process_blocks", %callsite.callee, ?bb);
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index 44ded1647fc..de93ab7059f 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -46,12 +46,9 @@ crate fn mir_callgraph_reachable<'tcx>(
         trace!(%caller);
         for &(callee, substs) in tcx.mir_inliner_callees(caller.def) {
             let substs = caller.subst_mir_and_normalize_erasing_regions(tcx, param_env, substs);
-            let callee = match ty::Instance::resolve(tcx, param_env, callee, substs).unwrap() {
-                Some(callee) => callee,
-                None => {
-                    trace!(?callee, "cannot resolve, skipping");
-                    continue;
-                }
+            let Some(callee) = ty::Instance::resolve(tcx, param_env, callee, substs).unwrap() else {
+                trace!(?callee, "cannot resolve, skipping");
+                continue;
             };
 
             // Found a path.
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index 4c4497ad629..684d988ee9e 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -17,9 +17,8 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
             let terminator = block.terminator.as_mut().unwrap();
             if let TerminatorKind::Call { func, args, destination, .. } = &mut terminator.kind {
                 let func_ty = func.ty(local_decls, tcx);
-                let (intrinsic_name, substs) = match resolve_rust_intrinsic(tcx, func_ty) {
-                    None => continue,
-                    Some(it) => it,
+                let Some((intrinsic_name, substs)) = resolve_rust_intrinsic(tcx, func_ty) else {
+                    continue;
                 };
                 match intrinsic_name {
                     sym::unreachable => {
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index c8297744873..43d1d62a21e 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -61,10 +61,7 @@ fn lower_slice_len_call<'tcx>(
             if args.len() != 1 {
                 return;
             }
-            let arg = match args[0].place() {
-                Some(arg) => arg,
-                None => return,
-            };
+            let Some(arg) = args[0].place() else { return };
             let func_ty = func.ty(local_decls, tcx);
             match func_ty.kind() {
                 ty::FnDef(fn_def_id, _) if fn_def_id == &slice_len_fn_item_def_id => {
diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs
index 797f7ee2685..ec25f298d48 100644
--- a/compiler/rustc_mir_transform/src/nrvo.rs
+++ b/compiler/rustc_mir_transform/src/nrvo.rs
@@ -39,12 +39,9 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
         let def_id = body.source.def_id();
-        let returned_local = match local_eligible_for_nrvo(body) {
-            Some(l) => l,
-            None => {
-                debug!("`{:?}` was ineligible for NRVO", def_id);
-                return;
-            }
+        let Some(returned_local) = local_eligible_for_nrvo(body) else {
+            debug!("`{:?}` was ineligible for NRVO", def_id);
+            return;
         };
 
         if !tcx.consider_optimizing(|| format!("RenameReturnPlace {:?}", def_id)) {
diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs
index 1d912e61409..785716ebecc 100644
--- a/compiler/rustc_mir_transform/src/remove_zsts.rs
+++ b/compiler/rustc_mir_transform/src/remove_zsts.rs
@@ -26,9 +26,8 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
                     if !maybe_zst(place_ty) {
                         continue;
                     }
-                    let layout = match tcx.layout_of(param_env.and(place_ty)) {
-                        Ok(layout) => layout,
-                        Err(_) => continue,
+                    let Ok(layout) = tcx.layout_of(param_env.and(place_ty)) else {
+                        continue;
                     };
                     if !layout.is_zst() {
                         continue;
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index b8feeb993e7..837295292b9 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -734,9 +734,8 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
     let sig = tcx.fn_sig(ctor_id).no_bound_vars().expect("LBR in ADT constructor signature");
     let sig = tcx.normalize_erasing_regions(param_env, sig);
 
-    let (adt_def, substs) = match sig.output().kind() {
-        ty::Adt(adt_def, substs) => (adt_def, substs),
-        _ => bug!("unexpected type for ADT ctor {:?}", sig.output()),
+    let ty::Adt(adt_def, substs) = sig.output().kind() else {
+        bug!("unexpected type for ADT ctor {:?}", sig.output());
     };
 
     debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig);
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 4651e1f4ed0..d8b58ce53f8 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -172,9 +172,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
         let mut terminators: SmallVec<[_; 1]> = Default::default();
         let mut current = *start;
         while let Some(terminator) = self.take_terminator_if_simple_goto(current) {
-            let target = match terminator {
-                Terminator { kind: TerminatorKind::Goto { target }, .. } => target,
-                _ => unreachable!(),
+            let Terminator { kind: TerminatorKind::Goto { target }, .. } = terminator else {
+                unreachable!();
             };
             terminators.push((current, terminator));
             current = target;
@@ -182,9 +181,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
         let last = current;
         *start = last;
         while let Some((current, mut terminator)) = terminators.pop() {
-            let target = match terminator {
-                Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } => target,
-                _ => unreachable!(),
+            let Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } = terminator else {
+                unreachable!();
             };
             *changed |= *target != last;
             *target = last;
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 72c1b3fa6e9..bd42505e3a3 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -847,14 +847,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                 debug!(?source_info);
                 let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
                 debug!(?lint_root);
-                let lint_root = match lint_root {
-                    Some(lint_root) => lint_root,
+                let Some(lint_root) = lint_root else {
                     // This happens when the issue is in a function from a foreign crate that
                     // we monomorphized in the current crate. We can't get a `HirId` for things
                     // in other crates.
                     // FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
                     // but correct span? This would make the lint at least accept crate-level lint attributes.
-                    None => return,
+                    return;
                 };
                 self.tcx.struct_span_lint_hir(
                     LARGE_ASSIGNMENTS,
@@ -1256,9 +1255,8 @@ impl<'v> RootCollector<'_, 'v> {
     /// the return type of `main`. This is not needed when
     /// the user writes their own `start` manually.
     fn push_extra_entry_roots(&mut self) {
-        let main_def_id = match self.entry_fn {
-            Some((def_id, EntryFnType::Main)) => def_id,
-            _ => return,
+        let Some((main_def_id, EntryFnType::Main)) = self.entry_fn else {
+            return;
         };
 
         let start_def_id = match self.tcx.lang_items().require(LangItem::Start) {
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index ccd11f06bc5..c2a75d2bc2c 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -338,20 +338,16 @@ pub(super) fn check_for_substitution<'a>(
     ch: char,
     err: &mut DiagnosticBuilder<'a>,
 ) -> Option<token::TokenKind> {
-    let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) {
-        Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char),
-        None => return None,
+    let Some(&(_u_char, u_name, ascii_char)) = UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) else {
+        return None;
     };
 
     let span = Span::with_root_ctxt(pos, pos + Pos::from_usize(ch.len_utf8()));
 
-    let (ascii_name, token) = match ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) {
-        Some((_ascii_char, ascii_name, token)) => (ascii_name, token),
-        None => {
-            let msg = format!("substitution character not found for '{}'", ch);
-            reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
-            return None;
-        }
+    let Some((_ascii_char, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) else {
+        let msg = format!("substitution character not found for '{}'", ch);
+        reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
+        return None;
     };
 
     // special help suggestion for "directed" double quotes
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index e9aa4adcaf7..7cb8c35b868 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1667,9 +1667,8 @@ impl<'a> Parser<'a> {
             Err(LitError::NotLiteral) => None,
             Err(err) => {
                 let span = token.span;
-                let lit = match token.kind {
-                    token::Literal(lit) => lit,
-                    _ => unreachable!(),
+                let token::Literal(lit) = token.kind else {
+                    unreachable!();
                 };
                 self.bump();
                 self.report_lit_error(err, lit, span);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 93f5d79c0db..20ca8a99ab7 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -439,9 +439,8 @@ impl<'a> Parser<'a> {
 
     /// Recover if we parsed attributes and expected an item but there was none.
     fn recover_attrs_no_item(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
-        let (start, end) = match attrs {
-            [] => return Ok(()),
-            [x0 @ xn] | [x0, .., xn] => (x0, xn),
+        let ([start @ end] | [start, .., end]) = attrs else {
+            return Ok(());
         };
         let msg = if end.is_doc_comment() {
             "expected item after doc comment"
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index d3e7d1690cc..227a9e37dbc 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -524,9 +524,8 @@ impl<'a> Parser<'a> {
         // Skip looking for a trailing semicolon when we have an interpolated statement.
         maybe_whole!(self, NtStmt, |x| Some(x));
 
-        let mut stmt = match self.parse_stmt_without_recovery(true, ForceCollect::No)? {
-            Some(stmt) => stmt,
-            None => return Ok(None),
+        let Some(mut stmt) = self.parse_stmt_without_recovery(true, ForceCollect::No)? else {
+            return Ok(None);
         };
 
         let mut eat_semi = true;
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 479a08e43c0..3d69e8ba4e4 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1318,9 +1318,8 @@ impl CheckAttrVisitor<'_> {
             return false;
         }
 
-        let list = match attr.meta_item_list() {
-            None => return false,
-            Some(it) => it,
+        let Some(list) = attr.meta_item_list() else {
+            return false;
         };
 
         if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) {
@@ -1352,18 +1351,16 @@ impl CheckAttrVisitor<'_> {
             return false;
         }
 
-        let list = match attr.meta_item_list() {
+        let Some(list) = attr.meta_item_list() else {
             // The attribute form is validated on AST.
-            None => return false,
-            Some(it) => it,
+            return false;
         };
 
-        let (decl, generics) = match item {
-            Some(ItemLike::Item(Item {
-                kind: ItemKind::Fn(FnSig { decl, .. }, generics, _),
-                ..
-            })) => (decl, generics),
-            _ => bug!("should be a function item"),
+        let Some(ItemLike::Item(Item {
+            kind: ItemKind::Fn(FnSig { decl, .. }, generics, _),
+            ..
+        }))  = item else {
+            bug!("should be a function item");
         };
 
         for param in generics.params {
diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs
index 1031ba01c1b..bd772d9975b 100644
--- a/compiler/rustc_passes/src/intrinsicck.rs
+++ b/compiler/rustc_passes/src/intrinsicck.rs
@@ -35,10 +35,7 @@ struct ExprVisitor<'tcx> {
 /// If the type is `Option<T>`, it will return `T`, otherwise
 /// the type itself. Works on most `Option`-like types.
 fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-    let (def, substs) = match *ty.kind() {
-        ty::Adt(def, substs) => (def, substs),
-        _ => return ty,
-    };
+    let ty::Adt(def, substs) = *ty.kind() else { return ty };
 
     if def.variants.len() == 2 && !def.repr.c() && def.repr.int.is_none() {
         let data_idx;
@@ -202,18 +199,15 @@ impl<'tcx> ExprVisitor<'tcx> {
             }
             _ => None,
         };
-        let asm_ty = match asm_ty {
-            Some(asm_ty) => asm_ty,
-            None => {
-                let msg = &format!("cannot use value of type `{}` for inline assembly", ty);
-                let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
-                err.note(
-                    "only integers, floats, SIMD vectors, pointers and function pointers \
-                     can be used as arguments for inline assembly",
-                );
-                err.emit();
-                return None;
-            }
+        let Some(asm_ty) = asm_ty else {
+            let msg = &format!("cannot use value of type `{}` for inline assembly", ty);
+            let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
+            err.note(
+                "only integers, floats, SIMD vectors, pointers and function pointers \
+                 can be used as arguments for inline assembly",
+            );
+            err.emit();
+            return None;
         };
 
         // Check that the type implements Copy. The only case where this can
@@ -260,27 +254,24 @@ impl<'tcx> ExprVisitor<'tcx> {
         let asm_arch = self.tcx.sess.asm_arch.unwrap();
         let reg_class = reg.reg_class();
         let supported_tys = reg_class.supported_types(asm_arch);
-        let feature = match supported_tys.iter().find(|&&(t, _)| t == asm_ty) {
-            Some((_, feature)) => feature,
-            None => {
-                let msg = &format!("type `{}` cannot be used with this register class", ty);
-                let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
-                let supported_tys: Vec<_> =
-                    supported_tys.iter().map(|(t, _)| t.to_string()).collect();
-                err.note(&format!(
-                    "register class `{}` supports these types: {}",
-                    reg_class.name(),
-                    supported_tys.join(", "),
+        let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else {
+            let msg = &format!("type `{}` cannot be used with this register class", ty);
+            let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
+            let supported_tys: Vec<_> =
+                supported_tys.iter().map(|(t, _)| t.to_string()).collect();
+            err.note(&format!(
+                "register class `{}` supports these types: {}",
+                reg_class.name(),
+                supported_tys.join(", "),
+            ));
+            if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) {
+                err.help(&format!(
+                    "consider using the `{}` register class instead",
+                    suggest.name()
                 ));
-                if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) {
-                    err.help(&format!(
-                        "consider using the `{}` register class instead",
-                        suggest.name()
-                    ));
-                }
-                err.emit();
-                return Some(asm_ty);
             }
+            err.emit();
+            return Some(asm_ty);
         };
 
         // Check whether the selected type requires a target feature. Note that
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 69cd1b4fed5..a959089ebb3 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -1430,9 +1430,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
     }
 
     fn warn_about_unused_upvars(&self, entry_ln: LiveNode) {
-        let closure_min_captures = match self.closure_min_captures {
-            None => return,
-            Some(closure_min_captures) => closure_min_captures,
+        let Some(closure_min_captures) = self.closure_min_captures else {
+            return;
         };
 
         // If closure_min_captures is Some(), upvars must be Some() too.
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 6cd9dc23285..adbfb4fcf01 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -354,9 +354,8 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
                 let tcx = self.tcx;
                 self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.def_id));
 
-                let trait_def_id = match trait_ref.path.res {
-                    Res::Def(DefKind::Trait, def_id) => def_id,
-                    _ => unreachable!(),
+                let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res else {
+                    unreachable!();
                 };
 
                 if !trait_def_id.is_local() {
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 136059677c5..a55198e6a9f 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -756,9 +756,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                     return;
                 }
 
-                let cnum = match self.tcx.extern_mod_stmt_cnum(item.def_id) {
-                    Some(cnum) => cnum,
-                    None => return,
+                let Some(cnum) = self.tcx.extern_mod_stmt_cnum(item.def_id) else {
+                    return;
                 };
                 let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
                 self.tcx.check_stability(def_id, Some(item.hir_id()), item.span, None);
@@ -808,10 +807,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
             // so semi-randomly perform it here in stability.rs
             hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => {
                 let ty = self.tcx.type_of(item.def_id);
-                let (adt_def, substs) = match ty.kind() {
-                    ty::Adt(adt_def, substs) => (adt_def, substs),
-                    _ => bug!(),
-                };
+                let ty::Adt(adt_def, substs) = ty.kind() else { bug!() };
 
                 // Non-`Copy` fields are unstable, except for `ManuallyDrop`.
                 let param_env = self.tcx.param_env(item.def_id);
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index a8c2a5e1424..5e21161f2e0 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -351,13 +351,11 @@ impl<'a> Resolver<'a> {
             if !self.is_accessible_from(single_import.vis.get(), parent_scope.module) {
                 continue;
             }
-            let module = match single_import.imported_module.get() {
-                Some(x) => x,
-                None => return Err((Undetermined, Weak::No)),
+            let Some(module) = single_import.imported_module.get() else {
+                return Err((Undetermined, Weak::No));
             };
-            let ident = match single_import.kind {
-                ImportKind::Single { source, .. } => source,
-                _ => unreachable!(),
+            let ImportKind::Single { source: ident, .. } = single_import.kind else {
+                unreachable!();
             };
             match self.resolve_ident_in_module(
                 module,
@@ -1347,12 +1345,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     }
 
     fn resolve_glob_import(&mut self, import: &'b Import<'b>) {
-        let module = match import.imported_module.get().unwrap() {
-            ModuleOrUniformRoot::Module(module) => module,
-            _ => {
-                self.r.session.span_err(import.span, "cannot glob-import all possible crates");
-                return;
-            }
+        let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
+            self.r.session.span_err(import.span, "cannot glob-import all possible crates");
+            return;
         };
 
         if module.is_trait() {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 129db038f4a..f20cf29cc89 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1582,12 +1582,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         def_id: DefId,
         span: Span,
     ) {
-        let variants = match self.collect_enum_ctors(def_id) {
-            Some(variants) => variants,
-            None => {
-                err.note("you might have meant to use one of the enum's variants");
-                return;
-            }
+        let Some(variants) = self.collect_enum_ctors(def_id) else {
+            err.note("you might have meant to use one of the enum's variants");
+            return;
         };
 
         let suggest_only_tuple_variants =
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 3bea95fa1d5..2f0ad60709d 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -1748,10 +1748,7 @@ fn object_lifetime_defaults_for_item<'tcx>(
             let param_def_id = tcx.hir().local_def_id(param.hir_id);
             for predicate in generics.where_clause.predicates {
                 // Look for `type: ...` where clauses.
-                let data = match *predicate {
-                    hir::WherePredicate::BoundPredicate(ref data) => data,
-                    _ => continue,
-                };
+                let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue };
 
                 // Ignore `for<'a> type: ...` as they can change what
                 // lifetimes mean (although we could "just" handle it).
@@ -1976,12 +1973,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
     }
 
     fn check_uses_for_lifetimes_defined_by_scope(&mut self) {
-        let defined_by = match self.scope {
-            Scope::Binder { lifetimes, .. } => lifetimes,
-            _ => {
-                debug!("check_uses_for_lifetimes_defined_by_scope: not in a binder scope");
-                return;
-            }
+        let Scope::Binder { lifetimes: defined_by, .. } = self.scope else {
+            debug!("check_uses_for_lifetimes_defined_by_scope: not in a binder scope");
+            return;
         };
 
         let def_ids: Vec<_> = defined_by
@@ -2636,9 +2630,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             smallvec![(def_id, smallvec![])];
         let mut visited: FxHashSet<DefId> = FxHashSet::default();
         loop {
-            let (def_id, bound_vars) = match stack.pop() {
-                Some(next) => next,
-                None => break None,
+            let Some((def_id, bound_vars)) = stack.pop() else {
+                break None;
             };
             // See issue #83753. If someone writes an associated type on a non-trait, just treat it as
             // there being no supertrait HRTBs.
@@ -2723,10 +2716,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         });
 
-        let output = match output {
-            Some(ty) => ty,
-            None => return,
-        };
+        let Some(output) = output else { return };
 
         debug!("determine output");
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 28d8d9247ac..04b0a18b12b 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -3479,16 +3479,15 @@ impl<'a> Resolver<'a> {
         let ident = Ident::with_dummy_span(sym::main);
         let parent_scope = &ParentScope::module(module, self);
 
-        let name_binding = match self.resolve_ident_in_module(
+        let Ok(name_binding) = self.resolve_ident_in_module(
             ModuleOrUniformRoot::Module(module),
             ident,
             ValueNS,
             parent_scope,
             false,
             DUMMY_SP,
-        ) {
-            Ok(name_binding) => name_binding,
-            _ => return,
+        ) else {
+            return;
         };
 
         let res = name_binding.res();
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index 0ff56a30ea0..51f73ac2eb1 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -522,9 +522,8 @@ impl<'tcx> DumpVisitor<'tcx> {
         ty_params: &'tcx hir::Generics<'tcx>,
     ) {
         let enum_data = self.save_ctxt.get_item_data(item);
-        let enum_data = match enum_data {
-            None => return,
-            Some(data) => data,
+        let Some(enum_data) = enum_data else {
+            return;
         };
         down_cast_data!(enum_data, DefData, item.span);
 
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index 8b0adba9fab..5d32063d50b 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -115,12 +115,9 @@ impl<'tcx> SaveContext<'tcx> {
         let mut result = Vec::with_capacity(self.tcx.crates(()).len());
 
         for &n in self.tcx.crates(()).iter() {
-            let span = match self.tcx.extern_crate(n.as_def_id()) {
-                Some(&ExternCrate { span, .. }) => span,
-                None => {
-                    debug!("skipping crate {}, no data", n);
-                    continue;
-                }
+            let Some(&ExternCrate { span, .. }) = self.tcx.extern_crate(n.as_def_id()) else {
+                debug!("skipping crate {}, no data", n);
+                continue;
             };
             let lo_loc = self.span_utils.sess.source_map().lookup_char_pos(span.lo());
             result.push(ExternalCrateData {
@@ -566,12 +563,9 @@ impl<'tcx> SaveContext<'tcx> {
                 }
             },
             hir::ExprKind::MethodCall(ref seg, ..) => {
-                let method_id = match self.typeck_results().type_dependent_def_id(expr.hir_id) {
-                    Some(id) => id,
-                    None => {
-                        debug!("could not resolve method id for {:?}", expr);
-                        return None;
-                    }
+                let Some(method_id) = self.typeck_results().type_dependent_def_id(expr.hir_id) else {
+                    debug!("could not resolve method id for {:?}", expr);
+                    return None;
                 };
                 let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
                     ty::ImplContainer(_) => (Some(method_id), None),
diff --git a/compiler/rustc_serialize/src/json.rs b/compiler/rustc_serialize/src/json.rs
index 6a398549241..7e08b18cf48 100644
--- a/compiler/rustc_serialize/src/json.rs
+++ b/compiler/rustc_serialize/src/json.rs
@@ -2306,9 +2306,8 @@ impl crate::Decoder for Decoder {
             }
             json => bad!(ExpectedError("String or Object".to_owned(), json.to_string())),
         };
-        let idx = match names.iter().position(|n| *n == &name[..]) {
-            Some(idx) => idx,
-            None => bad!(UnknownVariantError(name)),
+        let Some(idx) = names.iter().position(|n| *n == &name[..]) else {
+            bad!(UnknownVariantError(name));
         };
         f(self, idx)
     }
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index b31fbab20ac..bd257dc6464 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -15,6 +15,7 @@ Core encoding and decoding interfaces.
 #![feature(min_specialization)]
 #![feature(core_intrinsics)]
 #![feature(maybe_uninit_slice)]
+#![feature(let_else)]
 #![feature(new_uninit)]
 #![cfg_attr(test, feature(test))]
 #![allow(rustc::internal)]
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 383250cd68f..82a95faa347 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,5 +1,6 @@
 #![feature(crate_visibility_modifier)]
 #![feature(derive_default_enum)]
+#![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(once_cell)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 0a4bd23937d..9a92258f809 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -763,12 +763,9 @@ mod parse {
             }
         }
 
-        let v = match v {
-            None => {
-                *slot = Some(MirSpanview::Statement);
-                return true;
-            }
-            Some(v) => v,
+        let Some(v) = v else {
+            *slot = Some(MirSpanview::Statement);
+            return true;
         };
 
         *slot = Some(match v.trim_end_matches('s') {
@@ -792,12 +789,9 @@ mod parse {
             }
         }
 
-        let v = match v {
-            None => {
-                *slot = Some(InstrumentCoverage::All);
-                return true;
-            }
-            Some(v) => v,
+        let Some(v) = v else {
+            *slot = Some(InstrumentCoverage::All);
+            return true;
         };
 
         *slot = Some(match v {
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index dea2fbf04be..5991b4d217c 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -17,6 +17,7 @@
 #![feature(array_windows)]
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
+#![feature(let_else)]
 #![feature(if_let_guard)]
 #![feature(negative_impls)]
 #![feature(nll)]
@@ -2103,13 +2104,9 @@ where
         // If this is not an empty or invalid span, we want to hash the last
         // position that belongs to it, as opposed to hashing the first
         // position past it.
-        let (file, line_lo, col_lo, line_hi, col_hi) = match ctx.span_data_to_lines_and_cols(&span)
-        {
-            Some(pos) => pos,
-            None => {
-                Hash::hash(&TAG_INVALID_SPAN, hasher);
-                return;
-            }
+        let Some((file, line_lo, col_lo, line_hi, col_hi)) = ctx.span_data_to_lines_and_cols(&span) else {
+            Hash::hash(&TAG_INVALID_SPAN, hasher);
+            return;
         };
 
         Hash::hash(&TAG_VALID_SPAN, hasher);
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 7f1fd28b30d..4ef86371298 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -121,12 +121,9 @@ impl TargetDataLayout {
                     dl.pointer_align = align(a, p)?;
                 }
                 [s, ref a @ ..] if s.starts_with('i') => {
-                    let bits = match s[1..].parse::<u64>() {
-                        Ok(bits) => bits,
-                        Err(_) => {
-                            size(&s[1..], "i")?; // For the user error.
-                            continue;
-                        }
+                    let Ok(bits) = s[1..].parse::<u64>() else {
+                        size(&s[1..], "i")?; // For the user error.
+                        continue;
                     };
                     let a = align(a, s)?;
                     match bits {
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index b18d17c1b7d..2919743e499 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -9,6 +9,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(bool_to_option)]
+#![feature(let_else)]
 #![feature(nll)]
 #![feature(never_type)]
 #![feature(associated_type_bounds)]
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index 51b66e1bb65..fee014ea7ef 100644
--- a/compiler/rustc_traits/src/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
@@ -72,9 +72,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     ) -> Arc<chalk_solve::rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> {
         let def_id = assoc_type_id.0;
         let assoc_item = self.interner.tcx.associated_item(def_id);
-        let trait_def_id = match assoc_item.container {
-            AssocItemContainer::TraitContainer(def_id) => def_id,
-            _ => unimplemented!("Not possible??"),
+        let AssocItemContainer::TraitContainer(trait_def_id) = assoc_item.container else {
+            unimplemented!("Not possible??");
         };
         match assoc_item.kind {
             AssocKind::Type => {}
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index b814b984dae..73fd95e98ca 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -2,6 +2,7 @@
 //! the guts are broken up into modules; see the comments in those modules.
 
 #![feature(crate_visibility_modifier)]
+#![feature(let_else)]
 #![feature(nll)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 55e19990761..702a9513b44 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -6,6 +6,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(control_flow_enum)]
+#![feature(let_else)]
 #![feature(nll)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index e44f80d5ac3..20ae986ffa4 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -49,10 +49,7 @@ fn sized_constraint_for_ty<'tcx>(
             // we know that `T` is Sized and do not need to check
             // it on the impl.
 
-            let sized_trait = match tcx.lang_items().sized_trait() {
-                Some(x) => x,
-                _ => return vec![ty],
-            };
+            let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] };
             let sized_predicate = ty::Binder::dummy(ty::TraitRef {
                 def_id: sized_trait,
                 substs: tcx.mk_substs_trait(ty, &[]),
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 96f92049983..dbe7ddeb6a8 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1808,12 +1808,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             (_, Res::SelfTy { trait_: Some(_), alias_to: Some((impl_def_id, _)) }) => {
                 // `Self` in an impl of a trait -- we have a concrete self type and a
                 // trait reference.
-                let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
-                    Some(trait_ref) => trait_ref,
-                    None => {
-                        // A cycle error occurred, most likely.
-                        return Err(ErrorReported);
-                    }
+                let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
+                    // A cycle error occurred, most likely.
+                    return Err(ErrorReported);
                 };
 
                 self.one_bound_for_assoc_type(
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index f64a90ed10e..679cac0b82a 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -219,10 +219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             (self.tcx.lang_items().fn_mut_trait(), Ident::with_dummy_span(sym::call_mut), true),
             (self.tcx.lang_items().fn_once_trait(), Ident::with_dummy_span(sym::call_once), false),
         ] {
-            let trait_def_id = match opt_trait_def_id {
-                Some(def_id) => def_id,
-                None => continue,
-            };
+            let Some(trait_def_id) = opt_trait_def_id else { continue };
 
             let opt_input_types = opt_arg_exprs.map(|arg_exprs| {
                 [self.tcx.mk_tup(arg_exprs.iter().map(|e| {
@@ -246,11 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if borrow {
                     // Check for &self vs &mut self in the method signature. Since this is either
                     // the Fn or FnMut trait, it should be one of those.
-                    let (region, mutbl) = if let ty::Ref(r, _, mutbl) =
-                        method.sig.inputs()[0].kind()
-                    {
-                        (r, mutbl)
-                    } else {
+                    let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else {
                         // The `fn`/`fn_mut` lang item is ill-formed, which should have
                         // caused an error elsewhere.
                         self.tcx
diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs
index 56b6c090690..a5e1b2579f8 100644
--- a/compiler/rustc_typeck/src/check/cast.rs
+++ b/compiler/rustc_typeck/src/check/cast.rs
@@ -799,10 +799,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
         let expr_kind = fcx.pointer_kind(m_expr.ty, self.span)?;
         let cast_kind = fcx.pointer_kind(m_cast.ty, self.span)?;
 
-        let cast_kind = match cast_kind {
+        let Some(cast_kind) = cast_kind else {
             // We can't cast if target pointer kind is unknown
-            None => return Err(CastError::UnknownCastPtrKind),
-            Some(cast_kind) => cast_kind,
+            return Err(CastError::UnknownCastPtrKind);
         };
 
         // Cast to thin pointer is OK
@@ -810,10 +809,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             return Ok(CastKind::PtrPtrCast);
         }
 
-        let expr_kind = match expr_kind {
+        let Some(expr_kind) = expr_kind else {
             // We can't cast to fat pointer if source pointer kind is unknown
-            None => return Err(CastError::UnknownExprPtrKind),
-            Some(expr_kind) => expr_kind,
+            return Err(CastError::UnknownExprPtrKind);
         };
 
         // thin -> fat? report invalid cast (don't complain about vtable kinds)
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 1650a62f79f..30ae382de42 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -415,13 +415,10 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Spa
     // have UB during initialization if they are uninhabited, but there also seems to be no good
     // reason to allow any statics to be uninhabited.
     let ty = tcx.type_of(def_id);
-    let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
-        Ok(l) => l,
-        Err(_) => {
-            // Generic statics are rejected, but we still reach this case.
-            tcx.sess.delay_span_bug(span, "generic static must be rejected");
-            return;
-        }
+    let Ok(layout) = tcx.layout_of(ParamEnv::reveal_all().and(ty)) else {
+        // Generic statics are rejected, but we still reach this case.
+        tcx.sess.delay_span_bug(span, "generic static must be rejected");
+        return;
     };
     if layout.abi.is_uninhabited() {
         tcx.struct_span_lint_hir(
@@ -852,10 +849,7 @@ pub(super) fn check_specialization_validity<'tcx>(
     impl_id: DefId,
     impl_item: &hir::ImplItemRef,
 ) {
-    let ancestors = match trait_def.ancestors(tcx, impl_id) {
-        Ok(ancestors) => ancestors,
-        Err(_) => return,
-    };
+    let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) else { return };
     let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| {
         if parent.is_from_trait() {
             None
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index 3c626837ef1..966ef8baedd 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -676,12 +676,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // We do not expect any bound regions in our predicate, so
         // skip past the bound vars.
-        let predicate = match predicate.no_bound_vars() {
-            Some(p) => p,
-            None => {
-                debug!("deduce_future_output_from_projection: has late-bound regions");
-                return None;
-            }
+        let Some(predicate) = predicate.no_bound_vars() else {
+            debug!("deduce_future_output_from_projection: has late-bound regions");
+            return None;
         };
 
         // Check that this is a projection from the `Future` trait.
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index be7ac006926..b011fb8804d 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -429,13 +429,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         // (e.g., in example above, the failure from relating `Vec<T>`
         // to the target type), since that should be the least
         // confusing.
-        let InferOk { value: ty, mut obligations } = match found {
-            Some(d) => d,
-            None => {
-                let err = first_error.expect("coerce_borrowed_pointer had no error");
-                debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
-                return Err(err);
-            }
+        let Some(InferOk { value: ty, mut obligations }) = found else {
+            let err = first_error.expect("coerce_borrowed_pointer had no error");
+            debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
+            return Err(err);
         };
 
         if ty == a && mt_a.mutbl == hir::Mutability::Not && autoderef.step_count() == 1 {
@@ -461,9 +458,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         // Now apply the autoref. We have to extract the region out of
         // the final ref type we got.
-        let r_borrow = match ty.kind() {
-            ty::Ref(r_borrow, _, _) => r_borrow,
-            _ => span_bug!(span, "expected a ref type, got {:?}", ty),
+        let ty::Ref(r_borrow, _, _) = ty.kind() else {
+            span_bug!(span, "expected a ref type, got {:?}", ty);
         };
         let mutbl = match mutbl_b {
             hir::Mutability::Not => AutoBorrowMutability::Not,
@@ -944,9 +940,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // We don't ever need two-phase here since we throw out the result of the coercion
         let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
         self.probe(|_| {
-            let ok = match coerce.coerce(source, target) {
-                Ok(ok) => ok,
-                _ => return false,
+            let Ok(ok) = coerce.coerce(source, target) else {
+                return false;
             };
             let mut fcx = traits::FulfillmentContext::new_in_snapshot();
             fcx.register_predicate_obligations(self, ok.obligations);
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index e7eadb760c7..6c45af3e786 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -435,44 +435,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// opt.map(|param| { takes_ref(param) });
     /// ```
     fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> {
-        let path = match expr.kind {
-            hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => path,
-            _ => return None,
+        let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.kind else {
+            return None;
         };
 
-        let local_id = match path.res {
-            hir::def::Res::Local(id) => id,
-            _ => return None,
+        let hir::def::Res::Local(local_id) = path.res else {
+            return None;
         };
 
         let local_parent = self.tcx.hir().get_parent_node(local_id);
-        let param_hir_id = match self.tcx.hir().find(local_parent) {
-            Some(Node::Param(hir::Param { hir_id, .. })) => hir_id,
-            _ => return None,
+        let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) = self.tcx.hir().find(local_parent) else {
+            return None;
         };
 
         let param_parent = self.tcx.hir().get_parent_node(*param_hir_id);
-        let (expr_hir_id, closure_fn_decl) = match self.tcx.hir().find(param_parent) {
-            Some(Node::Expr(hir::Expr {
-                hir_id,
-                kind: hir::ExprKind::Closure(_, decl, ..),
-                ..
-            })) => (hir_id, decl),
-            _ => return None,
+        let Some(Node::Expr(hir::Expr {
+            hir_id: expr_hir_id,
+            kind: hir::ExprKind::Closure(_, closure_fn_decl, ..),
+            ..
+        })) = self.tcx.hir().find(param_parent) else {
+            return None;
         };
 
         let expr_parent = self.tcx.hir().get_parent_node(*expr_hir_id);
         let hir = self.tcx.hir().find(expr_parent);
         let closure_params_len = closure_fn_decl.inputs.len();
-        let (method_path, method_expr) = match (hir, closure_params_len) {
-            (
-                Some(Node::Expr(hir::Expr {
-                    kind: hir::ExprKind::MethodCall(segment, expr, _),
-                    ..
-                })),
-                1,
-            ) => (segment, expr),
-            _ => return None,
+        let (
+            Some(Node::Expr(hir::Expr {
+                kind: hir::ExprKind::MethodCall(method_path, method_expr, _),
+                ..
+            })),
+            1,
+        ) = (hir, closure_params_len) else {
+            return None;
         };
 
         let self_ty = self.typeck_results.borrow().node_type(method_expr[0].hir_id);
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 4869d193d80..be9bf6399d7 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -622,15 +622,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // the `enclosing_loops` field and let's coerce the
             // type of `expr_opt` into what is expected.
             let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
-            let ctxt = match enclosing_breakables.opt_find_breakable(target_id) {
-                Some(ctxt) => ctxt,
-                None => {
-                    // Avoid ICE when `break` is inside a closure (#65383).
-                    return tcx.ty_error_with_message(
-                        expr.span,
-                        "break was outside loop, but no error was emitted",
-                    );
-                }
+            let Some(ctxt) = enclosing_breakables.opt_find_breakable(target_id) else {
+                // Avoid ICE when `break` is inside a closure (#65383).
+                return tcx.ty_error_with_message(
+                    expr.span,
+                    "break was outside loop, but no error was emitted",
+                );
             };
 
             if let Some(ref mut coerce) = ctxt.coerce {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 96bbc2800d5..f6cd1369403 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -745,10 +745,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         formal_args: &[Ty<'tcx>],
     ) -> Vec<Ty<'tcx>> {
         let formal_ret = self.resolve_vars_with_obligations(formal_ret);
-        let ret_ty = match expected_ret.only_has_type(self) {
-            Some(ret) => ret,
-            None => return Vec::new(),
-        };
+        let Some(ret_ty) = expected_ret.only_has_type(self) else { return Vec::new() };
         let expect_args = self
             .fudge_inference_if_ok(|| {
                 // Attempt to apply a subtyping relationship between the formal
@@ -1044,9 +1041,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Be helpful when the user wrote `{... expr;}` and
         // taking the `;` off is enough to fix the error.
         let last_stmt = blk.stmts.last()?;
-        let last_expr = match last_stmt.kind {
-            hir::StmtKind::Semi(ref e) => e,
-            _ => return None,
+        let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else {
+            return None;
         };
         let last_expr_ty = self.node_ty(last_expr.hir_id);
         let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) {
@@ -1061,11 +1057,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     last_def_id, last_bounds, exp_def_id, exp_bounds
                 );
 
-                let (last_local_id, exp_local_id) =
-                    match (last_def_id.as_local(), exp_def_id.as_local()) {
-                        (Some(last_hir_id), Some(exp_hir_id)) => (last_hir_id, exp_hir_id),
-                        (_, _) => return None,
-                    };
+                let last_local_id = last_def_id.as_local()?;
+                let exp_local_id = exp_def_id.as_local()?;
 
                 match (
                     &self.tcx.hir().expect_item(last_local_id).kind,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index f9c482713f1..f6a2447572f 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -438,9 +438,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // is and we were expecting a Box, ergo Pin<Box<expected>>, we
                 // can suggest Box::pin.
                 let parent = self.tcx.hir().get_parent_node(expr.hir_id);
-                let fn_name = match self.tcx.hir().find(parent) {
-                    Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) => fn_name,
-                    _ => return false,
+                let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) = self.tcx.hir().find(parent) else {
+                    return false;
                 };
                 match fn_name.kind {
                     ExprKind::Path(QPath::TypeRelative(
diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs
index fdc3ba17e3c..3fa873e46ab 100644
--- a/compiler/rustc_typeck/src/check/method/confirm.rs
+++ b/compiler/rustc_typeck/src/check/method/confirm.rs
@@ -149,14 +149,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         // time writing the results into the various typeck results.
         let mut autoderef =
             self.autoderef_overloaded_span(self.span, unadjusted_self_ty, self.call_expr.span);
-        let (ty, n) = match autoderef.nth(pick.autoderefs) {
-            Some(n) => n,
-            None => {
-                return self.tcx.ty_error_with_message(
-                    rustc_span::DUMMY_SP,
-                    &format!("failed autoderef {}", pick.autoderefs),
-                );
-            }
+        let Some((ty, n)) = autoderef.nth(pick.autoderefs) else {
+            return self.tcx.ty_error_with_message(
+                rustc_span::DUMMY_SP,
+                &format!("failed autoderef {}", pick.autoderefs),
+            );
         };
         assert_eq!(n, pick.autoderefs);
 
@@ -520,10 +517,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         &self,
         predicates: &ty::InstantiatedPredicates<'tcx>,
     ) -> Option<Span> {
-        let sized_def_id = match self.tcx.lang_items().sized_trait() {
-            Some(def_id) => def_id,
-            None => return None,
-        };
+        let sized_def_id = self.tcx.lang_items().sized_trait()?;
 
         traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied())
             // We don't care about regions here.
diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs
index e5ef52e0324..780a57278c5 100644
--- a/compiler/rustc_typeck/src/check/method/mod.rs
+++ b/compiler/rustc_typeck/src/check/method/mod.rs
@@ -371,15 +371,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Trait must have a method named `m_name` and it should not have
         // type parameters or early-bound regions.
         let tcx = self.tcx;
-        let method_item = match self.associated_value(trait_def_id, m_name) {
-            Some(method_item) => method_item,
-            None => {
-                tcx.sess.delay_span_bug(
-                    span,
-                    "operator trait does not have corresponding operator method",
-                );
-                return None;
-            }
+        let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
+            tcx.sess.delay_span_bug(
+                span,
+                "operator trait does not have corresponding operator method",
+            );
+            return None;
         };
         let def_id = method_item.def_id;
         let generics = tcx.generics_of(def_id);
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index c429e0f1653..876c575781c 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -1246,9 +1246,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             return None;
         }
 
-        let ty = match self_ty.kind() {
-            &ty::RawPtr(ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }) => ty,
-            _ => return None,
+        let &ty::RawPtr(ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }) = self_ty.kind() else {
+            return None;
         };
 
         let const_self_ty = ty::TypeAndMut { ty, mutbl: hir::Mutability::Not };
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index a523ba286ec..475070b6b83 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -37,9 +37,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
             // If it's not a simple function, look for things which implement `FnOnce`.
             _ => {
-                let fn_once = match tcx.lang_items().require(LangItem::FnOnce) {
-                    Ok(fn_once) => fn_once,
-                    Err(..) => return false,
+                let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
+                    return false;
                 };
 
                 // This conditional prevents us from asking to call errors and unresolved types.
@@ -112,12 +111,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     CandidateSource::ImplSource(impl_did) => {
                         // Provide the best span we can. Use the item, if local to crate, else
                         // the impl, if local to crate (item may be defaulted), else nothing.
-                        let item = match self.associated_value(impl_did, item_name).or_else(|| {
+                        let Some(item) = self.associated_value(impl_did, item_name).or_else(|| {
                             let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
                             self.associated_value(impl_trait_ref.def_id, item_name)
-                        }) {
-                            Some(item) => item,
-                            None => continue,
+                        }) else {
+                            continue;
                         };
                         let note_span = self
                             .tcx
@@ -194,10 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     CandidateSource::TraitSource(trait_did) => {
-                        let item = match self.associated_value(trait_did, item_name) {
-                            Some(item) => item,
-                            None => continue,
-                        };
+                        let Some(item) = self.associated_value(trait_did, item_name) else { continue };
                         let item_span = self
                             .tcx
                             .sess
@@ -1202,10 +1197,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut derives = Vec::<(String, Span, String)>::new();
         let mut traits = Vec::<Span>::new();
         for (pred, _, _) in unsatisfied_predicates {
-            let trait_pred = match pred.kind().skip_binder() {
-                ty::PredicateKind::Trait(trait_pred) => trait_pred,
-                _ => continue,
-            };
+            let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
             let adt = match trait_pred.self_ty().ty_adt_def() {
                 Some(adt) if adt.did.is_local() => adt,
                 _ => continue,
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index e034adde1be..767979c3912 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -981,9 +981,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if subpats.len() == variant.fields.len()
             || subpats.len() < variant.fields.len() && ddpos.is_some()
         {
-            let substs = match pat_ty.kind() {
-                ty::Adt(_, substs) => substs,
-                _ => bug!("unexpected pattern type {:?}", pat_ty),
+            let ty::Adt(_, substs) = pat_ty.kind() else {
+                bug!("unexpected pattern type {:?}", pat_ty);
             };
             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
@@ -1221,9 +1220,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> bool {
         let tcx = self.tcx;
 
-        let (substs, adt) = match adt_ty.kind() {
-            ty::Adt(adt, substs) => (substs, adt),
-            _ => span_bug!(pat.span, "struct pattern is not an ADT"),
+        let ty::Adt(adt, substs) = adt_ty.kind() else {
+            span_bug!(pat.span, "struct pattern is not an ADT");
         };
 
         // Index the struct fields' types.
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 949d857bff4..73f7cafa162 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -533,19 +533,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 base => bug!("Expected upvar, found={:?}", base),
             };
 
-            let min_cap_list = match root_var_min_capture_list.get_mut(&var_hir_id) {
-                None => {
-                    let mutability = self.determine_capture_mutability(&typeck_results, &place);
-                    let min_cap_list = vec![ty::CapturedPlace {
-                        place,
-                        info: capture_info,
-                        mutability,
-                        region: None,
-                    }];
-                    root_var_min_capture_list.insert(var_hir_id, min_cap_list);
-                    continue;
-                }
-                Some(min_cap_list) => min_cap_list,
+            let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else {
+                let mutability = self.determine_capture_mutability(&typeck_results, &place);
+                let min_cap_list = vec![ty::CapturedPlace {
+                    place,
+                    info: capture_info,
+                    mutability,
+                    region: None,
+                }];
+                root_var_min_capture_list.insert(var_hir_id, min_cap_list);
+                continue;
             };
 
             // Go through each entry in the current list of min_captures
diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
index f4e5cce0129..78e54997403 100644
--- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
@@ -40,11 +40,8 @@ struct InherentCollect<'tcx> {
 
 impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> {
     fn visit_item(&mut self, item: &hir::Item<'_>) {
-        let (ty, assoc_items) = match item.kind {
-            hir::ItemKind::Impl(hir::Impl { of_trait: None, ref self_ty, items, .. }) => {
-                (self_ty, items)
-            }
-            _ => return,
+        let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, items: assoc_items, .. }) = item.kind else {
+            return;
         };
 
         let self_ty = self.tcx.type_of(item.def_id);
diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs
index 9bb31003796..54fffeb3cda 100644
--- a/compiler/rustc_typeck/src/coherence/orphan.rs
+++ b/compiler/rustc_typeck/src/coherence/orphan.rs
@@ -38,9 +38,8 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorRep
     let trait_def_id = trait_ref.def_id;
 
     let item = tcx.hir().item(hir::ItemId { def_id });
-    let impl_ = match item.kind {
-        hir::ItemKind::Impl(ref impl_) => impl_,
-        _ => bug!("{:?} is not an impl: {:?}", def_id, item),
+    let hir::ItemKind::Impl(ref impl_) = item.kind else {
+        bug!("{:?} is not an impl: {:?}", def_id, item);
     };
     let sp = tcx.sess.source_map().guess_head_span(item.span);
     let tr = impl_.of_trait.as_ref().unwrap();
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 18f54eb2246..19b3d35566b 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-filelength
 //! "Collection" is the process of determining the type and other external
 //! details of each item in Rust. Collection is specifically concerned
 //! with *inter-procedural* things -- for example, for a function
@@ -1018,9 +1017,8 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
 
     let def_id = def_id.expect_local();
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-    let item = match tcx.hir().get(hir_id) {
-        Node::Item(item) => item,
-        _ => bug!(),
+    let Node::Item(item) = tcx.hir().get(hir_id) else {
+        bug!();
     };
 
     let repr = ReprOptions::new(tcx, def_id.to_def_id());
@@ -1122,9 +1120,8 @@ fn super_predicates_that_define_assoc_type(
         debug!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id);
         let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
 
-        let item = match tcx.hir().get(trait_hir_id) {
-            Node::Item(item) => item,
-            _ => bug!("trait_node_id {} is not an item", trait_hir_id),
+        let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
+            bug!("trait_node_id {} is not an item", trait_hir_id);
         };
 
         let (generics, bounds) = match item.kind {
@@ -2637,10 +2634,7 @@ fn from_target_feature(
     supported_target_features: &FxHashMap<String, Option<Symbol>>,
     target_features: &mut Vec<Symbol>,
 ) {
-    let list = match attr.meta_item_list() {
-        Some(list) => list,
-        None => return,
-    };
+    let Some(list) = attr.meta_item_list() else { return };
     let bad_item = |span| {
         let msg = "malformed `target_feature` attribute input";
         let code = "enable = \"..\"".to_owned();
@@ -2658,35 +2652,29 @@ fn from_target_feature(
         }
 
         // Must be of the form `enable = "..."` (a string).
-        let value = match item.value_str() {
-            Some(value) => value,
-            None => {
-                bad_item(item.span());
-                continue;
-            }
+        let Some(value) = item.value_str() else {
+            bad_item(item.span());
+            continue;
         };
 
         // We allow comma separation to enable multiple features.
         target_features.extend(value.as_str().split(',').filter_map(|feature| {
-            let feature_gate = match supported_target_features.get(feature) {
-                Some(g) => g,
-                None => {
-                    let msg =
-                        format!("the feature named `{}` is not valid for this target", feature);
-                    let mut err = tcx.sess.struct_span_err(item.span(), &msg);
-                    err.span_label(
-                        item.span(),
-                        format!("`{}` is not valid for this target", feature),
-                    );
-                    if let Some(stripped) = feature.strip_prefix('+') {
-                        let valid = supported_target_features.contains_key(stripped);
-                        if valid {
-                            err.help("consider removing the leading `+` in the feature name");
-                        }
+            let Some(feature_gate) = supported_target_features.get(feature) else {
+                let msg =
+                    format!("the feature named `{}` is not valid for this target", feature);
+                let mut err = tcx.sess.struct_span_err(item.span(), &msg);
+                err.span_label(
+                    item.span(),
+                    format!("`{}` is not valid for this target", feature),
+                );
+                if let Some(stripped) = feature.strip_prefix('+') {
+                    let valid = supported_target_features.contains_key(stripped);
+                    if valid {
+                        err.help("consider removing the leading `+` in the feature name");
                     }
-                    err.emit();
-                    return None;
                 }
+                err.emit();
+                return None;
             };
 
             // Only allow features whose feature gates have been enabled.
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index 92f88a15ee4..78097e3697f 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -164,12 +164,9 @@ fn get_impl_substs<'tcx>(
     // Conservatively use an empty `ParamEnv`.
     let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
     infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env, RegionckMode::default());
-    let impl2_substs = match infcx.fully_resolve(impl2_substs) {
-        Ok(s) => s,
-        Err(_) => {
-            tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();
-            return None;
-        }
+    let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
+        tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();
+        return None;
     };
     Some((impl1_substs, impl2_substs))
 }
diff --git a/compiler/rustc_typeck/src/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs
index 1bbd6d29294..876b1ae72ad 100644
--- a/compiler/rustc_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_typeck/src/mem_categorization.rs
@@ -484,9 +484,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         let place_ty = self.expr_ty(expr)?;
         let base_ty = self.expr_ty_adjusted(base)?;
 
-        let (region, mutbl) = match *base_ty.kind() {
-            ty::Ref(region, _, mutbl) => (region, mutbl),
-            _ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference"),
+        let ty::Ref(region, _, mutbl) = *base_ty.kind() else {
+            span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
         };
         let ref_ty = self.tcx().mk_ref(region, ty::TypeAndMut { ty: place_ty, mutbl });
 
@@ -544,14 +543,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     ) -> McResult<VariantIdx> {
         let res = self.typeck_results.qpath_res(qpath, pat_hir_id);
         let ty = self.typeck_results.node_type(pat_hir_id);
-        let adt_def = match ty.kind() {
-            ty::Adt(adt_def, _) => adt_def,
-            _ => {
-                self.tcx()
-                    .sess
-                    .delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
-                return Err(());
-            }
+        let ty::Adt(adt_def, _) = ty.kind() else {
+            self.tcx()
+                .sess
+                .delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
+            return Err(());
         };
 
         match res {
@@ -744,12 +740,9 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
             }
 
             PatKind::Slice(before, ref slice, after) => {
-                let element_ty = match place_with_id.place.ty().builtin_index() {
-                    Some(ty) => ty,
-                    None => {
-                        debug!("explicit index of non-indexable type {:?}", place_with_id);
-                        return Err(());
-                    }
+                let Some(element_ty) = place_with_id.place.ty().builtin_index() else {
+                    debug!("explicit index of non-indexable type {:?}", place_with_id);
+                    return Err(());
                 };
                 let elt_place = self.cat_projection(
                     pat,
diff --git a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
index 91727d57ddf..435df9c00f4 100644
--- a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
+++ b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
@@ -71,12 +71,9 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
             result,
         );
         debug!("implied_outlives_bounds for {:?}: {:#?}", ty, result);
-        let result = match result {
-            Ok(v) => v,
-            Err(_) => {
-                self.tcx.sess.delay_span_bug(span, "implied_outlives_bounds failed to instantiate");
-                return vec![];
-            }
+        let Ok(result) = result else {
+            self.tcx.sess.delay_span_bug(span, "implied_outlives_bounds failed to instantiate");
+            return vec![];
         };
 
         // Instantiation may have produced new inference variables and constraints on those
diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs
index 1774ddd7cbb..139841368d6 100644
--- a/library/core/src/char/convert.rs
+++ b/library/core/src/char/convert.rs
@@ -6,8 +6,6 @@ use crate::fmt;
 use crate::mem::transmute;
 use crate::str::FromStr;
 
-use super::MAX;
-
 /// Converts a `u32` to a `char`.
 ///
 /// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with
@@ -271,7 +269,20 @@ impl FromStr for char {
 
 #[inline]
 const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> {
-    if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
+    // This is an optimized version of the check
+    // (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF),
+    // which can also be written as
+    // i >= 0x110000 || (i >= 0xD800 && i < 0xE000).
+    //
+    // The XOR with 0xD800 permutes the ranges such that 0xD800..0xE000 is
+    // mapped to 0x0000..0x0800, while keeping all the high bits outside 0xFFFF the same.
+    // In particular, numbers >= 0x110000 stay in this range.
+    //
+    // Subtracting 0x800 causes 0x0000..0x0800 to wrap, meaning that a single
+    // unsigned comparison against 0x110000 - 0x800 will detect both the wrapped
+    // surrogate range as well as the numbers originally larger than 0x110000.
+    //
+    if (i ^ 0xD800).wrapping_sub(0x800) >= 0x110000 - 0x800 {
         Err(CharTryFromError(()))
     } else {
         // SAFETY: checked that it's a legal unicode value
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index dec1b5270d5..ebfd12d1533 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -805,7 +805,7 @@ impl<T: ?Sized> Pin<&'static T> {
     ///
     /// This is safe, because `T` is borrowed for the `'static` lifetime, which
     /// never ends.
-    #[unstable(feature = "pin_static_ref", issue = "78186")]
+    #[stable(feature = "pin_static_ref", since = "1.60.0")]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     pub const fn static_ref(r: &'static T) -> Pin<&'static T> {
         // SAFETY: The 'static borrow guarantees the data will not be
@@ -858,7 +858,7 @@ impl<T: ?Sized> Pin<&'static mut T> {
     ///
     /// This is safe, because `T` is borrowed for the `'static` lifetime, which
     /// never ends.
-    #[unstable(feature = "pin_static_ref", issue = "78186")]
+    #[stable(feature = "pin_static_ref", since = "1.60.0")]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> {
         // SAFETY: The 'static borrow guarantees the data will not be
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 304ba7ee554..1dba24dd149 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -79,6 +79,84 @@ impl [u8] {
     pub fn escape_ascii(&self) -> EscapeAscii<'_> {
         EscapeAscii { inner: self.iter().flat_map(EscapeByte) }
     }
+
+    /// Returns a byte slice with leading ASCII whitespace bytes removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// `u8::is_ascii_whitespace`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+    /// assert_eq!(b"  ".trim_ascii_start(), b"");
+    /// assert_eq!(b"".trim_ascii_start(), b"");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    pub const fn trim_ascii_start(&self) -> &[u8] {
+        let mut bytes = self;
+        // Note: A pattern matching based approach (instead of indexing) allows
+        // making the function const.
+        while let [first, rest @ ..] = bytes {
+            if first.is_ascii_whitespace() {
+                bytes = rest;
+            } else {
+                break;
+            }
+        }
+        bytes
+    }
+
+    /// Returns a byte slice with trailing ASCII whitespace bytes removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// `u8::is_ascii_whitespace`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+    /// assert_eq!(b"  ".trim_ascii_end(), b"");
+    /// assert_eq!(b"".trim_ascii_end(), b"");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    pub const fn trim_ascii_end(&self) -> &[u8] {
+        let mut bytes = self;
+        // Note: A pattern matching based approach (instead of indexing) allows
+        // making the function const.
+        while let [rest @ .., last] = bytes {
+            if last.is_ascii_whitespace() {
+                bytes = rest;
+            } else {
+                break;
+            }
+        }
+        bytes
+    }
+
+    /// Returns a byte slice with leading and trailing ASCII whitespace bytes
+    /// removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// `u8::is_ascii_whitespace`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+    /// assert_eq!(b"  ".trim_ascii(), b"");
+    /// assert_eq!(b"".trim_ascii(), b"");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    pub const fn trim_ascii(&self) -> &[u8] {
+        self.trim_ascii_start().trim_ascii_end()
+    }
 }
 
 impl_fn_for_zst! {
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 146096535db..dd9b035e86d 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -41,8 +41,8 @@ dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
 [target.x86_64-fortanix-unknown-sgx.dependencies]
 fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
 
-[target.'cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_os = "hermit"))'.dependencies]
-hermit-abi = { version = "0.1.19", features = ['rustc-dep-of-std'] }
+[target.'cfg(target_os = "hermit")'.dependencies]
+hermit-abi = { version = "0.2.0", features = ['rustc-dep-of-std'] }
 
 [target.wasm32-wasi.dependencies]
 wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 8c38db9b62c..2628afd4237 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -311,7 +311,6 @@
 #![feature(panic_internals)]
 #![feature(panic_can_unwind)]
 #![feature(panic_unwind)]
-#![feature(pin_static_ref)]
 #![feature(platform_intrinsics)]
 #![feature(portable_simd)]
 #![feature(prelude_import)]
@@ -365,6 +364,10 @@ extern crate libc;
 #[allow(unused_extern_crates)]
 extern crate unwind;
 
+#[doc(masked)]
+#[allow(unused_extern_crates)]
+extern crate miniz_oxide;
+
 // During testing, this crate is not actually the "real" std library, but rather
 // it links to the real std library, which was compiled from this same source
 // code. So any lang items std defines are conditionally excluded (or else they
diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs
index 1179a49c22f..c400f5f2c2e 100644
--- a/library/std/src/sys/hermit/fd.rs
+++ b/library/std/src/sys/hermit/fd.rs
@@ -1,6 +1,6 @@
 #![unstable(reason = "not public", issue = "none", feature = "fd")]
 
-use crate::io::{self, Read, ReadBuf};
+use crate::io::{self, Read};
 use crate::mem;
 use crate::sys::cvt;
 use crate::sys::hermit::abi;
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 029049d5434..8693e85e474 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -2056,6 +2056,7 @@ impl Step for RustDev {
             "llvm-bcanalyzer",
             "llvm-cov",
             "llvm-dwp",
+            "llvm-nm",
         ] {
             tarball.add_file(src_bindir.join(exe(bin, target)), "bin", 0o755);
         }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 1d312df1f78..fe1992a5d7e 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -302,7 +302,11 @@ fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: ty::Const<'_>) -> S
     // For all other types, fallback to the original `pretty_print_const`.
     match (ct.val(), ct.ty().kind()) {
         (ty::ConstKind::Value(ConstValue::Scalar(int)), ty::Uint(ui)) => {
-            format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str())
+            format!(
+                "{}{}",
+                format_integer_with_underscore_sep(&int.rustdoc_display()),
+                ui.name_str()
+            )
         }
         (ty::ConstKind::Value(ConstValue::Scalar(int)), ty::Int(i)) => {
             let ty = tcx.lift(ct.ty()).unwrap();
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 2455d56bd2b..a7f852a432c 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -250,6 +250,8 @@ impl<'tcx> Context<'tcx> {
     fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc>> {
         // BTreeMap instead of HashMap to get a sorted output
         let mut map: BTreeMap<_, Vec<_>> = BTreeMap::new();
+        let mut inserted: FxHashMap<ItemType, FxHashSet<Symbol>> = FxHashMap::default();
+
         for item in &m.items {
             if item.is_stripped() {
                 continue;
@@ -258,13 +260,16 @@ impl<'tcx> Context<'tcx> {
             let short = item.type_();
             let myname = match item.name {
                 None => continue,
-                Some(ref s) => s.to_string(),
+                Some(s) => s,
             };
-            let short = short.to_string();
-            map.entry(short).or_default().push((
-                myname,
-                Some(item.doc_value().map_or_else(String::new, |s| plain_text_summary(&s))),
-            ));
+            if inserted.entry(short).or_default().insert(myname) {
+                let short = short.to_string();
+                let myname = myname.to_string();
+                map.entry(short).or_default().push((
+                    myname,
+                    Some(item.doc_value().map_or_else(String::new, |s| plain_text_summary(&s))),
+                ));
+            }
         }
 
         if self.shared.sort_modules_alphabetically {
diff --git a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
index 1b53318806f..03f827f63f3 100644
--- a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
@@ -2,68 +2,63 @@
 + // MIR for `main` after ConstProp
   
   fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/invalid_constant.rs:15:11: 15:11
-      let _1: std::option::Option<()>;     // in scope 0 at $DIR/invalid_constant.rs:16:5: 16:12
-      let mut _2: std::option::Option<std::option::Option<()>>; // in scope 0 at $DIR/invalid_constant.rs:16:7: 16:11
-      let _3: main::Union;                 // in scope 0 at $DIR/invalid_constant.rs:22:9: 22:22
+      let mut _0: ();                      // return place in scope 0 at $DIR/invalid_constant.rs:13:11: 13:11
+      let _1: main::InvalidChar;           // in scope 0 at $DIR/invalid_constant.rs:19:9: 19:22
+      let mut _3: main::InvalidTag;        // in scope 0 at $DIR/invalid_constant.rs:26:25: 26:46
+      let mut _5: main::NoVariants;        // in scope 0 at $DIR/invalid_constant.rs:33:35: 33:56
       scope 1 {
-          debug _invalid_char => _3;       // in scope 1 at $DIR/invalid_constant.rs:22:9: 22:22
-      }
-      scope 2 (inlined f) {                // at $DIR/invalid_constant.rs:16:5: 16:12
-          debug x => _2;                   // in scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
-          let mut _4: isize;               // in scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
-          let _5: std::option::Option<()>; // in scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
-          scope 3 {
-              debug y => _5;               // in scope 3 at $DIR/invalid_constant.rs:16:5: 16:12
+          debug _invalid_char => _1;       // in scope 1 at $DIR/invalid_constant.rs:19:9: 19:22
+          let _2: [main::InvalidTag; 1];   // in scope 1 at $DIR/invalid_constant.rs:26:9: 26:21
+          scope 2 {
+              debug _invalid_tag => _2;    // in scope 2 at $DIR/invalid_constant.rs:26:9: 26:21
+              let _4: [main::NoVariants; 1]; // in scope 2 at $DIR/invalid_constant.rs:33:9: 33:31
+              scope 3 {
+                  debug _enum_without_variants => _4; // in scope 3 at $DIR/invalid_constant.rs:33:9: 33:31
+              }
           }
       }
   
       bb0: {
-          discriminant(_2) = 0;            // scope 0 at $DIR/invalid_constant.rs:16:7: 16:11
--         _4 = discriminant(_2);           // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
--         switchInt(move _4) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
-+         _4 = const 0_isize;              // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
-+         switchInt(const 0_isize) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
-      }
-  
-      bb1: {
--         _3 = const { Union { int: 0x110001 } }; // scope 0 at $DIR/invalid_constant.rs:22:25: 22:58
-+         _3 = const main::Union { int: 1114113_u32, chr: {transmute(0x00110001): char} }; // scope 0 at $DIR/invalid_constant.rs:22:25: 22:58
+          StorageLive(_1);                 // scope 0 at $DIR/invalid_constant.rs:19:9: 19:22
+-         _1 = const { InvalidChar { int: 0x110001 } }; // scope 0 at $DIR/invalid_constant.rs:19:25: 19:64
++         _1 = const InvalidChar { int: 1114113_u32, chr: {transmute(0x00110001): char} }; // scope 0 at $DIR/invalid_constant.rs:19:25: 19:64
                                            // ty::Const
-                                           // + ty: main::Union
--                                          // + val: Unevaluated(main::{constant#0}, [main::Union], None)
+                                           // + ty: main::InvalidChar
+-                                          // + val: Unevaluated(main::{constant#0}, [main::InvalidChar], None)
 +                                          // + val: Value(Scalar(0x00110001))
                                            // mir::Constant
-                                           // + span: $DIR/invalid_constant.rs:22:25: 22:58
--                                          // + literal: Const { ty: main::Union, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:8 ~ invalid_constant[726d]::main::{constant#0}), const_param_did: None }, substs: [main::Union], promoted: None }) }
-+                                          // + literal: Const { ty: main::Union, val: Value(Scalar(0x00110001)) }
-          nop;                             // scope 0 at $DIR/invalid_constant.rs:15:11: 23:2
-          return;                          // scope 0 at $DIR/invalid_constant.rs:23:2: 23:2
-      }
-  
-      bb2: {
--         _5 = ((_2 as Some).0: std::option::Option<()>); // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
--         _1 = _5;                         // scope 3 at $DIR/invalid_constant.rs:16:5: 16:12
-+         _5 = const Scalar(0x02): Option::<()>; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
+                                           // + span: $DIR/invalid_constant.rs:19:25: 19:64
+-                                          // + literal: Const { ty: main::InvalidChar, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ invalid_constant[726d]::main::{constant#0}), const_param_did: None }, substs: [main::InvalidChar], promoted: None }) }
++                                          // + literal: Const { ty: main::InvalidChar, val: Value(Scalar(0x00110001)) }
+          StorageLive(_2);                 // scope 1 at $DIR/invalid_constant.rs:26:9: 26:21
+          StorageLive(_3);                 // scope 1 at $DIR/invalid_constant.rs:26:25: 26:46
+          (_3.0: u32) = const 4_u32;       // scope 1 at $DIR/invalid_constant.rs:26:25: 26:46
+-         _2 = [move _3];                  // scope 1 at $DIR/invalid_constant.rs:26:24: 26:47
++         _2 = [const InvalidTag { int: 4_u32, e: Scalar(0x00000004): E }]; // scope 1 at $DIR/invalid_constant.rs:26:24: 26:47
 +                                          // ty::Const
-+                                          // + ty: std::option::Option<()>
-+                                          // + val: Value(Scalar(0x02))
++                                          // + ty: main::InvalidTag
++                                          // + val: Value(Scalar(0x00000004))
 +                                          // mir::Constant
-+                                          // + span: $DIR/invalid_constant.rs:16:5: 16:12
-+                                          // + literal: Const { ty: std::option::Option<()>, val: Value(Scalar(0x02)) }
-+         _1 = const Scalar(0x02): Option::<()>; // scope 3 at $DIR/invalid_constant.rs:16:5: 16:12
++                                          // + span: $DIR/invalid_constant.rs:26:24: 26:47
++                                          // + literal: Const { ty: main::InvalidTag, val: Value(Scalar(0x00000004)) }
+          StorageDead(_3);                 // scope 1 at $DIR/invalid_constant.rs:26:46: 26:47
+          StorageLive(_4);                 // scope 2 at $DIR/invalid_constant.rs:33:9: 33:31
+          StorageLive(_5);                 // scope 2 at $DIR/invalid_constant.rs:33:35: 33:56
+          (_5.0: u32) = const 0_u32;       // scope 2 at $DIR/invalid_constant.rs:33:35: 33:56
+-         _4 = [move _5];                  // scope 2 at $DIR/invalid_constant.rs:33:34: 33:57
++         _4 = [const NoVariants { int: 0_u32, empty: Scalar(<ZST>): Empty }]; // scope 2 at $DIR/invalid_constant.rs:33:34: 33:57
 +                                          // ty::Const
-+                                          // + ty: std::option::Option<()>
-+                                          // + val: Value(Scalar(0x02))
++                                          // + ty: main::NoVariants
++                                          // + val: Value(Scalar(0x00000000))
 +                                          // mir::Constant
-+                                          // + span: $DIR/invalid_constant.rs:16:5: 16:12
-+                                          // + literal: Const { ty: std::option::Option<()>, val: Value(Scalar(0x02)) }
-          goto -> bb1;                     // scope 0 at $DIR/invalid_constant.rs:10:20: 10:21
-      }
-  
-      bb3: {
-          discriminant(_1) = 0;            // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
-          goto -> bb1;                     // scope 0 at $DIR/invalid_constant.rs:9:17: 9:21
++                                          // + span: $DIR/invalid_constant.rs:33:34: 33:57
++                                          // + literal: Const { ty: main::NoVariants, val: Value(Scalar(0x00000000)) }
+          StorageDead(_5);                 // scope 2 at $DIR/invalid_constant.rs:33:56: 33:57
+          nop;                             // scope 0 at $DIR/invalid_constant.rs:13:11: 34:2
+          StorageDead(_4);                 // scope 2 at $DIR/invalid_constant.rs:34:1: 34:2
+          StorageDead(_2);                 // scope 1 at $DIR/invalid_constant.rs:34:1: 34:2
+          StorageDead(_1);                 // scope 0 at $DIR/invalid_constant.rs:34:1: 34:2
+          return;                          // scope 0 at $DIR/invalid_constant.rs:34:2: 34:2
       }
   }
   
diff --git a/src/test/mir-opt/const_prop/invalid_constant.rs b/src/test/mir-opt/const_prop/invalid_constant.rs
index 4aca9090019..e0879cf4800 100644
--- a/src/test/mir-opt/const_prop/invalid_constant.rs
+++ b/src/test/mir-opt/const_prop/invalid_constant.rs
@@ -1,23 +1,34 @@
-// Verify that we can pretty print invalid constant introduced
-// by constant propagation. Regression test for issue #93688.
-//
-// compile-flags: -Copt-level=0 -Zinline-mir
+// Verify that we can pretty print invalid constants.
+
 #![feature(inline_const)]
-#[inline(always)]
-pub fn f(x: Option<Option<()>>) -> Option<()> {
-    match x {
-        None => None,
-        Some(y) => y,
-    }
-}
+
+#[derive(Copy, Clone)]
+#[repr(u32)]
+enum E { A, B, C }
+
+#[derive(Copy, Clone)]
+enum Empty {}
 
 // EMIT_MIR invalid_constant.main.ConstProp.diff
 fn main() {
-    f(None);
-
-    union Union {
+    // An invalid char.
+    union InvalidChar {
         int: u32,
         chr: char,
     }
-    let _invalid_char = const { Union { int: 0x110001 } };
+    let _invalid_char = const { InvalidChar { int: 0x110001 } };
+
+    // An enum with an invalid tag. Regression test for #93688.
+    union InvalidTag {
+        int: u32,
+        e: E,
+    }
+    let _invalid_tag = [InvalidTag { int: 4 }];
+
+    // An enum without variants. Regression test for #94073.
+    union NoVariants {
+        int: u32,
+        empty: Empty,
+    }
+    let _enum_without_variants = [NoVariants { int: 0 }];
 }
diff --git a/src/test/run-make-fulldeps/static-nobundle/Makefile b/src/test/run-make-fulldeps/static-nobundle/Makefile
index 8f78c401a11..001081798a6 100644
--- a/src/test/run-make-fulldeps/static-nobundle/Makefile
+++ b/src/test/run-make-fulldeps/static-nobundle/Makefile
@@ -9,8 +9,10 @@ all: $(call NATIVE_STATICLIB,aaa)
 	$(RUSTC) bbb.rs --crate-type=rlib
 
 	# Check that bbb does NOT contain the definition of `native_func`
-	nm $(TMPDIR)/libbbb.rlib | $(CGREP) -ve "T _*native_func"
-	nm $(TMPDIR)/libbbb.rlib | $(CGREP) -e "U _*native_func"
+	# We're using the llvm-nm instead of the system nm to ensure it
+	# is compatible with the LLVM bitcode generated by rustc.
+	"$(LLVM_BIN_DIR)/llvm-nm" $(TMPDIR)/libbbb.rlib | $(CGREP) -ve "T _*native_func"
+	"$(LLVM_BIN_DIR)/llvm-nm" $(TMPDIR)/libbbb.rlib | $(CGREP) -e "U _*native_func"
 
 	# Check that aaa gets linked (either as `-l aaa` or `aaa.lib`) when building ccc.
 	$(RUSTC) ccc.rs -C prefer-dynamic --crate-type=dylib --print link-args | $(CGREP) -e '-l[" ]*aaa|aaa\.lib'
diff --git a/src/test/rustdoc-gui/duplicate-macro-reexport.goml b/src/test/rustdoc-gui/duplicate-macro-reexport.goml
new file mode 100644
index 00000000000..c79b3a220c4
--- /dev/null
+++ b/src/test/rustdoc-gui/duplicate-macro-reexport.goml
@@ -0,0 +1,14 @@
+// This test ensures that there is no macro duplicates in the sidebar.
+goto: file://|DOC_PATH|/test_docs/macro.a.html
+// Waiting for the elements in the sidebar to be rendered.
+wait-for: ".sidebar-elems .others .macro"
+// Check there is only one macro named "a" listed in the sidebar.
+assert-count: (
+    "//*[@class='sidebar-elems']//*[@class='others']/*[@class='block macro']//li/a[text()='a']",
+    1,
+)
+// Check there is only one macro named "b" listed in the sidebar.
+assert-count: (
+    "//*[@class='sidebar-elems']//*[@class='others']/*[@class='block macro']//li/a[text()='b']",
+    1,
+)
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index 2068d1d6f39..348b1a65c78 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -271,3 +271,6 @@ impl EmptyTrait1 for HasEmptyTraits {}
 impl EmptyTrait2 for HasEmptyTraits {}
 #[doc(cfg(feature = "some-feature"))]
 impl EmptyTrait3 for HasEmptyTraits {}
+
+mod macros;
+pub use macros::*;
diff --git a/src/test/rustdoc-gui/src/test_docs/macros.rs b/src/test/rustdoc-gui/src/test_docs/macros.rs
new file mode 100644
index 00000000000..07b2b97926d
--- /dev/null
+++ b/src/test/rustdoc-gui/src/test_docs/macros.rs
@@ -0,0 +1,4 @@
+#[macro_export]
+macro_rules! a{ () => {}}
+#[macro_export]
+macro_rules! b{ () => {}}
diff --git a/src/test/rustdoc/const-value-display.rs b/src/test/rustdoc/const-value-display.rs
new file mode 100644
index 00000000000..0ae52592b64
--- /dev/null
+++ b/src/test/rustdoc/const-value-display.rs
@@ -0,0 +1,9 @@
+#![crate_name = "foo"]
+
+// @has 'foo/constant.HOUR_IN_SECONDS.html'
+// @has - '//*[@class="docblock item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = 60 * 60; // 3_600u64'
+pub const HOUR_IN_SECONDS: u64 = 60 * 60;
+
+// @has 'foo/constant.NEGATIVE.html'
+// @has - '//*[@class="docblock item-decl"]//code' 'pub const NEGATIVE: i64 = -60 * 60; // -3_600i64'
+pub const NEGATIVE: i64 = -60 * 60;