From c05276ae7b5996049be7b34e497021e3e28156cd Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 2 Feb 2022 12:52:58 +0100 Subject: [PATCH 01/15] Stabilize pin_static_ref. --- library/core/src/pin.rs | 4 ++-- library/std/src/lib.rs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 09fc6df542975..8cae48e4aba2b 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -798,7 +798,7 @@ impl 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 @@ -851,7 +851,7 @@ impl 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/std/src/lib.rs b/library/std/src/lib.rs index 4f44a3183a6ec..c53101538ecb1 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -310,7 +310,6 @@ #![feature(panic_internals)] #![feature(panic_can_unwind)] #![feature(panic_unwind)] -#![feature(pin_static_ref)] #![feature(platform_intrinsics)] #![feature(portable_simd)] #![feature(prelude_import)] From 1ab5b0bc05e2d5d4fbb259366598e81d4607193a Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 15 Feb 2022 13:57:07 +0100 Subject: [PATCH 02/15] removing architecture requirements for RustyHermit RustHermit and HermitCore is able to run on aarch64 and x86_64. In the future these operating systems will also support RISC-V. Consequently, the dependency to a specific target should be removed. Building hermit-abi fails if the architecture isn't supported. --- Cargo.lock | 15 ++++++++++++--- library/std/Cargo.toml | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b330155d14483..be8d129e6e0d7 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", ] @@ -1610,6 +1610,15 @@ name = "hermit-abi" 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", @@ -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/library/std/Cargo.toml b/library/std/Cargo.toml index 146096535dbbe..dd9b035e86df1 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 } From 227d106aec8e127b51f422966b1412415e1925f6 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 15 Feb 2022 14:03:26 +0100 Subject: [PATCH 03/15] remove compiler warnings --- library/std/src/sys/hermit/fd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs index 1179a49c22fd0..c400f5f2c2e84 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; From 4b5beae0b2626bd8936856494b06d60b9a6e42ac Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Tue, 15 Feb 2022 15:17:22 +0100 Subject: [PATCH 04/15] adapt static-nobundle test to use llvm-nm No functional changes intended. This updates the test case to use llvm-nm instead of the system nm. This fixes an instance over at the experimental build of rustc with HEAD LLVM: https://buildkite.com/llvm-project/rust-llvm-integrate-prototype/builds/8380#ef6f41b5-8595-49a6-be37-0eff80e0ccb5 It is related to https://github.com/rust-lang/rust/pull/94001. The issue is that this test uses the system nm, which may not be recent enough to understand the update to uwtable. This replaces the test to use the llvm-nm that should be recent enough (consistent with the LLVM sources we use to build rustc). --- src/test/run-make-fulldeps/static-nobundle/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/run-make-fulldeps/static-nobundle/Makefile b/src/test/run-make-fulldeps/static-nobundle/Makefile index 8f78c401a1141..001081798a6e4 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' From 0647e3890435b387f7815e0e9bfb1786e1787d9f Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Wed, 16 Feb 2022 14:13:09 +0100 Subject: [PATCH 05/15] add llvm-nm to bootstrap dist bin's --- src/bootstrap/dist.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 472ee3fb01474..17a8fde0ccfea 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2060,6 +2060,7 @@ impl Step for RustDev { "llvm-bcanalyzer", "llvm-cov", "llvm-dwp", + "llvm-nm", ] { tarball.add_file(src_bindir.join(exe(bin, target)), "bin", 0o755); } From 5cf827421e0b5467fa50f897e2625d691835a109 Mon Sep 17 00:00:00 2001 From: pierwill Date: Thu, 17 Feb 2022 13:07:33 -0600 Subject: [PATCH 06/15] Add module-level docs for `rustc_middle::query` --- compiler/rustc_middle/src/query/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 43cfe6f3b8a7a..be86f1e92744e 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 From f7448a77e4d9ddb2e0b52905a6a89cab86ea35f6 Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Sun, 6 Feb 2022 02:20:53 +0100 Subject: [PATCH 07/15] core: Implement trim functions on byte slices Co-authored-by: Jubilee Young --- library/core/src/slice/ascii.rs | 78 +++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 080256f493f5f..a4ad85c9202bc 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -80,6 +80,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! { From 0f14bea448dfdafccbecbb6302a55191a763562a Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Thu, 17 Feb 2022 20:27:53 -0800 Subject: [PATCH 08/15] Optimize char_try_from_u32 The optimization was proposed by @falk-hueffner in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Micro-optimizing.20char.3A.3Afrom_u32/near/272146171, and I simplified it a bit and added an explanation of why the optimization is correct. --- library/core/src/char/convert.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 1774ddd7cbb2c..56dc2a594e176 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -271,7 +271,20 @@ impl FromStr for char { #[inline] const fn char_try_from_u32(i: u32) -> Result { - 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 From 7c3ebec0caf23a11773c8291005649dd488ca2ee Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Thu, 17 Feb 2022 22:14:54 -0800 Subject: [PATCH 09/15] fix --- library/core/src/char/convert.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 56dc2a594e176..139841368d6a1 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 From b78123cdcf53b146da3739acc436eb883ee39d17 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Feb 2022 17:31:38 +0100 Subject: [PATCH 10/15] Fix miniz_oxide types showing up in std --- library/std/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index a03da0682a5cd..e2cfd4a14acff 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -365,6 +365,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 From f2a404d433b4e43e1c2cc3d8cdc102011fb0f6d5 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 9 Feb 2022 17:24:51 -0500 Subject: [PATCH 11/15] Convert `newtype_index` to a proc macro The `macro_rules!` implementation was becomng excessively complicated, and difficult to modify. The new proc macro implementation should make it much easier to add new features (e.g. skipping certain `#[derive]`s) --- compiler/rustc_index/src/lib.rs | 2 + compiler/rustc_index/src/vec.rs | 455 --------------------------- compiler/rustc_macros/src/lib.rs | 23 ++ compiler/rustc_macros/src/newtype.rs | 324 +++++++++++++++++++ 4 files changed, 349 insertions(+), 455 deletions(-) create mode 100644 compiler/rustc_macros/src/newtype.rs diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 7919e40925392..a498b9fcce5b6 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -9,3 +9,5 @@ pub mod bit_set; pub mod interval; pub mod vec; + +pub use rustc_macros::newtype_index; diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 8b61530577d8e..4656994ac0869 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -49,461 +49,6 @@ impl Idx for u32 { } } -/// Creates a struct type `S` that can be used as an index with -/// `IndexVec` and so on. -/// -/// There are two ways of interacting with these indices: -/// -/// - The `From` impls are the preferred way. So you can do -/// `S::from(v)` with a `usize` or `u32`. And you can convert back -/// to an integer with `u32::from(s)`. -/// -/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` -/// to create/return a value. -/// -/// Internally, the index uses a u32, so the index must not exceed -/// `u32::MAX`. You can also customize things like the `Debug` impl, -/// what traits are derived, and so forth via the macro. -#[macro_export] -#[allow_internal_unstable(step_trait, rustc_attrs, trusted_step)] -macro_rules! newtype_index { - // ---- public rules ---- - - // Use default constants - ($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => ( - $crate::newtype_index!( - // Leave out derives marker so we can use its absence to ensure it comes first - @attrs [$(#[$attrs])*] - @type [$name] - // shave off 256 indices at the end to allow space for packing these indices into enums - @max [0xFFFF_FF00] - @vis [$v] - @debug_format ["{}"]); - ); - - // Define any constants - ($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => ( - $crate::newtype_index!( - // Leave out derives marker so we can use its absence to ensure it comes first - @attrs [$(#[$attrs])*] - @type [$name] - // shave off 256 indices at the end to allow space for packing these indices into enums - @max [0xFFFF_FF00] - @vis [$v] - @debug_format ["{}"] - $($tokens)+); - ); - - // ---- private rules ---- - - // Base case, user-defined constants (if any) have already been defined - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt]) => ( - $(#[$attrs])* - #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] - #[rustc_layout_scalar_valid_range_end($max)] - $v struct $type { - private: u32 - } - - impl Clone for $type { - #[inline] - fn clone(&self) -> Self { - *self - } - } - - impl $type { - /// Maximum value the index can take, as a `u32`. - $v const MAX_AS_U32: u32 = $max; - - /// Maximum value the index can take. - $v const MAX: Self = Self::from_u32($max); - - /// Creates a new index from a given `usize`. - /// - /// # Panics - /// - /// Will panic if `value` exceeds `MAX`. - #[inline] - $v const fn from_usize(value: usize) -> Self { - assert!(value <= ($max as usize)); - // SAFETY: We just checked that `value <= max`. - unsafe { - Self::from_u32_unchecked(value as u32) - } - } - - /// Creates a new index from a given `u32`. - /// - /// # Panics - /// - /// Will panic if `value` exceeds `MAX`. - #[inline] - $v const fn from_u32(value: u32) -> Self { - assert!(value <= $max); - // SAFETY: We just checked that `value <= max`. - unsafe { - Self::from_u32_unchecked(value) - } - } - - /// Creates a new index from a given `u32`. - /// - /// # Safety - /// - /// The provided value must be less than or equal to the maximum value for the newtype. - /// Providing a value outside this range is undefined due to layout restrictions. - /// - /// Prefer using `from_u32`. - #[inline] - $v const unsafe fn from_u32_unchecked(value: u32) -> Self { - Self { private: value } - } - - /// Extracts the value of this index as a `usize`. - #[inline] - $v const fn index(self) -> usize { - self.as_usize() - } - - /// Extracts the value of this index as a `u32`. - #[inline] - $v const fn as_u32(self) -> u32 { - self.private - } - - /// Extracts the value of this index as a `usize`. - #[inline] - $v const fn as_usize(self) -> usize { - self.as_u32() as usize - } - } - - impl std::ops::Add for $type { - type Output = Self; - - fn add(self, other: usize) -> Self { - Self::from_usize(self.index() + other) - } - } - - impl $crate::vec::Idx for $type { - #[inline] - fn new(value: usize) -> Self { - Self::from_usize(value) - } - - #[inline] - fn index(self) -> usize { - self.as_usize() - } - } - - impl ::std::iter::Step for $type { - #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { - ::steps_between( - &Self::index(*start), - &Self::index(*end), - ) - } - - #[inline] - fn forward_checked(start: Self, u: usize) -> Option { - Self::index(start).checked_add(u).map(Self::from_usize) - } - - #[inline] - fn backward_checked(start: Self, u: usize) -> Option { - Self::index(start).checked_sub(u).map(Self::from_usize) - } - } - - // Safety: The implementation of `Step` upholds all invariants. - unsafe impl ::std::iter::TrustedStep for $type {} - - impl From<$type> for u32 { - #[inline] - fn from(v: $type) -> u32 { - v.as_u32() - } - } - - impl From<$type> for usize { - #[inline] - fn from(v: $type) -> usize { - v.as_usize() - } - } - - impl From for $type { - #[inline] - fn from(value: usize) -> Self { - Self::from_usize(value) - } - } - - impl From for $type { - #[inline] - fn from(value: u32) -> Self { - Self::from_u32(value) - } - } - - $crate::newtype_index!( - @handle_debug - @derives [$($derives,)*] - @type [$type] - @debug_format [$debug_format]); - ); - - // base case for handle_debug where format is custom. No Debug implementation is emitted. - (@handle_debug - @derives [$($_derives:ident,)*] - @type [$type:ident] - @debug_format [custom]) => (); - - // base case for handle_debug, no debug overrides found, so use default - (@handle_debug - @derives [] - @type [$type:ident] - @debug_format [$debug_format:tt]) => ( - impl ::std::fmt::Debug for $type { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(fmt, $debug_format, self.as_u32()) - } - } - ); - - // Debug is requested for derive, don't generate any Debug implementation. - (@handle_debug - @derives [Debug, $($derives:ident,)*] - @type [$type:ident] - @debug_format [$debug_format:tt]) => (); - - // It's not Debug, so just pop it off the front of the derives stack and check the rest. - (@handle_debug - @derives [$_derive:ident, $($derives:ident,)*] - @type [$type:ident] - @debug_format [$debug_format:tt]) => ( - $crate::newtype_index!( - @handle_debug - @derives [$($derives,)*] - @type [$type] - @debug_format [$debug_format]); - ); - - // Append comma to end of derives list if it's missing - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident),*] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - derive [$($derives,)*] - $($tokens)*); - ); - - // By not including the @derives marker in this list nor in the default args, we can force it - // to come first if it exists. When encodable is custom, just use the derives list as-is. - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident,)+] - ENCODABLE = custom - $($tokens:tt)*) => ( - $crate::newtype_index!( - @attrs [$(#[$attrs])*] - @derives [$($derives,)+] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // By not including the @derives marker in this list nor in the default args, we can force it - // to come first if it exists. When encodable isn't custom, add serialization traits by default. - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident,)+] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)+] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - $crate::newtype_index!(@serializable $type); - ); - - // The case where no derives are added, but encodable is overridden. Don't - // derive serialization traits - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - ENCODABLE = custom - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // The case where no derives are added, add serialization derives by default - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - $crate::newtype_index!(@serializable $type); - ); - - (@serializable $type:ident) => ( - impl ::rustc_serialize::Decodable for $type { - fn decode(d: &mut D) -> Self { - Self::from_u32(d.read_u32()) - } - } - impl ::rustc_serialize::Encodable for $type { - fn encode(&self, e: &mut E) -> Result<(), E::Error> { - e.emit_u32(self.private) - } - } - ); - - // Rewrite final without comma to one that includes comma - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $name:ident = $constant:expr) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $name = $constant,); - ); - - // Rewrite final const without comma to one that includes comma - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $(#[doc = $doc:expr])* - const $name:ident = $constant:expr) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $(#[doc = $doc])* const $name = $constant,); - ); - - // Replace existing default for max - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$_max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - MAX = $max:expr, - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // Replace existing default for debug_format - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$_debug_format:tt] - DEBUG_FORMAT = $debug_format:tt, - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // Assign a user-defined constant - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $(#[doc = $doc:expr])* - const $name:ident = $constant:expr, - $($tokens:tt)*) => ( - $(#[doc = $doc])* - $v const $name: $type = $type::from_u32($constant); - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); -} - #[derive(Clone, PartialEq, Eq, Hash)] pub struct IndexVec { pub raw: Vec, diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 152ae159aed44..03e139755ba29 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,4 +1,5 @@ #![feature(proc_macro_diagnostic)] +#![feature(allow_internal_unstable)] #![allow(rustc::default_hash_types)] #![recursion_limit = "128"] @@ -8,6 +9,7 @@ use proc_macro::TokenStream; mod hash_stable; mod lift; +mod newtype; mod query; mod serialize; mod session_diagnostic; @@ -24,6 +26,27 @@ pub fn symbols(input: TokenStream) -> TokenStream { symbols::symbols(input.into()).into() } +/// Creates a struct type `S` that can be used as an index with +/// `IndexVec` and so on. +/// +/// There are two ways of interacting with these indices: +/// +/// - The `From` impls are the preferred way. So you can do +/// `S::from(v)` with a `usize` or `u32`. And you can convert back +/// to an integer with `u32::from(s)`. +/// +/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` +/// to create/return a value. +/// +/// Internally, the index uses a u32, so the index must not exceed +/// `u32::MAX`. You can also customize things like the `Debug` impl, +/// what traits are derived, and so forth via the macro. +#[proc_macro] +#[allow_internal_unstable(step_trait, rustc_attrs, trusted_step)] +pub fn newtype_index(input: TokenStream) -> TokenStream { + newtype::newtype(input).into() +} + decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); decl_derive!( [HashStable_Generic, attributes(stable_hasher)] => diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs new file mode 100644 index 0000000000000..b59ec34ba7b2d --- /dev/null +++ b/compiler/rustc_macros/src/newtype.rs @@ -0,0 +1,324 @@ +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::parse::*; +use syn::punctuated::Punctuated; +use syn::*; + +mod kw { + syn::custom_keyword!(derive); + syn::custom_keyword!(DEBUG_FORMAT); + syn::custom_keyword!(MAX); + syn::custom_keyword!(ENCODABLE); + syn::custom_keyword!(custom); +} + +#[derive(Debug)] +enum DebugFormat { + // The user will provide a custom `Debug` impl, so we shouldn't generate + // one + Custom, + // Use the specified format string in the generated `Debug` impl + // By default, this is "{}" + Format(String), +} + +// We parse the input and emit the output in a single step. +// This field stores the final macro output +struct Newtype(TokenStream); + +impl Parse for Newtype { + fn parse(input: ParseStream<'_>) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + input.parse::()?; + let name: Ident = input.parse()?; + + let body; + braced!(body in input); + + // Any additional `#[derive]` macro paths to apply + let mut derive_paths: Option> = None; + let mut debug_format: Option = None; + let mut max = None; + let mut consts = Vec::new(); + let mut encodable = true; + + // Parse an optional trailing comma + let try_comma = || -> Result<()> { + if body.lookahead1().peek(Token![,]) { + body.parse::()?; + } + Ok(()) + }; + + if body.lookahead1().peek(Token![..]) { + body.parse::()?; + } else { + loop { + if body.lookahead1().peek(kw::derive) { + body.parse::()?; + let derives; + bracketed!(derives in body); + let derives: Punctuated = + derives.parse_terminated(Path::parse)?; + try_comma()?; + if let Some(old) = derive_paths.replace(derives.into_iter().collect()) { + panic!("Specified multiple derives: {:?}", old); + } + continue; + } + if body.lookahead1().peek(kw::DEBUG_FORMAT) { + body.parse::()?; + body.parse::()?; + if body.lookahead1().peek(kw::custom) { + body.parse::()?; + if let Some(old) = debug_format.replace(DebugFormat::Custom) { + panic!("Specified multiple debug format options: {:?}", old); + } + } else { + let format_str: LitStr = body.parse()?; + if let Some(old) = + debug_format.replace(DebugFormat::Format(format_str.value())) + { + panic!("Specified multiple debug format options: {:?}", old); + } + } + try_comma()?; + continue; + } + if body.lookahead1().peek(kw::MAX) { + body.parse::()?; + body.parse::()?; + let val: Lit = body.parse()?; + try_comma()?; + if let Some(old) = max.replace(val) { + panic!("Specified multiple MAX: {:?}", old); + } + continue; + } + if body.lookahead1().peek(kw::ENCODABLE) { + body.parse::()?; + body.parse::()?; + body.parse::()?; + try_comma()?; + encodable = false; + continue; + } + + // We've parsed everything that the user provided, so we're done + if body.is_empty() { + break; + } + + // Otherwise, we are parsng a user-defined constant + let const_attrs = body.call(Attribute::parse_outer)?; + body.parse::()?; + let const_name: Ident = body.parse()?; + body.parse::()?; + let const_val: Expr = body.parse()?; + try_comma()?; + consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); }); + } + } + + let derive_paths = derive_paths.unwrap_or_else(Vec::new); + let debug_format = debug_format.unwrap_or(DebugFormat::Format("{}".to_string())); + // shave off 256 indices at the end to allow space for packing these indices into enums + let max = max.unwrap_or_else(|| Lit::Int(LitInt::new("0xFFFF_FF00", Span::call_site()))); + + let encodable_impls = if encodable { + quote! { + impl ::rustc_serialize::Decodable for #name { + fn decode(d: &mut D) -> Self { + Self::from_u32(d.read_u32()) + } + } + impl ::rustc_serialize::Encodable for #name { + fn encode(&self, e: &mut E) -> Result<(), E::Error> { + e.emit_u32(self.private) + } + } + } + } else { + quote! {} + }; + + let debug_impl = match debug_format { + DebugFormat::Custom => quote! {}, + DebugFormat::Format(format) => { + quote! { + impl ::std::fmt::Debug for #name { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(fmt, #format, self.as_u32()) + } + } + } + } + }; + + Ok(Self(quote! { + #(#attrs)* + #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, #(#derive_paths),*)] + #[rustc_layout_scalar_valid_range_end(#max)] + #vis struct #name { + private: u32, + } + + #(#consts)* + + impl Clone for #name { + #[inline] + fn clone(&self) -> Self { + *self + } + } + + impl #name { + /// Maximum value the index can take, as a `u32`. + #vis const MAX_AS_U32: u32 = #max; + + /// Maximum value the index can take. + #vis const MAX: Self = Self::from_u32(#max); + + /// Creates a new index from a given `usize`. + /// + /// # Panics + /// + /// Will panic if `value` exceeds `MAX`. + #[inline] + #vis const fn from_usize(value: usize) -> Self { + assert!(value <= (#max as usize)); + // SAFETY: We just checked that `value <= max`. + unsafe { + Self::from_u32_unchecked(value as u32) + } + } + + /// Creates a new index from a given `u32`. + /// + /// # Panics + /// + /// Will panic if `value` exceeds `MAX`. + #[inline] + #vis const fn from_u32(value: u32) -> Self { + assert!(value <= #max); + // SAFETY: We just checked that `value <= max`. + unsafe { + Self::from_u32_unchecked(value) + } + } + + /// Creates a new index from a given `u32`. + /// + /// # Safety + /// + /// The provided value must be less than or equal to the maximum value for the newtype. + /// Providing a value outside this range is undefined due to layout restrictions. + /// + /// Prefer using `from_u32`. + #[inline] + #vis const unsafe fn from_u32_unchecked(value: u32) -> Self { + Self { private: value } + } + + /// Extracts the value of this index as a `usize`. + #[inline] + #vis const fn index(self) -> usize { + self.as_usize() + } + + /// Extracts the value of this index as a `u32`. + #[inline] + #vis const fn as_u32(self) -> u32 { + self.private + } + + /// Extracts the value of this index as a `usize`. + #[inline] + #vis const fn as_usize(self) -> usize { + self.as_u32() as usize + } + } + + impl std::ops::Add for #name { + type Output = Self; + + fn add(self, other: usize) -> Self { + Self::from_usize(self.index() + other) + } + } + + impl rustc_index::vec::Idx for #name { + #[inline] + fn new(value: usize) -> Self { + Self::from_usize(value) + } + + #[inline] + fn index(self) -> usize { + self.as_usize() + } + } + + impl ::std::iter::Step for #name { + #[inline] + fn steps_between(start: &Self, end: &Self) -> Option { + ::steps_between( + &Self::index(*start), + &Self::index(*end), + ) + } + + #[inline] + fn forward_checked(start: Self, u: usize) -> Option { + Self::index(start).checked_add(u).map(Self::from_usize) + } + + #[inline] + fn backward_checked(start: Self, u: usize) -> Option { + Self::index(start).checked_sub(u).map(Self::from_usize) + } + } + + // Safety: The implementation of `Step` upholds all invariants. + unsafe impl ::std::iter::TrustedStep for #name {} + + impl From<#name> for u32 { + #[inline] + fn from(v: #name) -> u32 { + v.as_u32() + } + } + + impl From<#name> for usize { + #[inline] + fn from(v: #name) -> usize { + v.as_usize() + } + } + + impl From for #name { + #[inline] + fn from(value: usize) -> Self { + Self::from_usize(value) + } + } + + impl From for #name { + #[inline] + fn from(value: u32) -> Self { + Self::from_u32(value) + } + } + + #encodable_impls + #debug_impl + + })) + } +} + +pub fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as Newtype); + input.0.into() +} From db0b3bda5dd3dc146071bdc6ba126a70f8764f58 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 18 Feb 2022 16:16:02 -0500 Subject: [PATCH 12/15] Fix test --- compiler/rustc_index/src/vec/tests.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs index 15c43c72c7b37..915d2e8bcb3ff 100644 --- a/compiler/rustc_index/src/vec/tests.rs +++ b/compiler/rustc_index/src/vec/tests.rs @@ -1,5 +1,9 @@ #![allow(dead_code)] -newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA }); + +// Allows the macro invocation below to work +use crate as rustc_index; + +rustc_macros::newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA }); #[test] fn index_size_is_optimized() { From cb2e4ee8712b1653eb751b6f0f739040261e31cb Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 18 Feb 2022 19:14:51 -0500 Subject: [PATCH 13/15] Address review comments --- compiler/rustc_macros/src/newtype.rs | 34 ++++++++-------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs index b59ec34ba7b2d..f284e5cdd5c1e 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_macros/src/newtype.rs @@ -37,7 +37,7 @@ impl Parse for Newtype { braced!(body in input); // Any additional `#[derive]` macro paths to apply - let mut derive_paths: Option> = None; + let mut derive_paths: Vec = Vec::new(); let mut debug_format: Option = None; let mut max = None; let mut consts = Vec::new(); @@ -62,28 +62,23 @@ impl Parse for Newtype { let derives: Punctuated = derives.parse_terminated(Path::parse)?; try_comma()?; - if let Some(old) = derive_paths.replace(derives.into_iter().collect()) { - panic!("Specified multiple derives: {:?}", old); - } + derive_paths.extend(derives); continue; } if body.lookahead1().peek(kw::DEBUG_FORMAT) { body.parse::()?; body.parse::()?; - if body.lookahead1().peek(kw::custom) { + let new_debug_format = if body.lookahead1().peek(kw::custom) { body.parse::()?; - if let Some(old) = debug_format.replace(DebugFormat::Custom) { - panic!("Specified multiple debug format options: {:?}", old); - } + DebugFormat::Custom } else { let format_str: LitStr = body.parse()?; - if let Some(old) = - debug_format.replace(DebugFormat::Format(format_str.value())) - { - panic!("Specified multiple debug format options: {:?}", old); - } - } + DebugFormat::Format(format_str.value()) + }; try_comma()?; + if let Some(old) = debug_format.replace(new_debug_format) { + panic!("Specified multiple debug format options: {:?}", old); + } continue; } if body.lookahead1().peek(kw::MAX) { @@ -121,7 +116,6 @@ impl Parse for Newtype { } } - let derive_paths = derive_paths.unwrap_or_else(Vec::new); let debug_format = debug_format.unwrap_or(DebugFormat::Format("{}".to_string())); // shave off 256 indices at the end to allow space for packing these indices into enums let max = max.unwrap_or_else(|| Lit::Int(LitInt::new("0xFFFF_FF00", Span::call_site()))); @@ -158,7 +152,7 @@ impl Parse for Newtype { Ok(Self(quote! { #(#attrs)* - #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, #(#derive_paths),*)] + #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, #(#derive_paths),*)] #[rustc_layout_scalar_valid_range_end(#max)] #vis struct #name { private: u32, @@ -166,13 +160,6 @@ impl Parse for Newtype { #(#consts)* - impl Clone for #name { - #[inline] - fn clone(&self) -> Self { - *self - } - } - impl #name { /// Maximum value the index can take, as a `u32`. #vis const MAX_AS_U32: u32 = #max; @@ -313,7 +300,6 @@ impl Parse for Newtype { #encodable_impls #debug_impl - })) } } From c2da477853e1bd8e3a6077d17efabc7dc9b1b792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 17 Feb 2022 00:00:00 +0000 Subject: [PATCH 14/15] Fix pretty printing of enums without variants 92d20c4aaddea9507f8ad37fe37c551219153bbf removed no-variants special case from try_destructure_const with expectation that this case would be handled gracefully when read_discriminant returns an error. Alas in that case read_discriminant succeeds while returning a non-existing variant, so the special case is still necessary. --- .../rustc_const_eval/src/const_eval/mod.rs | 4 + .../invalid_constant.main.ConstProp.diff | 95 +++++++++---------- .../mir-opt/const_prop/invalid_constant.rs | 41 +++++--- 3 files changed, 75 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index ba1d5f45bbb10..724f92243d07e 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/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff index 1b53318806f4d..03f827f63f37f 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>; // 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(): 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 4aca90900199e..e0879cf4800ca 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<()> { - 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 }]; } From 2ef8af66196f7cc270a0532ea989f2fc6bc6885d Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 19 Feb 2022 00:48:49 +0100 Subject: [PATCH 15/15] Adopt let else in more places --- compiler/rustc_ast_lowering/src/asm.rs | 5 +- compiler/rustc_ast_lowering/src/expr.rs | 5 +- compiler/rustc_ast_lowering/src/item.rs | 5 +- .../rustc_ast_passes/src/ast_validation.rs | 10 +-- compiler/rustc_ast_passes/src/show_span.rs | 5 +- compiler/rustc_attr/src/builtin.rs | 24 +++--- .../src/diagnostics/conflict_errors.rs | 25 ++---- .../src/diagnostics/explain_borrow.rs | 11 +-- .../rustc_borrowck/src/diagnostics/mod.rs | 10 +-- .../src/diagnostics/move_errors.rs | 5 +- compiler/rustc_borrowck/src/lib.rs | 5 +- .../rustc_borrowck/src/region_infer/mod.rs | 12 ++- compiler/rustc_borrowck/src/type_check/mod.rs | 76 ++++++++----------- .../rustc_borrowck/src/universal_regions.rs | 5 +- .../src/cfg_accessible.rs | 5 +- .../rustc_builtin_macros/src/compile_error.rs | 5 +- compiler/rustc_builtin_macros/src/concat.rs | 5 +- .../rustc_builtin_macros/src/concat_bytes.rs | 5 +- .../src/deriving/clone.rs | 7 +- .../src/deriving/cmp/ord.rs | 5 +- .../src/deriving/cmp/partial_eq.rs | 5 +- .../src/deriving/cmp/partial_ord.rs | 5 +- .../src/deriving/default.rs | 5 +- .../rustc_builtin_macros/src/deriving/hash.rs | 5 +- .../rustc_builtin_macros/src/deriving/mod.rs | 5 +- compiler/rustc_builtin_macros/src/env.rs | 10 +-- .../src/proc_macro_harness.rs | 23 +++--- .../rustc_builtin_macros/src/source_util.rs | 15 ++-- .../rustc_codegen_llvm/src/back/archive.rs | 5 +- compiler/rustc_codegen_llvm/src/back/write.rs | 10 +-- compiler/rustc_codegen_llvm/src/base.rs | 5 +- compiler/rustc_codegen_llvm/src/consts.rs | 5 +- .../src/debuginfo/metadata.rs | 21 +++-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 10 +-- compiler/rustc_codegen_llvm/src/type_of.rs | 5 +- compiler/rustc_codegen_ssa/src/back/link.rs | 15 ++-- .../rustc_codegen_ssa/src/back/metadata.rs | 5 +- .../src/back/symbol_export.rs | 5 +- compiler/rustc_codegen_ssa/src/base.rs | 21 +++-- compiler/rustc_codegen_ssa/src/common.rs | 7 +- .../rustc_codegen_ssa/src/mir/constant.rs | 5 +- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 15 +--- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 32 ++++---- compiler/rustc_codegen_ssa/src/mir/mod.rs | 5 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 15 ++-- .../src/binary_search_util/mod.rs | 5 +- compiler/rustc_data_structures/src/lib.rs | 1 + .../src/transitive_relation.rs | 12 +-- compiler/rustc_driver/src/lib.rs | 6 +- compiler/rustc_errors/src/emitter.rs | 10 +-- compiler/rustc_expand/src/base.rs | 23 ++---- compiler/rustc_expand/src/config.rs | 27 +++---- compiler/rustc_expand/src/expand.rs | 10 +-- compiler/rustc_expand/src/module.rs | 31 ++++---- .../rustc_expand/src/proc_macro_server.rs | 5 +- compiler/rustc_hir/src/hir.rs | 5 +- compiler/rustc_hir/src/lib.rs | 1 + .../src/persist/dirty_clean.rs | 5 +- compiler/rustc_incremental/src/persist/fs.rs | 48 +++++------- compiler/rustc_index/src/interval.rs | 18 ++--- .../mismatched_static_lifetime.rs | 31 ++++---- .../nice_region_error/static_impl_trait.rs | 15 ++-- .../src/infer/lexical_region_resolve/mod.rs | 10 +-- compiler/rustc_interface/src/queries.rs | 5 +- compiler/rustc_interface/src/util.rs | 5 +- compiler/rustc_lint/src/context.rs | 5 +- compiler/rustc_lint/src/internal.rs | 5 +- compiler/rustc_lint/src/levels.rs | 6 +- compiler/rustc_lint/src/non_ascii_idents.rs | 5 +- compiler/rustc_lint/src/types.rs | 9 +-- compiler/rustc_metadata/src/creader.rs | 10 +-- .../rustc_metadata/src/foreign_modules.rs | 5 +- compiler/rustc_metadata/src/locator.rs | 13 ++-- compiler/rustc_metadata/src/native_libs.rs | 27 +++---- .../src/rmeta/decoder/cstore_impl.rs | 5 +- compiler/rustc_middle/src/middle/region.rs | 5 +- compiler/rustc_middle/src/mir/pretty.rs | 10 +-- compiler/rustc_middle/src/ty/context.rs | 10 +-- compiler/rustc_middle/src/ty/error.rs | 9 +-- compiler/rustc_middle/src/ty/layout.rs | 15 ++-- compiler/rustc_middle/src/ty/print/pretty.rs | 5 +- .../rustc_mir_build/src/build/matches/test.rs | 12 +-- compiler/rustc_mir_build/src/build/mod.rs | 5 +- compiler/rustc_mir_build/src/thir/constant.rs | 10 +-- compiler/rustc_mir_build/src/thir/cx/expr.rs | 17 ++--- .../src/thir/pattern/deconstruct_pat.rs | 16 ++-- .../rustc_mir_build/src/thir/pattern/mod.rs | 15 ++-- .../src/drop_flag_effects.rs | 10 +-- .../src/framework/engine.rs | 6 +- .../src/framework/graphviz.rs | 5 +- compiler/rustc_mir_dataflow/src/impls/mod.rs | 20 ++--- .../src/abort_unwinding_calls.rs | 5 +- .../src/add_moves_for_packed_drops.rs | 5 +- .../rustc_mir_transform/src/check_unsafety.rs | 9 +-- .../rustc_mir_transform/src/deaggregator.rs | 7 +- .../src/elaborate_drops.rs | 9 +-- compiler/rustc_mir_transform/src/generator.rs | 22 ++---- compiler/rustc_mir_transform/src/inline.rs | 5 +- .../rustc_mir_transform/src/inline/cycle.rs | 9 +-- .../src/lower_intrinsics.rs | 5 +- .../src/lower_slice_len.rs | 5 +- compiler/rustc_mir_transform/src/nrvo.rs | 9 +-- .../rustc_mir_transform/src/remove_zsts.rs | 5 +- compiler/rustc_mir_transform/src/shim.rs | 5 +- compiler/rustc_mir_transform/src/simplify.rs | 10 +-- compiler/rustc_monomorphize/src/collector.rs | 10 +-- .../rustc_parse/src/lexer/unicode_chars.rs | 16 ++-- compiler/rustc_parse/src/parser/expr.rs | 5 +- compiler/rustc_parse/src/parser/item.rs | 5 +- compiler/rustc_parse/src/parser/stmt.rs | 5 +- compiler/rustc_passes/src/check_attr.rs | 21 +++-- compiler/rustc_passes/src/intrinsicck.rs | 61 +++++++-------- compiler/rustc_passes/src/liveness.rs | 5 +- compiler/rustc_passes/src/reachable.rs | 5 +- compiler/rustc_passes/src/stability.rs | 10 +-- compiler/rustc_resolve/src/imports.rs | 19 ++--- .../rustc_resolve/src/late/diagnostics.rs | 9 +-- compiler/rustc_resolve/src/late/lifetimes.rs | 24 ++---- compiler/rustc_resolve/src/lib.rs | 7 +- .../rustc_save_analysis/src/dump_visitor.rs | 5 +- compiler/rustc_save_analysis/src/lib.rs | 18 ++--- compiler/rustc_serialize/src/json.rs | 5 +- compiler/rustc_serialize/src/lib.rs | 1 + compiler/rustc_session/src/lib.rs | 1 + compiler/rustc_session/src/options.rs | 18 ++--- compiler/rustc_span/src/lib.rs | 11 +-- compiler/rustc_target/src/abi/mod.rs | 9 +-- compiler/rustc_target/src/lib.rs | 1 + compiler/rustc_traits/src/chalk/db.rs | 5 +- compiler/rustc_traits/src/lib.rs | 1 + compiler/rustc_ty_utils/src/lib.rs | 1 + compiler/rustc_ty_utils/src/ty.rs | 5 +- 132 files changed, 539 insertions(+), 881 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 5a85356d96daa..17425fb0a6e9d 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -338,9 +338,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 17bc8d7591b40..0b7bf09cad184 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -326,9 +326,8 @@ impl<'hir> LoweringContext<'_, 'hir> { args: Vec>, 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 f48cf212a984b..f3ed8314b3c2e 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1331,9 +1331,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 eb7c75cac0520..20caed1b230d5 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) { - 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 6cef26a13e6b0..27637e311f48d 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 dca7f5dd48769..639dd0e36ddeb 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -531,17 +531,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(); @@ -644,9 +641,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 fce5ed0ef4239..6988fbf833666 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 db8268c8e2e89..b1e5a211cf1cb 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 73b0d39828504..5f533ddcb82ba 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 cc6566882ad5d..d4f238ff71f25 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 459b03b0fad65..719862e67c873 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 abd6a15334c90..b99fb00599e7f 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 46924f50d2e1b..8c4d81aaf5250 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 72de3805467dc..33e65439fd7df 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 09ed1af345675..7b7db3eaea613 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 f5955604e5fb2..990b88295690c 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 { - 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 59361510a672e..a23dd1d1213b7 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 { - 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 c06af5206d5b1..a1afec410c1c5 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 { - 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 2e5ad66c60bb8..fd26a376f91aa 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 f84e6e0762012..2b3ac0a86c16c 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 8e9f15743cc34..eead8b37024c0 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 { let op = |cx: &mut ExtCtxt<'_>, span: Span, self_f: P, other_fs: &[P]| { - 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 151a919e0293b..d28ac822a1ed9 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 1d1eee88a68e6..ca83941f600ca 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 { - 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 7114b98768091..f1d46f03bad8f 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 { - 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 0ca7988ca152f..812d86af6e8f2 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 285027fc632d7..66ee93ce3c90e 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 { - 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 6f61e4cba0776..ecd69c4afdf0b 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -108,11 +108,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 { @@ -224,15 +222,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 1ea2c8843d6d7..bbc8e62d68ff0 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 { 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 { 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 { 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 21bd1dae7ac47..1a2cec2a0d97f 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 384596dfff503..e60ad170434c3 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 7b6ce5ea89bed..e15b86aa84fa4 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 6707de933522b..51223697dbd85 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 1abc3fb523d1b..fd1e61f2b8aa0 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 cfd23f5c24e05..f471f461e8639 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 fafb9a6dbdecc..dc2df8849f8ae 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 58e0667d67898..5a07b23f3f989 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 9ebbcac76a28a..39d39ad13655a 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 aeddd926896e8..8191d8b5e4924 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 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 4a5eabc87554c..ed6c156547e29 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 2df58ecc9f68a..ae54442e884a8 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 5cdf131b0b633..479b2b05f4305 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 c710fcc2c1dcb..bb53c722a244a 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 c654232c10a57..f15c469ae5741 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 814e4d626e119..fcae40616648f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -281,9 +281,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 0c526ff13f2ba..66be58cf62ca0 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 { 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_data_structures/src/binary_search_util/mod.rs b/compiler/rustc_data_structures/src/binary_search_util/mod.rs index bf09b2f8eef37..d40172a2e2fe8 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 80f83140f4b41..ea02a73c42204 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 ccf8bd69ebd06..0af571610fe95 100644 --- a/compiler/rustc_data_structures/src/transitive_relation.rs +++ b/compiler/rustc_data_structures/src/transitive_relation.rs @@ -190,11 +190,8 @@ impl TransitiveRelation { /// /// 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 TransitiveRelation { /// 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 3601169528b9d..83a3b856943e6 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 f90f4d46a9a0b..bfed9211cec34 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 258320aeb636a..2bdf3b3912619 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 5fa7ffd554ef1..c0d7bc359bf44 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 { - 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 9a4daa6d7500a..bdc9c064a6f9c 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 e9532dbe2ceca..aa54bdbd3a73d 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 { // 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 efbe0b65715f4..99a945b1c913b 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 0961d0131d07c..255e661652db9 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 f1d62d03cbc98..ba3eeb91fe95f 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 94c149dd23e6f..8a4ed02f6aea1 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 a49a1554d5bfe..a6da4b0bab683 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 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 6da95053b116d..ed504938e8aa7 100644 --- a/compiler/rustc_index/src/interval.rs +++ b/compiler/rustc_index/src/interval.rs @@ -136,12 +136,9 @@ impl IntervalSet { 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 IntervalSet { 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 ef4c9c24f3eb9..2bc2f78261df3 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 625fd8642186d..8601180842ccc 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 4e50585ff524f..c7b4a96fb7853 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 89390ee1d6ccd..4af69f7cd2ee6 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 700710c82c9e0..139c6b3fcdd4d 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -422,10 +422,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option, 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 d2d853efda2d2..e9996a7ef14df 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 944a099642755..5078c240ec753 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 8afbd462c146b..35c7d885e1d74 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 2dd6dbd67a8d2..264a80339ccdb 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 fc88e8cd912ea..5cd3791583f9a 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 36a1798cd6a86..7343f1465f603 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, 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 c70a691452018..c4ee1e191286d 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 550b22a2a3c65..2204b44e3a10d 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 88292a4422419..0f10c269a04a3 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 7708b5193f450..ce61fd20a7b1e 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 75dd223d014d4..6124d14070266 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/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 784babffeff42..7894c7fec4405 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/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 41145d250173f..bb8566ea4df37 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, Bound) { 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 2ccfeba2b665d..5ceabf99eda96 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 6d4178c3e753f..4996a13bd8c6c 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 ae838a461574b..a111a695f3600 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 ce848773b10cc..da9c4b930df47 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, ) -> 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 fb403615e572f..f2f85043df292 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 ec2ff3c37ab73..72c0985a63c33 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 { - let rust_f = match num.parse::() { - Ok(f) => f, - Err(_) => return None, - }; + let Ok(rust_f) = num.parse::() else { return None }; let mut f = num.parse::().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 { - let rust_f = match num.parse::() { - Ok(f) => f, - Err(_) => return None, - }; + let Ok(rust_f) = num.parse::() else { return None }; let mut f = num.parse::().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 829dec74803dd..5a7e1d88dd03f 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 e4d9bd9c237e9..1d31516e2463c 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) { - 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)> + 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 ddf39fb824cda..0c1daa519ab7c 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 e2269562b3d9b..f102872cd2d06 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 e8a6d8dad439e..e20358ba9896d 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 34bc157a744a7..599b4087c78e4 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 5dc8a003b4778..63d935db8ca13 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 1abb64219f6e9..757dc09375584 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 9eaf2b6a21113..8de0aad041cc3 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 fd93744d40091..704f0901b9590 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 a5491f0ef4e2d..44753c5f631ca 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 7320b2738a76c..a4b1d86ff610e 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 05de52458add2..388bb7d34364a 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 f0e4129b002e8..3282000055def 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -109,9 +109,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 44ded1647fc28..de93ab7059f87 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 4c4497ad629da..684d988ee9ed2 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 c829774487308..43d1d62a21efb 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 797f7ee2685b8..ec25f298d48e0 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 1d912e6140989..785716ebecc28 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 b8feeb993e7c8..837295292b9ff 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 4651e1f4ed059..d8b58ce53f838 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 72c1b3fa6e98c..bd42505e3a354 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 ccd11f06bc582..c2a75d2bc2c64 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 { - 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 e9aa4adcaf79b..7cb8c35b868a5 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 93f5d79c0db13..20ca8a99ab7e6 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 d3e7d1690ccf6..227a9e37dbcb4 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 479a08e43c01a..3d69e8ba4e430 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 1031ba01c1b48..bd772d9975b3a 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`, 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 69cd1b4fed589..a959089ebb318 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 6cd9dc23285a9..adbfb4fcf01ca 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 136059677c5ae..a55198e6a9fb5 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 a8c2a5e1424b8..5e21161f2e06a 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 f9926a71c30ac..c63ca9289a20f 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 3bea95fa1d554..2f0ad60709dac 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 = 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 28d8d9247ac13..04b0a18b12b62 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 0ff56a30ea005..51f73ac2eb199 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 8b0adba9fab15..5d32063d50b2d 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 6a39854924122..7e08b18cf486f 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 b31fbab20ac92..bd257dc64646a 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 383250cd68f17..82a95faa3470a 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 c069144fa9f1c..547a3bed81b66 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -762,12 +762,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') { @@ -791,12 +788,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 dea2fbf04be59..5991b4d217c6e 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 7f1fd28b30df8..4ef863712983f 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::() { - Ok(bits) => bits, - Err(_) => { - size(&s[1..], "i")?; // For the user error. - continue; - } + let Ok(bits) = s[1..].parse::() 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 b18d17c1b7d1f..2919743e4996f 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 51b66e1bb6503..fee014ea7ef7d 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> for RustIrDatabase<'t ) -> Arc>> { 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 b814b984daeef..73fd95e98ca54 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 55e199907617c..702a9513b4402 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 e44f80d5ac3f2..20ae986ffa4ee 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, &[]),