From 0cd8694128262d3fed4744d9629151776a6c5813 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Mon, 28 Oct 2024 17:28:47 +0200 Subject: [PATCH 01/26] Impl TryFrom> for String --- library/alloc/src/string.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index b042720933b6d..565947db14587 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -3078,6 +3078,24 @@ impl From for Vec { } } +#[stable(feature = "try_from_vec_u8_for_string", since = "CURRENT_RUSTC_VERSION")] +impl TryFrom> for String { + type Error = FromUtf8Error; + /// Converts the given [`Vec`] into a [`String`] if it contains valid UTF-8 data. + /// + /// # Examples + /// + /// ``` + /// let s1 = b"hello world".to_vec(); + /// let v1 = String::try_from(s1).unwrap(); + /// assert_eq!(v1, "hello world"); + /// + /// ``` + fn try_from(bytes: Vec) -> Result { + Self::from_utf8(bytes) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Write for String { From 4c9b9d7258773d6d0aac6711ba350d9395120e32 Mon Sep 17 00:00:00 2001 From: Lukas Bergdoll Date: Sun, 3 Nov 2024 18:34:45 +0100 Subject: [PATCH 02/26] Use more explicit and reliable ptr select in sort impls Using if ... with the intent to avoid branches can be surprising to readers and carries the risk of turning into jumps/branches generated by some future compiler version, breaking crucial optimizations. This commit replaces their usage with the explicit and IR annotated `bool::select_unpredictable`. --- .../core/src/slice/sort/shared/smallsort.rs | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs index 09f898309bd65..f6dcf42ba6037 100644 --- a/library/core/src/slice/sort/shared/smallsort.rs +++ b/library/core/src/slice/sort/shared/smallsort.rs @@ -387,7 +387,7 @@ unsafe fn swap_if_less(v_base: *mut T, a_pos: usize, b_pos: usize, is_less where F: FnMut(&T, &T) -> bool, { - // SAFETY: the caller must guarantee that `a` and `b` each added to `v_base` yield valid + // SAFETY: the caller must guarantee that `a_pos` and `b_pos` each added to `v_base` yield valid // pointers into `v_base`, and are properly aligned, and part of the same allocation. unsafe { let v_a = v_base.add(a_pos); @@ -404,16 +404,16 @@ where // The equivalent code with a branch would be: // // if should_swap { - // ptr::swap(left, right, 1); + // ptr::swap(v_a, v_b, 1); // } // The goal is to generate cmov instructions here. - let left_swap = if should_swap { v_b } else { v_a }; - let right_swap = if should_swap { v_a } else { v_b }; + let v_a_swap = should_swap.select_unpredictable(v_b, v_a); + let v_b_swap = should_swap.select_unpredictable(v_a, v_b); - let right_swap_tmp = ManuallyDrop::new(ptr::read(right_swap)); - ptr::copy(left_swap, v_a, 1); - ptr::copy_nonoverlapping(&*right_swap_tmp, v_b, 1); + let v_b_swap_tmp = ManuallyDrop::new(ptr::read(v_b_swap)); + ptr::copy(v_a_swap, v_a, 1); + ptr::copy_nonoverlapping(&*v_b_swap_tmp, v_b, 1); } } @@ -640,26 +640,21 @@ pub unsafe fn sort4_stable bool>( // 1, 1 | c b a d let c3 = is_less(&*c, &*a); let c4 = is_less(&*d, &*b); - let min = select(c3, c, a); - let max = select(c4, b, d); - let unknown_left = select(c3, a, select(c4, c, b)); - let unknown_right = select(c4, d, select(c3, b, c)); + let min = c3.select_unpredictable(c, a); + let max = c4.select_unpredictable(b, d); + let unknown_left = c3.select_unpredictable(a, c4.select_unpredictable(c, b)); + let unknown_right = c4.select_unpredictable(d, c3.select_unpredictable(b, c)); // Sort the last two unknown elements. let c5 = is_less(&*unknown_right, &*unknown_left); - let lo = select(c5, unknown_right, unknown_left); - let hi = select(c5, unknown_left, unknown_right); + let lo = c5.select_unpredictable(unknown_right, unknown_left); + let hi = c5.select_unpredictable(unknown_left, unknown_right); ptr::copy_nonoverlapping(min, dst, 1); ptr::copy_nonoverlapping(lo, dst.add(1), 1); ptr::copy_nonoverlapping(hi, dst.add(2), 1); ptr::copy_nonoverlapping(max, dst.add(3), 1); } - - #[inline(always)] - fn select(cond: bool, if_true: *const T, if_false: *const T) -> *const T { - if cond { if_true } else { if_false } - } } /// SAFETY: The caller MUST guarantee that `v_base` is valid for 8 reads and From 5573cd320cd80f6ed9d44aa6129570380280f0fd Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 10 Feb 2025 12:16:27 +0000 Subject: [PATCH 03/26] Prevent /msys64/bin from being prepended to PATH --- src/ci/scripts/install-mingw.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index 91eab2e7a0816..c8c501e646a9d 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -32,6 +32,12 @@ if isWindows && isKnownToBeMingwBuild; then ;; esac + # Stop /msys64/bin from being prepended to PATH by adding the bin directory manually. + # Note that this intentionally uses a Windows style path instead of the msys2 path to + # avoid being auto-translated into `/usr/bin`, which will not have the desired effect. + msys2Path="c:/msys64" + ciCommandAddPath "${msys2Path}/usr/bin" + mingw_dir="mingw${bits}" curl -o mingw.7z "${MIRRORS_BASE}/${mingw_archive}" From ec8ec41d9ee8b03bbddf815217452e37656e2d0b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 10 Feb 2025 15:06:41 +0000 Subject: [PATCH 04/26] Print the environment a second time --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0934e42b277e4..c6f3fcada08e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -173,6 +173,11 @@ jobs: - name: ensure the stable version number is correct run: src/ci/scripts/verify-stable-version-number.sh + # Show the environment just before we run the build + # This makes it easier to diagnose problems with the above install scripts. + - name: show the current environment + run: src/ci/scripts/dump-environment.sh + - name: run the build # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. run: src/ci/scripts/run-build-from-ci.sh 2>&1 From f3515fb127ae07f1b13340dde0c61a20291eb304 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Feb 2025 10:35:32 +0100 Subject: [PATCH 05/26] Remove ignored `#[must_use]` attributes from portable-simd The `#[must_use]` attribute has no effect when applied to methods in trait implementations. --- library/portable-simd/crates/core_simd/src/masks.rs | 13 ------------- .../crates/core_simd/src/masks/full_masks.rs | 5 ----- library/portable-simd/crates/core_simd/src/ops.rs | 1 - .../portable-simd/crates/core_simd/src/ops/deref.rs | 3 --- .../portable-simd/crates/core_simd/src/ops/unary.rs | 2 -- .../crates/core_simd/src/simd/num/float.rs | 1 - 6 files changed, 25 deletions(-) diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index b763a7c75a5a6..19d45f4d3b31a 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -401,7 +401,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a defaulted mask with all elements set to false (0)"] fn default() -> Self { Self::splat(false) } @@ -413,7 +412,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] fn eq(&self, other: &Self) -> bool { self.0 == other.0 } @@ -425,7 +423,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new Ordering and does not mutate the original value"] fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } @@ -451,7 +448,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Self) -> Self { Self(self.0 & rhs.0) } @@ -464,7 +460,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: bool) -> Self { self & Self::splat(rhs) } @@ -477,7 +472,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Mask) -> Mask { Mask::splat(self) & rhs } @@ -490,7 +484,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Self) -> Self { Self(self.0 | rhs.0) } @@ -503,7 +496,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: bool) -> Self { self | Self::splat(rhs) } @@ -516,7 +508,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Mask) -> Mask { Mask::splat(self) | rhs } @@ -529,7 +520,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Self) -> Self::Output { Self(self.0 ^ rhs.0) } @@ -542,7 +532,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: bool) -> Self::Output { self ^ Self::splat(rhs) } @@ -555,7 +544,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Mask) -> Self::Output { Mask::splat(self) ^ rhs } @@ -568,7 +556,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(self) -> Self::Output { Self(!self.0) } diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs index 2d01946b5747c..387b508c4b4ef 100644 --- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs @@ -21,7 +21,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn clone(&self) -> Self { *self } @@ -252,7 +251,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_and(self.0, rhs.0)) } @@ -266,7 +264,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_or(self.0, rhs.0)) } @@ -280,7 +277,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_xor(self.0, rhs.0)) } @@ -294,7 +290,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(self) -> Self::Output { Self::splat(true) ^ self } diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs index d3bd14a340278..4ac64a253a3bd 100644 --- a/library/portable-simd/crates/core_simd/src/ops.rs +++ b/library/portable-simd/crates/core_simd/src/ops.rs @@ -135,7 +135,6 @@ macro_rules! for_base_types { type Output = $out; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] // TODO: only useful for int Div::div, but we hope that this // will essentially always get inlined anyway. #[track_caller] diff --git a/library/portable-simd/crates/core_simd/src/ops/deref.rs b/library/portable-simd/crates/core_simd/src/ops/deref.rs index 0ff76cfba39bb..913cbbe977c46 100644 --- a/library/portable-simd/crates/core_simd/src/ops/deref.rs +++ b/library/portable-simd/crates/core_simd/src/ops/deref.rs @@ -18,7 +18,6 @@ macro_rules! deref_lhs { type Output = Simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: $simd) -> Self::Output { (*self).$call(rhs) } @@ -39,7 +38,6 @@ macro_rules! deref_rhs { type Output = Simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: &$simd) -> Self::Output { self.$call(*rhs) } @@ -71,7 +69,6 @@ macro_rules! deref_ops { type Output = $simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: &'rhs $simd) -> Self::Output { (*self).$call(*rhs) } diff --git a/library/portable-simd/crates/core_simd/src/ops/unary.rs b/library/portable-simd/crates/core_simd/src/ops/unary.rs index bdae96332a3ae..412a5b801171b 100644 --- a/library/portable-simd/crates/core_simd/src/ops/unary.rs +++ b/library/portable-simd/crates/core_simd/src/ops/unary.rs @@ -11,7 +11,6 @@ macro_rules! neg { type Output = Self; #[inline] - #[must_use = "operator returns a new vector without mutating the input"] fn neg(self) -> Self::Output { // Safety: `self` is a signed vector unsafe { core::intrinsics::simd::simd_neg(self) } @@ -46,7 +45,6 @@ macro_rules! not { type Output = Self; #[inline] - #[must_use = "operator returns a new vector without mutating the input"] fn not(self) -> Self::Output { self ^ (Simd::splat(!(0 as $scalar))) } diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs index 79954b937b397..db705dfe20221 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs @@ -371,7 +371,6 @@ macro_rules! impl_trait { } #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn is_normal(self) -> Self::Mask { !(self.abs().simd_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite()) } From 3e66ba73d519a2b653cc2f6af01c03ce6ed94055 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Feb 2025 15:22:32 +0100 Subject: [PATCH 06/26] Remove ignored `#[must_use]` attributes from Clippy The `#[must_use]` attribute has no effect when applied to methods in trait implementations. --- src/tools/clippy/clippy_lints/src/infinite_iter.rs | 1 - src/tools/clippy/clippy_utils/src/consts.rs | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index d3aade31f14fc..7210f4b438db2 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -94,7 +94,6 @@ impl Finiteness { } impl From for Finiteness { - #[must_use] fn from(b: bool) -> Self { if b { Infinite } else { Finite } } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index db82c458f703c..21909896c33eb 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -351,21 +351,18 @@ pub enum FullInt { } impl PartialEq for FullInt { - #[must_use] fn eq(&self, other: &Self) -> bool { self.cmp(other) == Ordering::Equal } } impl PartialOrd for FullInt { - #[must_use] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for FullInt { - #[must_use] fn cmp(&self, other: &Self) -> Ordering { use FullInt::{S, U}; From eec49bbf59c922060a5785a47d885529e6cb2ac8 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Fri, 2 Feb 2024 20:49:20 +0800 Subject: [PATCH 07/26] add MAX_LEN_UTF8 and MAX_LEN_UTF16 constants --- library/alloc/src/lib.rs | 1 + library/alloc/src/string.rs | 8 +++++--- library/alloc/tests/lib.rs | 1 + library/alloc/tests/str.rs | 5 +++-- library/core/src/char/methods.rs | 10 ++++++++++ library/core/src/char/mod.rs | 10 ++++++++++ library/core/src/fmt/mod.rs | 6 +++--- library/core/src/str/pattern.rs | 5 +++-- library/coretests/tests/char.rs | 3 ++- library/coretests/tests/lib.rs | 1 + library/std/src/fs/tests.rs | 7 ++++--- library/std/src/lib.rs | 1 + library/std/src/sys/pal/windows/stdio.rs | 3 ++- library/std/src/sys_common/wtf8.rs | 6 +++--- 14 files changed, 49 insertions(+), 18 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 0bb7c432cc35f..2795fe5c769d9 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -105,6 +105,7 @@ #![feature(box_uninit_write)] #![feature(bstr)] #![feature(bstr_internals)] +#![feature(char_max_len)] #![feature(clone_to_uninit)] #![feature(coerce_unsized)] #![feature(const_eval_select)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index b29f740ef0f2a..37e9e05a6a1cc 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1419,7 +1419,9 @@ impl String { pub fn push(&mut self, ch: char) { match ch.len_utf8() { 1 => self.vec.push(ch as u8), - _ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()), + _ => { + self.vec.extend_from_slice(ch.encode_utf8(&mut [0; char::MAX_LEN_UTF8]).as_bytes()) + } } } @@ -1716,7 +1718,7 @@ impl String { #[rustc_confusables("set")] pub fn insert(&mut self, idx: usize, ch: char) { assert!(self.is_char_boundary(idx)); - let mut bits = [0; 4]; + let mut bits = [0; char::MAX_LEN_UTF8]; let bits = ch.encode_utf8(&mut bits).as_bytes(); unsafe { @@ -2771,7 +2773,7 @@ impl SpecToString for core::ascii::Char { impl SpecToString for char { #[inline] fn spec_to_string(&self) -> String { - String::from(self.encode_utf8(&mut [0; 4])) + String::from(self.encode_utf8(&mut [0; char::MAX_LEN_UTF8])) } } diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 391ff04a4b8e4..708dfc582a7eb 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -3,6 +3,7 @@ #![feature(iter_array_chunks)] #![feature(assert_matches)] #![feature(btree_extract_if)] +#![feature(char_max_len)] #![feature(cow_is_borrowed)] #![feature(core_intrinsics)] #![feature(downcast_unchecked)] diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index 6f930ab08535c..aeb0e681c226f 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -2,6 +2,7 @@ use std::assert_matches::assert_matches; use std::borrow::Cow; +use std::char::MAX_LEN_UTF8; use std::cmp::Ordering::{Equal, Greater, Less}; use std::str::{from_utf8, from_utf8_unchecked}; @@ -1231,7 +1232,7 @@ fn test_to_uppercase_rev_iterator() { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_chars_decoding() { - let mut bytes = [0; 4]; + let mut bytes = [0; MAX_LEN_UTF8]; for c in (0..0x110000).filter_map(std::char::from_u32) { let s = c.encode_utf8(&mut bytes); if Some(c) != s.chars().next() { @@ -1243,7 +1244,7 @@ fn test_chars_decoding() { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_chars_rev_decoding() { - let mut bytes = [0; 4]; + let mut bytes = [0; MAX_LEN_UTF8]; for c in (0..0x110000).filter_map(std::char::from_u32) { let s = c.encode_utf8(&mut bytes); if Some(c) != s.chars().rev().next() { diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index ccfdbf0eb704d..40137ea44ddce 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -71,6 +71,16 @@ impl char { #[stable(feature = "assoc_char_consts", since = "1.52.0")] pub const MAX: char = '\u{10FFFF}'; + /// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to + /// UTF-8 encoding. + #[unstable(feature = "char_max_len", issue = "121714")] + pub const MAX_LEN_UTF8: usize = 4; + + /// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char` + /// to UTF-16 encoding. + #[unstable(feature = "char_max_len", issue = "121714")] + pub const MAX_LEN_UTF16: usize = 2; + /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a /// decoding error. /// diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 59fd7250e8f8e..088c709f1a2af 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -95,6 +95,16 @@ const MAX_THREE_B: u32 = 0x10000; #[stable(feature = "rust1", since = "1.0.0")] pub const MAX: char = char::MAX; +/// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to +/// UTF-8 encoding. +#[unstable(feature = "char_max_len", issue = "121714")] +pub const MAX_LEN_UTF8: usize = char::MAX_LEN_UTF8; + +/// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char` +/// to UTF-16 encoding. +#[unstable(feature = "char_max_len", issue = "121714")] +pub const MAX_LEN_UTF16: usize = char::MAX_LEN_UTF16; + /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a /// decoding error. Use [`char::REPLACEMENT_CHARACTER`] instead. #[stable(feature = "decode_utf16", since = "1.9.0")] diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index a1bf3a4d7a706..764e7fff33ec7 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -3,7 +3,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell}; -use crate::char::EscapeDebugExtArgs; +use crate::char::{EscapeDebugExtArgs, MAX_LEN_UTF8}; use crate::marker::PhantomData; use crate::num::fmt as numfmt; use crate::ops::Deref; @@ -187,7 +187,7 @@ pub trait Write { /// ``` #[stable(feature = "fmt_write_char", since = "1.1.0")] fn write_char(&mut self, c: char) -> Result { - self.write_str(c.encode_utf8(&mut [0; 4])) + self.write_str(c.encode_utf8(&mut [0; MAX_LEN_UTF8])) } /// Glue for usage of the [`write!`] macro with implementors of this trait. @@ -2768,7 +2768,7 @@ impl Display for char { if f.options.width.is_none() && f.options.precision.is_none() { f.write_char(*self) } else { - f.pad(self.encode_utf8(&mut [0; 4])) + f.pad(self.encode_utf8(&mut [0; MAX_LEN_UTF8])) } } } diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index 52e2364893eb1..2d941adfd859c 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -38,6 +38,7 @@ issue = "27721" )] +use crate::char::MAX_LEN_UTF8; use crate::cmp::Ordering; use crate::convert::TryInto as _; use crate::slice::memchr; @@ -561,8 +562,8 @@ impl Pattern for char { type Searcher<'a> = CharSearcher<'a>; #[inline] - fn into_searcher(self, haystack: &str) -> Self::Searcher<'_> { - let mut utf8_encoded = [0; 4]; + fn into_searcher<'a>(self, haystack: &'a str) -> Self::Searcher<'a> { + let mut utf8_encoded = [0; MAX_LEN_UTF8]; let utf8_size = self .encode_utf8(&mut utf8_encoded) .len() diff --git a/library/coretests/tests/char.rs b/library/coretests/tests/char.rs index 6422387e9560b..153fb36925e66 100644 --- a/library/coretests/tests/char.rs +++ b/library/coretests/tests/char.rs @@ -1,3 +1,4 @@ +use std::char::MAX_LEN_UTF8; use std::str::FromStr; use std::{char, str}; @@ -259,7 +260,7 @@ fn test_escape_unicode() { #[test] fn test_encode_utf8() { fn check(input: char, expect: &[u8]) { - let mut buf = [0; 4]; + let mut buf = [0; MAX_LEN_UTF8]; let ptr = buf.as_ptr(); let s = input.encode_utf8(&mut buf); assert_eq!(s.as_ptr() as usize, ptr as usize); diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 7fe7286260858..adceeb101ff35 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -13,6 +13,7 @@ #![feature(bigint_helper_methods)] #![feature(bstr)] #![feature(cell_update)] +#![feature(char_max_len)] #![feature(clone_to_uninit)] #![feature(const_eval_select)] #![feature(const_swap_nonoverlapping)] diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 28f16da1ed8d2..3e26e7007144a 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1,5 +1,6 @@ use rand::RngCore; +use crate::char::MAX_LEN_UTF8; use crate::fs::{self, File, FileTimes, OpenOptions}; use crate::io::prelude::*; use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; @@ -155,7 +156,7 @@ fn file_test_io_non_positional_read() { #[test] fn file_test_io_seek_and_tell_smoke_test() { let message = "ten-four"; - let mut read_mem = [0; 4]; + let mut read_mem = [0; MAX_LEN_UTF8]; let set_cursor = 4 as u64; let tell_pos_pre_read; let tell_pos_post_read; @@ -356,7 +357,7 @@ fn file_test_io_seek_shakedown() { let chunk_one: &str = "qwer"; let chunk_two: &str = "asdf"; let chunk_three: &str = "zxcv"; - let mut read_mem = [0; 4]; + let mut read_mem = [0; MAX_LEN_UTF8]; let tmpdir = tmpdir(); let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt"); { @@ -621,7 +622,7 @@ fn file_test_directoryinfo_readdir() { check!(w.write(msg)); } let files = check!(fs::read_dir(dir)); - let mut mem = [0; 4]; + let mut mem = [0; MAX_LEN_UTF8]; for f in files { let f = f.unwrap().path(); { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index acb3a0578e505..f75c56d4fa510 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -281,6 +281,7 @@ #![feature(cfg_sanitizer_cfi)] #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] +#![feature(char_max_len)] #![feature(concat_idents)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index fd3f559ba1901..1b245991aa797 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -1,5 +1,6 @@ #![unstable(issue = "none", feature = "windows_stdio")] +use core::char::MAX_LEN_UTF8; use core::str::utf8_char_width; use super::api::{self, WinError}; @@ -426,7 +427,7 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result { impl IncompleteUtf8 { pub const fn new() -> IncompleteUtf8 { - IncompleteUtf8 { bytes: [0; 4], len: 0 } + IncompleteUtf8 { bytes: [0; MAX_LEN_UTF8], len: 0 } } } diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 6c60d901ee904..a7704a65fc9f5 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -18,7 +18,7 @@ #[cfg(test)] mod tests; -use core::char::{encode_utf8_raw, encode_utf16_raw}; +use core::char::{MAX_LEN_UTF8, MAX_LEN_UTF16, encode_utf8_raw, encode_utf16_raw}; use core::clone::CloneToUninit; use core::str::next_code_point; @@ -240,7 +240,7 @@ impl Wtf8Buf { /// Copied from String::push /// This does **not** include the WTF-8 concatenation check or `is_known_utf8` check. fn push_code_point_unchecked(&mut self, code_point: CodePoint) { - let mut bytes = [0; 4]; + let mut bytes = [0; MAX_LEN_UTF8]; let bytes = encode_utf8_raw(code_point.value, &mut bytes); self.bytes.extend_from_slice(bytes) } @@ -1001,7 +1001,7 @@ impl<'a> Iterator for EncodeWide<'a> { return Some(tmp); } - let mut buf = [0; 2]; + let mut buf = [0; MAX_LEN_UTF16]; self.code_points.next().map(|code_point| { let n = encode_utf16_raw(code_point.value, &mut buf).len(); if n == 2 { From 09dc38f23b4aa759d65d2fb940781f080445f685 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Wed, 5 Feb 2025 14:03:50 -0800 Subject: [PATCH 08/26] Improve WTF-8 comments --- library/std/src/sys_common/wtf8.rs | 38 ++++++++++++++++++------------ 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 6c60d901ee904..0d327189d1235 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -156,9 +156,12 @@ impl ops::DerefMut for Wtf8Buf { } } -/// Format the string with double quotes, -/// and surrogates as `\u` followed by four hexadecimal digits. -/// Example: `"a\u{D800}"` for a string with code points [U+0061, U+D800] +/// Formats the string in double quotes, with characters escaped according to +/// [`char::escape_debug`] and unpaired surrogates represented as `\u{xxxx}`, +/// where each `x` is a hexadecimal digit. +/// +/// For example, the code units [U+0061, U+D800, U+000A] are formatted as +/// `"a\u{D800}\n"`. impl fmt::Debug for Wtf8Buf { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -181,7 +184,7 @@ impl Wtf8Buf { /// Creates a WTF-8 string from a WTF-8 byte vec. /// - /// Since the byte vec is not checked for valid WTF-8, this functions is + /// Since the byte vec is not checked for valid WTF-8, this function is /// marked unsafe. #[inline] pub unsafe fn from_bytes_unchecked(value: Vec) -> Wtf8Buf { @@ -237,8 +240,9 @@ impl Wtf8Buf { string } - /// Copied from String::push + /// Appends the given `char` to the end of this string. /// This does **not** include the WTF-8 concatenation check or `is_known_utf8` check. + /// Copied from String::push. fn push_code_point_unchecked(&mut self, code_point: CodePoint) { let mut bytes = [0; 4]; let bytes = encode_utf8_raw(code_point.value, &mut bytes); @@ -264,16 +268,16 @@ impl Wtf8Buf { /// /// # Panics /// - /// Panics if the new capacity overflows `usize`. + /// Panics if the new capacity exceeds `isize::MAX` bytes. #[inline] pub fn reserve(&mut self, additional: usize) { self.bytes.reserve(additional) } - /// Tries to reserve capacity for at least `additional` more length units - /// in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to avoid - /// frequent reallocations. After calling `try_reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if + /// Tries to reserve capacity for at least `additional` more bytes to be + /// inserted in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to + /// avoid frequent reallocations. After calling `try_reserve`, capacity will + /// be greater than or equal to `self.len() + additional`. Does nothing if /// capacity is already sufficient. This method preserves the contents even /// if an error occurs. /// @@ -291,8 +295,8 @@ impl Wtf8Buf { self.bytes.reserve_exact(additional) } - /// Tries to reserve the minimum capacity for exactly `additional` - /// length units in the given `Wtf8Buf`. After calling + /// Tries to reserve the minimum capacity for exactly `additional` more + /// bytes to be inserted in the given `Wtf8Buf`. After calling /// `try_reserve_exact`, capacity will be greater than or equal to /// `self.len() + additional` if it returns `Ok(())`. /// Does nothing if the capacity is already sufficient. @@ -450,6 +454,8 @@ impl Wtf8Buf { match self.next_surrogate(pos) { Some((surrogate_pos, _)) => { pos = surrogate_pos + 3; + // Surrogates and the replacement character are all 3 bytes, + // so they can substituted in-place. self.bytes[surrogate_pos..pos] .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes()); } @@ -535,9 +541,9 @@ impl AsInner<[u8]> for Wtf8 { } } -/// Format the slice with double quotes, -/// and surrogates as `\u` followed by four hexadecimal digits. -/// Example: `"a\u{D800}"` for a slice with code points [U+0061, U+D800] +/// Formats the string in double quotes, with characters escaped according to +/// [`char::escape_debug`] and unpaired surrogates represented as `\u{xxxx}`, +/// where each `x` is a hexadecimal digit. impl fmt::Debug for Wtf8 { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { fn write_str_escaped(f: &mut fmt::Formatter<'_>, s: &str) -> fmt::Result { @@ -562,6 +568,8 @@ impl fmt::Debug for Wtf8 { } } +/// Formats the string with unpaired surrogates substituted with the replacement +/// character, U+FFFD. impl fmt::Display for Wtf8 { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { let wtf8_bytes = &self.bytes; From 8b1a3a26c7b9db36f8ff6940ecc8e679c659d275 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Wed, 5 Feb 2025 22:46:27 -0800 Subject: [PATCH 09/26] Simplify control flow with while-let --- library/std/src/sys_common/wtf8.rs | 36 ++++++++++++------------------ 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 0d327189d1235..f4402fc6f9865 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -208,7 +208,7 @@ impl Wtf8Buf { /// Since WTF-8 is a superset of UTF-8, this always succeeds. #[inline] pub fn from_str(s: &str) -> Wtf8Buf { - Wtf8Buf { bytes: <[_]>::to_vec(s.as_bytes()), is_known_utf8: true } + Wtf8Buf { bytes: s.as_bytes().to_vec(), is_known_utf8: true } } pub fn clear(&mut self) { @@ -444,24 +444,17 @@ impl Wtf8Buf { /// /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”) pub fn into_string_lossy(mut self) -> String { - // Fast path: If we already have UTF-8, we can return it immediately. - if self.is_known_utf8 { - return unsafe { String::from_utf8_unchecked(self.bytes) }; - } - - let mut pos = 0; - loop { - match self.next_surrogate(pos) { - Some((surrogate_pos, _)) => { - pos = surrogate_pos + 3; - // Surrogates and the replacement character are all 3 bytes, - // so they can substituted in-place. - self.bytes[surrogate_pos..pos] - .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes()); - } - None => return unsafe { String::from_utf8_unchecked(self.bytes) }, + if !self.is_known_utf8 { + let mut pos = 0; + while let Some((surrogate_pos, _)) = self.next_surrogate(pos) { + pos = surrogate_pos + 3; + // Surrogates and the replacement character are all 3 bytes, so + // they can substituted in-place. + self.bytes[surrogate_pos..pos] + .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes()); } } + unsafe { String::from_utf8_unchecked(self.bytes) } } /// Converts this `Wtf8Buf` into a boxed `Wtf8`. @@ -680,9 +673,8 @@ impl Wtf8 { /// /// This only copies the data if necessary (if it contains any surrogate). pub fn to_string_lossy(&self) -> Cow<'_, str> { - let surrogate_pos = match self.next_surrogate(0) { - None => return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }), - Some((pos, _)) => pos, + let Some((surrogate_pos, _)) = self.next_surrogate(0) else { + return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }); }; let wtf8_bytes = &self.bytes; let mut utf8_bytes = Vec::with_capacity(self.len()); @@ -972,7 +964,7 @@ pub struct Wtf8CodePoints<'a> { bytes: slice::Iter<'a, u8>, } -impl<'a> Iterator for Wtf8CodePoints<'a> { +impl Iterator for Wtf8CodePoints<'_> { type Item = CodePoint; #[inline] @@ -998,7 +990,7 @@ pub struct EncodeWide<'a> { // Copied from libunicode/u_str.rs #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> Iterator for EncodeWide<'a> { +impl Iterator for EncodeWide<'_> { type Item = u16; #[inline] From 05e4175d79a7e8f2fc11c3d2ae70bb31a354f130 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Thu, 6 Feb 2025 15:36:42 -0800 Subject: [PATCH 10/26] Synchronize platform adaptors for OsString/OsStr * Order items as the average of the two adaptors. Enables easier diffs. * Consistently apply #[inline]. * Implement FromInner> for bytes::Buf. * Implement Clone::clone_from for wtf8::Buf. --- library/std/src/sys/os_str/bytes.rs | 86 ++++++++++++---------- library/std/src/sys/os_str/wtf8.rs | 107 ++++++++++++++++++---------- 2 files changed, 119 insertions(+), 74 deletions(-) diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 5b65d862be102..1d337694944bc 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -8,7 +8,7 @@ use crate::collections::TryReserveError; use crate::fmt::Write; use crate::rc::Rc; use crate::sync::Arc; -use crate::sys_common::{AsInner, IntoInner}; +use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::{fmt, mem, str}; #[cfg(test)] @@ -25,6 +25,37 @@ pub struct Slice { pub inner: [u8], } +impl IntoInner> for Buf { + fn into_inner(self) -> Vec { + self.inner + } +} + +impl FromInner> for Buf { + fn from_inner(inner: Vec) -> Self { + Buf { inner } + } +} + +impl AsInner<[u8]> for Buf { + #[inline] + fn as_inner(&self) -> &[u8] { + &self.inner + } +} + +impl fmt::Debug for Buf { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), f) + } +} + +impl fmt::Display for Buf { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), f) + } +} + impl fmt::Debug for Slice { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f) @@ -55,18 +86,6 @@ impl fmt::Display for Slice { } } -impl fmt::Debug for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_slice(), formatter) - } -} - -impl fmt::Display for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.as_slice(), formatter) - } -} - impl Clone for Buf { #[inline] fn clone(&self) -> Self { @@ -79,19 +98,6 @@ impl Clone for Buf { } } -impl IntoInner> for Buf { - fn into_inner(self) -> Vec { - self.inner - } -} - -impl AsInner<[u8]> for Buf { - #[inline] - fn as_inner(&self) -> &[u8] { - &self.inner - } -} - impl Buf { #[inline] pub fn into_encoded_bytes(self) -> Vec { @@ -103,6 +109,12 @@ impl Buf { Self { inner: s } } + #[inline] + pub fn into_string(self) -> Result { + String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() }) + } + + #[inline] pub fn from_string(s: String) -> Buf { Buf { inner: s.into_bytes() } } @@ -122,6 +134,11 @@ impl Buf { self.inner.capacity() } + #[inline] + pub fn push_slice(&mut self, s: &Slice) { + self.inner.extend_from_slice(&s.inner) + } + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) @@ -157,7 +174,7 @@ impl Buf { // SAFETY: Slice just wraps [u8], // and &*self.inner is &[u8], therefore // transmuting &[u8] to &Slice is safe. - unsafe { mem::transmute(&*self.inner) } + unsafe { mem::transmute(self.inner.as_slice()) } } #[inline] @@ -165,15 +182,7 @@ impl Buf { // SAFETY: Slice just wraps [u8], // and &mut *self.inner is &mut [u8], therefore // transmuting &mut [u8] to &mut Slice is safe. - unsafe { mem::transmute(&mut *self.inner) } - } - - pub fn into_string(self) -> Result { - String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() }) - } - - pub fn push_slice(&mut self, s: &Slice) { - self.inner.extend_from_slice(&s.inner) + unsafe { mem::transmute(self.inner.as_mut_slice()) } } #[inline] @@ -278,18 +287,22 @@ impl Slice { unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) } } + #[inline] pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { str::from_utf8(&self.inner) } + #[inline] pub fn to_string_lossy(&self) -> Cow<'_, str> { String::from_utf8_lossy(&self.inner) } + #[inline] pub fn to_owned(&self) -> Buf { Buf { inner: self.inner.to_vec() } } + #[inline] pub fn clone_into(&self, buf: &mut Buf) { self.inner.clone_into(&mut buf.inner) } @@ -300,6 +313,7 @@ impl Slice { unsafe { mem::transmute(boxed) } } + #[inline] pub fn empty_box() -> Box { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index a4ad5966afe57..19728d33990ac 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -10,11 +10,16 @@ use crate::sys_common::wtf8::{Wtf8, Wtf8Buf, check_utf8_boundary}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::{fmt, mem}; -#[derive(Clone, Hash)] +#[derive(Hash)] pub struct Buf { pub inner: Wtf8Buf, } +#[repr(transparent)] +pub struct Slice { + pub inner: Wtf8, +} + impl IntoInner for Buf { fn into_inner(self) -> Wtf8Buf { self.inner @@ -35,31 +40,38 @@ impl AsInner for Buf { } impl fmt::Debug for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_slice(), formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), f) } } impl fmt::Display for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.as_slice(), formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), f) } } -#[repr(transparent)] -pub struct Slice { - pub inner: Wtf8, -} - impl fmt::Debug for Slice { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.inner, formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.inner, f) } } impl fmt::Display for Slice { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.inner, formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.inner, f) + } +} + +impl Clone for Buf { + #[inline] + fn clone(&self) -> Self { + Buf { inner: self.inner.clone() } + } + + #[inline] + fn clone_from(&mut self, source: &Self) { + self.inner.clone_from(&source.inner) } } @@ -74,62 +86,57 @@ impl Buf { unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } } } - pub fn with_capacity(capacity: usize) -> Buf { - Buf { inner: Wtf8Buf::with_capacity(capacity) } - } - - pub fn clear(&mut self) { - self.inner.clear() - } - - pub fn capacity(&self) -> usize { - self.inner.capacity() + #[inline] + pub fn into_string(self) -> Result { + self.inner.into_string().map_err(|buf| Buf { inner: buf }) } + #[inline] pub fn from_string(s: String) -> Buf { Buf { inner: Wtf8Buf::from_string(s) } } - pub fn as_slice(&self) -> &Slice { - // SAFETY: Slice is just a wrapper for Wtf8, - // and self.inner.as_slice() returns &Wtf8. - // Therefore, transmuting &Wtf8 to &Slice is safe. - unsafe { mem::transmute(self.inner.as_slice()) } + #[inline] + pub fn with_capacity(capacity: usize) -> Buf { + Buf { inner: Wtf8Buf::with_capacity(capacity) } } - pub fn as_mut_slice(&mut self) -> &mut Slice { - // SAFETY: Slice is just a wrapper for Wtf8, - // and self.inner.as_mut_slice() returns &mut Wtf8. - // Therefore, transmuting &mut Wtf8 to &mut Slice is safe. - // Additionally, care should be taken to ensure the slice - // is always valid Wtf8. - unsafe { mem::transmute(self.inner.as_mut_slice()) } + #[inline] + pub fn clear(&mut self) { + self.inner.clear() } - pub fn into_string(self) -> Result { - self.inner.into_string().map_err(|buf| Buf { inner: buf }) + #[inline] + pub fn capacity(&self) -> usize { + self.inner.capacity() } + #[inline] pub fn push_slice(&mut self, s: &Slice) { self.inner.push_wtf8(&s.inner) } + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) } + #[inline] pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { self.inner.try_reserve(additional) } + #[inline] pub fn reserve_exact(&mut self, additional: usize) { self.inner.reserve_exact(additional) } + #[inline] pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { self.inner.try_reserve_exact(additional) } + #[inline] pub fn shrink_to_fit(&mut self) { self.inner.shrink_to_fit() } @@ -139,6 +146,24 @@ impl Buf { self.inner.shrink_to(min_capacity) } + #[inline] + pub fn as_slice(&self) -> &Slice { + // SAFETY: Slice is just a wrapper for Wtf8, + // and self.inner.as_slice() returns &Wtf8. + // Therefore, transmuting &Wtf8 to &Slice is safe. + unsafe { mem::transmute(self.inner.as_slice()) } + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut Slice { + // SAFETY: Slice is just a wrapper for Wtf8, + // and self.inner.as_mut_slice() returns &mut Wtf8. + // Therefore, transmuting &mut Wtf8 to &mut Slice is safe. + // Additionally, care should be taken to ensure the slice + // is always valid Wtf8. + unsafe { mem::transmute(self.inner.as_mut_slice()) } + } + #[inline] pub fn leak<'a>(self) -> &'a mut Slice { unsafe { mem::transmute(self.inner.leak()) } @@ -194,6 +219,7 @@ impl Slice { } #[track_caller] + #[inline] pub fn check_public_boundary(&self, index: usize) { check_utf8_boundary(&self.inner, index); } @@ -203,18 +229,22 @@ impl Slice { unsafe { mem::transmute(Wtf8::from_str(s)) } } + #[inline] pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { self.inner.as_str() } + #[inline] pub fn to_string_lossy(&self) -> Cow<'_, str> { self.inner.to_string_lossy() } + #[inline] pub fn to_owned(&self) -> Buf { Buf { inner: self.inner.to_owned() } } + #[inline] pub fn clone_into(&self, buf: &mut Buf) { self.inner.clone_into(&mut buf.inner) } @@ -224,6 +254,7 @@ impl Slice { unsafe { mem::transmute(self.inner.into_box()) } } + #[inline] pub fn empty_box() -> Box { unsafe { mem::transmute(Wtf8::empty_box()) } } From fe37adab4b378d68eda8a8893339606d7f381465 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Thu, 30 Jan 2025 16:28:00 -0600 Subject: [PATCH 11/26] Suggest using :: instead of . in more cases. When `Foo.field` or `Foo.method()` exprs are encountered, suggest `Foo::field` or `Foo::method()` when Foo is a type alias, not just a struct, trait, or module. Also rename test for this suggestion from issue-22692.rs to something more meaningful. --- .../rustc_resolve/src/late/diagnostics.rs | 16 +++--- src/tools/tidy/src/issues.txt | 1 - ...tation-type-namespace-suggest-path-sep.rs} | 20 ++++++++ ...on-type-namespace-suggest-path-sep.stderr} | 51 +++++++++++++++---- 4 files changed, 69 insertions(+), 19 deletions(-) rename tests/ui/resolve/{issue-22692.rs => dot-notation-type-namespace-suggest-path-sep.rs} (77%) rename tests/ui/resolve/{issue-22692.stderr => dot-notation-type-namespace-suggest-path-sep.stderr} (68%) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0962865e7f190..524915b44e789 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1566,7 +1566,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } }; - let mut bad_struct_syntax_suggestion = |this: &mut Self, def_id: DefId| { + let bad_struct_syntax_suggestion = |this: &mut Self, err: &mut Diag<'_>, def_id: DefId| { let (followed_by_brace, closing_brace) = this.followed_by_brace(span); match source { @@ -1740,12 +1740,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } ( - Res::Def(kind @ (DefKind::Mod | DefKind::Trait), _), + Res::Def(kind @ (DefKind::Mod | DefKind::Trait | DefKind::TyAlias), _), PathSource::Expr(Some(parent)), - ) => { - if !path_sep(self, err, parent, kind) { - return false; - } + ) if path_sep(self, err, parent, kind) => { + return true; } ( Res::Def(DefKind::Enum, def_id), @@ -1777,13 +1775,13 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let (ctor_def, ctor_vis, fields) = if let Some(struct_ctor) = struct_ctor { if let PathSource::Expr(Some(parent)) = source { if let ExprKind::Field(..) | ExprKind::MethodCall(..) = parent.kind { - bad_struct_syntax_suggestion(self, def_id); + bad_struct_syntax_suggestion(self, err, def_id); return true; } } struct_ctor } else { - bad_struct_syntax_suggestion(self, def_id); + bad_struct_syntax_suggestion(self, err, def_id); return true; }; @@ -1861,7 +1859,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.span_label(span, "constructor is not visible here due to private fields"); } (Res::Def(DefKind::Union | DefKind::Variant, def_id), _) if ns == ValueNS => { - bad_struct_syntax_suggestion(self, def_id); + bad_struct_syntax_suggestion(self, err, def_id); } (Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id), _) if ns == ValueNS => { match source { diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 39c9a148e9e56..1cb47353469fa 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -3619,7 +3619,6 @@ ui/resolve/issue-21221-1.rs ui/resolve/issue-21221-2.rs ui/resolve/issue-21221-3.rs ui/resolve/issue-21221-4.rs -ui/resolve/issue-22692.rs ui/resolve/issue-2330.rs ui/resolve/issue-23305.rs ui/resolve/issue-2356.rs diff --git a/tests/ui/resolve/issue-22692.rs b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs similarity index 77% rename from tests/ui/resolve/issue-22692.rs rename to tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs index 31a76261408ef..104d11f685cc9 100644 --- a/tests/ui/resolve/issue-22692.rs +++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs @@ -1,3 +1,11 @@ +// see also https://github.com/rust-lang/rust/issues/22692 + +type Alias = Vec; + +mod foo { + fn bar() {} +} + fn main() { let _ = String.new(); //~^ ERROR expected value, found struct `String` @@ -10,6 +18,18 @@ fn main() { let _ = Vec::<()>.with_capacity(1); //~^ ERROR expected value, found struct `Vec` //~| HELP use the path separator + + let _ = Alias.new(); + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + + let _ = Alias.default; + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + + let _ = foo.bar; + //~^ ERROR expected value, found module `foo` + //~| HELP use the path separator } macro_rules! Type { diff --git a/tests/ui/resolve/issue-22692.stderr b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr similarity index 68% rename from tests/ui/resolve/issue-22692.stderr rename to tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr index 546f12b35c156..a5397306b01e4 100644 --- a/tests/ui/resolve/issue-22692.stderr +++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr @@ -1,5 +1,5 @@ error[E0423]: expected value, found struct `String` - --> $DIR/issue-22692.rs:2:13 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:10:13 | LL | let _ = String.new(); | ^^^^^^ @@ -11,7 +11,7 @@ LL + let _ = String::new(); | error[E0423]: expected value, found struct `String` - --> $DIR/issue-22692.rs:6:13 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:14:13 | LL | let _ = String.default; | ^^^^^^ @@ -23,7 +23,7 @@ LL + let _ = String::default; | error[E0423]: expected value, found struct `Vec` - --> $DIR/issue-22692.rs:10:13 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:18:13 | LL | let _ = Vec::<()>.with_capacity(1); | ^^^^^^^^^ @@ -34,8 +34,41 @@ LL - let _ = Vec::<()>.with_capacity(1); LL + let _ = Vec::<()>::with_capacity(1); | +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:22:13 + | +LL | let _ = Alias.new(); + | ^^^^^ + | +help: use the path separator to refer to an item + | +LL | let _ = Alias::new(); + | ~~ + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:26:13 + | +LL | let _ = Alias.default; + | ^^^^^ + | +help: use the path separator to refer to an item + | +LL | let _ = Alias::default; + | ~~ + +error[E0423]: expected value, found module `foo` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:30:13 + | +LL | let _ = foo.bar; + | ^^^ + | +help: use the path separator to refer to an item + | +LL | let _ = foo::bar; + | ~~ + error[E0423]: expected value, found struct `std::cell::Cell` - --> $DIR/issue-22692.rs:17:9 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9 | LL | ::std::cell::Cell | ^^^^^^^^^^^^^^^^^ @@ -51,7 +84,7 @@ LL + ::get(); | error[E0423]: expected value, found struct `std::cell::Cell` - --> $DIR/issue-22692.rs:17:9 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9 | LL | ::std::cell::Cell | ^^^^^^^^^^^^^^^^^ @@ -67,7 +100,7 @@ LL + ::get; | error[E0423]: expected value, found struct `Vec` - --> $DIR/issue-22692.rs:26:9 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:46:9 | LL | Vec.new() | ^^^ @@ -83,7 +116,7 @@ LL + Vec::new() | error[E0423]: expected value, found struct `Vec` - --> $DIR/issue-22692.rs:31:9 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:51:9 | LL | Vec.new | ^^^ @@ -99,7 +132,7 @@ LL + Vec::new | error[E0423]: expected value, found struct `std::cell::Cell` - --> $DIR/issue-22692.rs:17:9 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9 | LL | ::std::cell::Cell | ^^^^^^^^^^^^^^^^^ @@ -114,6 +147,6 @@ LL - Type!().new(0) LL + ::new(0) | -error: aborting due to 8 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0423`. From bfde43c84bfb35fd0d7c7ea46f8cdb0d682ef680 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Thu, 30 Jan 2025 20:45:30 -0600 Subject: [PATCH 12/26] Suggest using :: instead of . for enums in some cases. Suggest replacing `.` with `::` when encountering "expected value, found enum": - in a method-call expression and the method has the same name as a tuple variant - in a field-access expression and the field has the same name as a unit or tuple variant --- .../rustc_resolve/src/late/diagnostics.rs | 70 ++++-- .../enum-expected-value-suggest-variants.rs | 58 +++++ ...num-expected-value-suggest-variants.stderr | 225 ++++++++++++++++++ 3 files changed, 339 insertions(+), 14 deletions(-) create mode 100644 tests/ui/resolve/enum-expected-value-suggest-variants.rs create mode 100644 tests/ui/resolve/enum-expected-value-suggest-variants.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 524915b44e789..2731efdba48bd 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -8,7 +8,7 @@ use rustc_ast::ptr::P; use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt, Visitor, walk_ty}; use rustc_ast::{ self as ast, AssocItemKind, DUMMY_NODE_ID, Expr, ExprKind, GenericParam, GenericParamKind, - Item, ItemKind, MethodCall, NodeId, Path, Ty, TyKind, + Item, ItemKind, MethodCall, NodeId, Path, PathSegment, Ty, TyKind, }; use rustc_ast_pretty::pprust::where_bound_predicate_to_string; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; @@ -2469,31 +2469,73 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { def_id: DefId, span: Span, ) { - let Some(variants) = self.collect_enum_ctors(def_id) else { + let Some(variant_ctors) = 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 = - matches!(source, PathSource::TupleStruct(..)) || source.is_call(); - if suggest_only_tuple_variants { + // If the expression is a field-access or method-call, try to find a variant with the field/method name + // that could have been intended, and suggest replacing the `.` with `::`. + // Otherwise, suggest adding `::VariantName` after the enum; + // and if the expression is call-like, only suggest tuple variants. + let (suggest_path_sep_dot_span, suggest_only_tuple_variants) = match source { + // `Type(a, b)` in a pattern, only suggest adding a tuple variant after `Type`. + PathSource::TupleStruct(..) => (None, true), + PathSource::Expr(Some(expr)) => match &expr.kind { + // `Type(a, b)`, only suggest adding a tuple variant after `Type`. + ExprKind::Call(..) => (None, true), + // `Type.Foo(a, b)`, suggest replacing `.` -> `::` if variant `Foo` exists and is a tuple variant, + // otherwise suggest adding a variant after `Type`. + ExprKind::MethodCall(box MethodCall { + receiver, + span, + seg: PathSegment { ident, .. }, + .. + }) => { + let dot_span = receiver.span.between(*span); + let found_tuple_variant = variant_ctors.iter().any(|(path, _, ctor_kind)| { + *ctor_kind == CtorKind::Fn + && path.segments.last().is_some_and(|seg| seg.ident == *ident) + }); + (found_tuple_variant.then_some(dot_span), false) + } + // `Type.Foo`, suggest replacing `.` -> `::` if variant `Foo` exists and is a unit or tuple variant, + // otherwise suggest adding a variant after `Type`. + ExprKind::Field(base, ident) => { + let dot_span = base.span.between(ident.span); + let found_tuple_or_unit_variant = variant_ctors.iter().any(|(path, ..)| { + path.segments.last().is_some_and(|seg| seg.ident == *ident) + }); + (found_tuple_or_unit_variant.then_some(dot_span), false) + } + _ => (None, false), + }, + _ => (None, false), + }; + + if let Some(dot_span) = suggest_path_sep_dot_span { + err.span_suggestion_verbose( + dot_span, + "use the path separator to refer to a variant", + "::", + Applicability::MaybeIncorrect, + ); + } else if suggest_only_tuple_variants { // Suggest only tuple variants regardless of whether they have fields and do not // suggest path with added parentheses. - let mut suggestable_variants = variants + let mut suggestable_variants = variant_ctors .iter() .filter(|(.., kind)| *kind == CtorKind::Fn) .map(|(variant, ..)| path_names_to_string(variant)) .collect::>(); suggestable_variants.sort(); - let non_suggestable_variant_count = variants.len() - suggestable_variants.len(); + let non_suggestable_variant_count = variant_ctors.len() - suggestable_variants.len(); - let source_msg = if source.is_call() { - "to construct" - } else if matches!(source, PathSource::TupleStruct(..)) { + let source_msg = if matches!(source, PathSource::TupleStruct(..)) { "to match against" } else { - unreachable!() + "to construct" }; if !suggestable_variants.is_empty() { @@ -2512,7 +2554,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } // If the enum has no tuple variants.. - if non_suggestable_variant_count == variants.len() { + if non_suggestable_variant_count == variant_ctors.len() { err.help(format!("the enum has no tuple variants {source_msg}")); } @@ -2535,7 +2577,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } }; - let mut suggestable_variants = variants + let mut suggestable_variants = variant_ctors .iter() .filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind)) .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) @@ -2562,7 +2604,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); } - let mut suggestable_variants_with_placeholders = variants + let mut suggestable_variants_with_placeholders = variant_ctors .iter() .filter(|(_, def_id, kind)| needs_placeholder(*def_id, *kind)) .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) diff --git a/tests/ui/resolve/enum-expected-value-suggest-variants.rs b/tests/ui/resolve/enum-expected-value-suggest-variants.rs new file mode 100644 index 0000000000000..9f86a0a1ecc76 --- /dev/null +++ b/tests/ui/resolve/enum-expected-value-suggest-variants.rs @@ -0,0 +1,58 @@ +enum Foo { + //~^ HELP consider importing this tuple variant + A(u32), + B(u32), +} + +enum Bar { + C(u32), + D(u32), + E, + F, +} + +fn main() { + let _: Foo = Foo(0); + //~^ ERROR expected function + //~| HELP try to construct one of the enum's variants + + let _: Foo = Foo.A(0); + //~^ ERROR expected value, found enum `Foo` + //~| HELP use the path separator to refer to a variant + + let _: Foo = Foo.Bad(0); + //~^ ERROR expected value, found enum `Foo` + //~| HELP the following enum variants are available + + let _: Bar = Bar(0); + //~^ ERROR expected function + //~| HELP try to construct one of the enum's variants + //~| HELP you might have meant to construct one of the enum's non-tuple variants + + let _: Bar = Bar.C(0); + //~^ ERROR expected value, found enum `Bar` + //~| HELP use the path separator to refer to a variant + + let _: Bar = Bar.E; + //~^ ERROR expected value, found enum `Bar` + //~| HELP use the path separator to refer to a variant + + let _: Bar = Bar.Bad(0); + //~^ ERROR expected value, found enum `Bar` + //~| HELP you might have meant to use one of the following enum variants + //~| HELP alternatively, the following enum variants are also available + + let _: Bar = Bar.Bad; + //~^ ERROR expected value, found enum `Bar` + //~| HELP you might have meant to use one of the following enum variants + //~| HELP alternatively, the following enum variants are also available + + match Foo::A(42) { + A(..) => {} + //~^ ERROR cannot find tuple struct or tuple variant `A` in this scope + Foo(..) => {} + //~^ ERROR expected tuple struct or tuple variant + //~| HELP try to match against one of the enum's variants + _ => {} + } +} diff --git a/tests/ui/resolve/enum-expected-value-suggest-variants.stderr b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr new file mode 100644 index 0000000000000..0bd6069b27206 --- /dev/null +++ b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr @@ -0,0 +1,225 @@ +error[E0423]: expected value, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:19:18 + | +LL | let _: Foo = Foo.A(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: use the path separator to refer to a variant + | +LL | let _: Foo = Foo::A(0); + | ~~ + +error[E0423]: expected value, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:23:18 + | +LL | let _: Foo = Foo.Bad(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: the following enum variants are available + | +LL | let _: Foo = (Foo::A(/* fields */)).Bad(0); + | ~~~~~~~~~~~~~~~~~~~~~~ +LL | let _: Foo = (Foo::B(/* fields */)).Bad(0); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:32:18 + | +LL | let _: Bar = Bar.C(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: use the path separator to refer to a variant + | +LL | let _: Bar = Bar::C(0); + | ~~ + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:36:18 + | +LL | let _: Bar = Bar.E; + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: use the path separator to refer to a variant + | +LL | let _: Bar = Bar::E; + | ~~ + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:40:18 + | +LL | let _: Bar = Bar.Bad(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: you might have meant to use one of the following enum variants + | +LL | let _: Bar = Bar::E.Bad(0); + | ~~~~~~ +LL | let _: Bar = Bar::F.Bad(0); + | ~~~~~~ +help: alternatively, the following enum variants are also available + | +LL | let _: Bar = (Bar::C(/* fields */)).Bad(0); + | ~~~~~~~~~~~~~~~~~~~~~~ +LL | let _: Bar = (Bar::D(/* fields */)).Bad(0); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:45:18 + | +LL | let _: Bar = Bar.Bad; + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: you might have meant to use one of the following enum variants + | +LL | let _: Bar = Bar::E.Bad; + | ~~~~~~ +LL | let _: Bar = Bar::F.Bad; + | ~~~~~~ +help: alternatively, the following enum variants are also available + | +LL | let _: Bar = (Bar::C(/* fields */)).Bad; + | ~~~~~~~~~~~~~~~~~~~~~~ +LL | let _: Bar = (Bar::D(/* fields */)).Bad; + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0531]: cannot find tuple struct or tuple variant `A` in this scope + --> $DIR/enum-expected-value-suggest-variants.rs:51:9 + | +LL | A(..) => {} + | ^ not found in this scope + | +help: consider importing this tuple variant + | +LL + use Foo::A; + | + +error[E0532]: expected tuple struct or tuple variant, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:53:9 + | +LL | Foo(..) => {} + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: try to match against one of the enum's variants + | +LL | Foo::A(..) => {} + | ~~~~~~ +LL | Foo::B(..) => {} + | ~~~~~~ + +error[E0423]: expected function, tuple struct or tuple variant, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:15:18 + | +LL | let _: Foo = Foo(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: try to construct one of the enum's variants + | +LL | let _: Foo = Foo::A(0); + | ~~~~~~ +LL | let _: Foo = Foo::B(0); + | ~~~~~~ + +error[E0423]: expected function, tuple struct or tuple variant, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:27:18 + | +LL | let _: Bar = Bar(0); + | ^^^ + | + = help: you might have meant to construct one of the enum's non-tuple variants +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: try to construct one of the enum's variants + | +LL | let _: Bar = Bar::C(0); + | ~~~~~~ +LL | let _: Bar = Bar::D(0); + | ~~~~~~ + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0423, E0531, E0532. +For more information about an error, try `rustc --explain E0423`. From ae7b45a6d4b25f01f5c8b9ed547a980146c0d519 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Fri, 31 Jan 2025 16:28:25 -0600 Subject: [PATCH 13/26] When giving a suggestion to use :: instead of . where the rhs is a macro giving a type, make it also work when the rhs is a type alias, not just a struct. --- .../rustc_resolve/src/late/diagnostics.rs | 2 +- ...otation-type-namespace-suggest-path-sep.rs | 43 +++++++++ ...ion-type-namespace-suggest-path-sep.stderr | 96 ++++++++++++++++++- 3 files changed, 137 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 2731efdba48bd..b37c684a0556a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1529,7 +1529,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { Applicability::MaybeIncorrect, ); true - } else if kind == DefKind::Struct + } else if matches!(kind, DefKind::Struct | DefKind::TyAlias) && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span) && let Ok(snippet) = this.r.tcx.sess.source_map().span_to_snippet(lhs_source_span) { diff --git a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs index 104d11f685cc9..432e3c0b77efc 100644 --- a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs +++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs @@ -39,6 +39,12 @@ macro_rules! Type { //~| ERROR expected value, found struct `std::cell::Cell` //~| ERROR expected value, found struct `std::cell::Cell` }; + (alias) => { + Alias + //~^ ERROR expected value, found type alias `Alias` + //~| ERROR expected value, found type alias `Alias` + //~| ERROR expected value, found type alias `Alias` + }; } macro_rules! create { @@ -56,6 +62,32 @@ macro_rules! create { Type!().new(0) //~^ HELP use the path separator }; + (macro method alias) => { + Type!(alias).new(0) + //~^ HELP use the path separator + }; +} + +macro_rules! check_ty { + ($Ty:ident) => { + $Ty.foo + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + }; +} +macro_rules! check_ident { + ($Ident:ident) => { + Alias.$Ident + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + }; +} +macro_rules! check_ty_ident { + ($Ty:ident, $Ident:ident) => { + $Ty.$Ident + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + }; } fn interaction_with_macros() { @@ -70,6 +102,12 @@ fn interaction_with_macros() { Type! {}.get; //~^ HELP use the path separator + Type!(alias).get(); + //~^ HELP use the path separator + + Type! {alias}.get; + //~^ HELP use the path separator + // // Ensure that the suggestion is shown for expressions inside of macro definitions. // @@ -77,4 +115,9 @@ fn interaction_with_macros() { let _ = create!(type method); let _ = create!(type field); let _ = create!(macro method); + let _ = create!(macro method alias); + + let _ = check_ty!(Alias); + let _ = check_ident!(foo); + let _ = check_ty_ident!(Alias, foo); } diff --git a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr index a5397306b01e4..bb2ae7f2de2d0 100644 --- a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr +++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr @@ -99,8 +99,38 @@ LL - Type! {}.get; LL + ::get; | +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9 + | +LL | Alias + | ^^^^^ +... +LL | Type!(alias).get(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL | ::get(); + | ~~~~~~~~~~~~~~~~ + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9 + | +LL | Alias + | ^^^^^ +... +LL | Type! {alias}.get; + | ------------- in this macro invocation + | + = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL | ::get; + | ~~~~~~~~~~~~~~~~~ + error[E0423]: expected value, found struct `Vec` - --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:46:9 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:52:9 | LL | Vec.new() | ^^^ @@ -116,7 +146,7 @@ LL + Vec::new() | error[E0423]: expected value, found struct `Vec` - --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:51:9 + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:57:9 | LL | Vec.new | ^^^ @@ -147,6 +177,66 @@ LL - Type!().new(0) LL + ::new(0) | -error: aborting due to 11 previous errors +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9 + | +LL | Alias + | ^^^^^ +... +LL | let _ = create!(macro method alias); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL | ::new(0) + | ~~~~~~~~~~~~~~~~ + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:73:9 + | +LL | $Ty.foo + | ^^^ +... +LL | let _ = check_ty!(Alias); + | ---------------- in this macro invocation + | + = note: this error originates in the macro `check_ty` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL | $Ty::foo + | ~~ + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:80:9 + | +LL | Alias.$Ident + | ^^^^^ +... +LL | let _ = check_ident!(foo); + | ----------------- in this macro invocation + | + = note: this error originates in the macro `check_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL | ::$Ident + | ~~~~~~~~~ + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:87:9 + | +LL | $Ty.$Ident + | ^^^ +... +LL | let _ = check_ty_ident!(Alias, foo); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `check_ty_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL | <$Ty>::$Ident + | ~~~~~~~ + +error: aborting due to 17 previous errors For more information about this error, try `rustc --explain E0423`. From e639e886b24d51a527e05477b787246148ce8cc2 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Wed, 12 Feb 2025 10:35:32 +0100 Subject: [PATCH 14/26] Lint `#[must_use]` attributes applied to methods in trait impls The `#[must_use]` attribute has no effect when applied to methods in trait implementations. This case was not linted before. --- compiler/rustc_passes/src/check_attr.rs | 47 ++++++++++++------- .../lint/unused/unused_attributes-must_use.rs | 5 ++ .../unused/unused_attributes-must_use.stderr | 36 ++++++++------ 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f578708b40cd3..939637d0e296f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1431,37 +1431,48 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Warns against some misuses of `#[must_use]` fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) { - if !matches!( + if matches!( target, Target::Fn | Target::Enum | Target::Struct | Target::Union - | Target::Method(_) + | Target::Method(MethodKind::Trait { body: false } | MethodKind::Inherent) | Target::ForeignFn // `impl Trait` in return position can trip // `unused_must_use` if `Trait` is marked as // `#[must_use]` | Target::Trait ) { - let article = match target { - Target::ExternCrate - | Target::Enum - | Target::Impl - | Target::Expression - | Target::Arm - | Target::AssocConst - | Target::AssocTy => "an", - _ => "a", - }; + return; + } - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MustUseNoEffect { article, target }, - ); + // `#[must_use]` can be applied to a trait method definition with a default body + if let Target::Method(MethodKind::Trait { body: true }) = target + && let parent_def_id = self.tcx.hir().get_parent_item(hir_id).def_id + && let containing_item = self.tcx.hir().expect_item(parent_def_id) + && let hir::ItemKind::Trait(..) = containing_item.kind + { + return; } + + let article = match target { + Target::ExternCrate + | Target::Enum + | Target::Impl + | Target::Expression + | Target::Arm + | Target::AssocConst + | Target::AssocTy => "an", + _ => "a", + }; + + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::MustUseNoEffect { article, target }, + ); } /// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait. diff --git a/tests/ui/lint/unused/unused_attributes-must_use.rs b/tests/ui/lint/unused/unused_attributes-must_use.rs index 51f868706b69b..860fc5046d103 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.rs +++ b/tests/ui/lint/unused/unused_attributes-must_use.rs @@ -79,6 +79,11 @@ trait Use { #[must_use] //~ ERROR `#[must_use]` has no effect impl Use for () { type AssocTy = (); + + #[must_use] //~ ERROR `#[must_use]` has no effect + fn get_four(&self) -> usize { + 4 + } } #[must_use] //~ ERROR `#[must_use]` has no effect diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr index 9633767c44287..28fd8eeb8cbdc 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.stderr +++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr @@ -76,43 +76,43 @@ LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a trait alias - --> $DIR/unused_attributes-must_use.rs:84:1 + --> $DIR/unused_attributes-must_use.rs:89:1 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a macro def - --> $DIR/unused_attributes-must_use.rs:87:1 + --> $DIR/unused_attributes-must_use.rs:92:1 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a statement - --> $DIR/unused_attributes-must_use.rs:95:5 + --> $DIR/unused_attributes-must_use.rs:100:5 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a closure - --> $DIR/unused_attributes-must_use.rs:99:13 + --> $DIR/unused_attributes-must_use.rs:104:13 | LL | let x = #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to an match arm - --> $DIR/unused_attributes-must_use.rs:121:9 + --> $DIR/unused_attributes-must_use.rs:126:9 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a struct field - --> $DIR/unused_attributes-must_use.rs:129:28 + --> $DIR/unused_attributes-must_use.rs:134:28 | LL | let s = PatternField { #[must_use] foo: 123 }; | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a pattern field - --> $DIR/unused_attributes-must_use.rs:130:24 + --> $DIR/unused_attributes-must_use.rs:135:24 | LL | let PatternField { #[must_use] foo } = s; | ^^^^^^^^^^^ @@ -129,6 +129,12 @@ error: `#[must_use]` has no effect when applied to an associated type LL | #[must_use] | ^^^^^^^^^^^ +error: `#[must_use]` has no effect when applied to a provided trait method + --> $DIR/unused_attributes-must_use.rs:83:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: `#[must_use]` has no effect when applied to a foreign static item --> $DIR/unused_attributes-must_use.rs:50:5 | @@ -136,7 +142,7 @@ LL | #[must_use] | ^^^^^^^^^^^ error: unused `X` that must be used - --> $DIR/unused_attributes-must_use.rs:103:5 + --> $DIR/unused_attributes-must_use.rs:108:5 | LL | X; | ^ @@ -152,7 +158,7 @@ LL | let _ = X; | +++++++ error: unused `Y` that must be used - --> $DIR/unused_attributes-must_use.rs:104:5 + --> $DIR/unused_attributes-must_use.rs:109:5 | LL | Y::Z; | ^^^^ @@ -163,7 +169,7 @@ LL | let _ = Y::Z; | +++++++ error: unused `U` that must be used - --> $DIR/unused_attributes-must_use.rs:105:5 + --> $DIR/unused_attributes-must_use.rs:110:5 | LL | U { unit: () }; | ^^^^^^^^^^^^^^ @@ -174,7 +180,7 @@ LL | let _ = U { unit: () }; | +++++++ error: unused return value of `U::method` that must be used - --> $DIR/unused_attributes-must_use.rs:106:5 + --> $DIR/unused_attributes-must_use.rs:111:5 | LL | U::method(); | ^^^^^^^^^^^ @@ -185,7 +191,7 @@ LL | let _ = U::method(); | +++++++ error: unused return value of `foo` that must be used - --> $DIR/unused_attributes-must_use.rs:107:5 + --> $DIR/unused_attributes-must_use.rs:112:5 | LL | foo(); | ^^^^^ @@ -196,7 +202,7 @@ LL | let _ = foo(); | +++++++ error: unused return value of `foreign_foo` that must be used - --> $DIR/unused_attributes-must_use.rs:110:9 + --> $DIR/unused_attributes-must_use.rs:115:9 | LL | foreign_foo(); | ^^^^^^^^^^^^^ @@ -207,7 +213,7 @@ LL | let _ = foreign_foo(); | +++++++ error: unused return value of `Use::get_four` that must be used - --> $DIR/unused_attributes-must_use.rs:118:5 + --> $DIR/unused_attributes-must_use.rs:123:5 | LL | ().get_four(); | ^^^^^^^^^^^^^ @@ -217,5 +223,5 @@ help: use `let _ = ...` to ignore the resulting value LL | let _ = ().get_four(); | +++++++ -error: aborting due to 28 previous errors +error: aborting due to 29 previous errors From 2c3725021e1b976ecc30b902f74e0f867c634592 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Tue, 11 Feb 2025 12:49:36 -0600 Subject: [PATCH 15/26] Update `.` -> `::` tests for new diff suggestion format. --- ...ion-type-namespace-suggest-path-sep.stderr | 45 ++++++++----- ...num-expected-value-suggest-variants.stderr | 65 +++++++++++-------- 2 files changed, 64 insertions(+), 46 deletions(-) diff --git a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr index bb2ae7f2de2d0..d74814dd876c2 100644 --- a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr +++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr @@ -42,8 +42,9 @@ LL | let _ = Alias.new(); | help: use the path separator to refer to an item | -LL | let _ = Alias::new(); - | ~~ +LL - let _ = Alias.new(); +LL + let _ = Alias::new(); + | error[E0423]: expected value, found type alias `Alias` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:26:13 @@ -53,8 +54,9 @@ LL | let _ = Alias.default; | help: use the path separator to refer to an item | -LL | let _ = Alias::default; - | ~~ +LL - let _ = Alias.default; +LL + let _ = Alias::default; + | error[E0423]: expected value, found module `foo` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:30:13 @@ -64,8 +66,9 @@ LL | let _ = foo.bar; | help: use the path separator to refer to an item | -LL | let _ = foo::bar; - | ~~ +LL - let _ = foo.bar; +LL + let _ = foo::bar; + | error[E0423]: expected value, found struct `std::cell::Cell` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9 @@ -111,8 +114,9 @@ LL | Type!(alias).get(); = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the path separator to refer to an item | -LL | ::get(); - | ~~~~~~~~~~~~~~~~ +LL - Type!(alias).get(); +LL + ::get(); + | error[E0423]: expected value, found type alias `Alias` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9 @@ -126,8 +130,9 @@ LL | Type! {alias}.get; = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the path separator to refer to an item | -LL | ::get; - | ~~~~~~~~~~~~~~~~~ +LL - Type! {alias}.get; +LL + ::get; + | error[E0423]: expected value, found struct `Vec` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:52:9 @@ -189,8 +194,9 @@ LL | let _ = create!(macro method alias); = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the path separator to refer to an item | -LL | ::new(0) - | ~~~~~~~~~~~~~~~~ +LL - Type!(alias).new(0) +LL + ::new(0) + | error[E0423]: expected value, found type alias `Alias` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:73:9 @@ -204,8 +210,9 @@ LL | let _ = check_ty!(Alias); = note: this error originates in the macro `check_ty` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the path separator to refer to an item | -LL | $Ty::foo - | ~~ +LL - $Ty.foo +LL + $Ty::foo + | error[E0423]: expected value, found type alias `Alias` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:80:9 @@ -219,8 +226,9 @@ LL | let _ = check_ident!(foo); = note: this error originates in the macro `check_ident` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the path separator to refer to an item | -LL | ::$Ident - | ~~~~~~~~~ +LL - Alias.$Ident +LL + ::$Ident + | error[E0423]: expected value, found type alias `Alias` --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:87:9 @@ -234,8 +242,9 @@ LL | let _ = check_ty_ident!(Alias, foo); = note: this error originates in the macro `check_ty_ident` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the path separator to refer to an item | -LL | <$Ty>::$Ident - | ~~~~~~~ +LL - $Ty.$Ident +LL + <$Ty>::$Ident + | error: aborting due to 17 previous errors diff --git a/tests/ui/resolve/enum-expected-value-suggest-variants.stderr b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr index 0bd6069b27206..548a4c0e59320 100644 --- a/tests/ui/resolve/enum-expected-value-suggest-variants.stderr +++ b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr @@ -15,8 +15,9 @@ LL | | } | |_^ help: use the path separator to refer to a variant | -LL | let _: Foo = Foo::A(0); - | ~~ +LL - let _: Foo = Foo.A(0); +LL + let _: Foo = Foo::A(0); + | error[E0423]: expected value, found enum `Foo` --> $DIR/enum-expected-value-suggest-variants.rs:23:18 @@ -35,10 +36,12 @@ LL | | } | |_^ help: the following enum variants are available | -LL | let _: Foo = (Foo::A(/* fields */)).Bad(0); - | ~~~~~~~~~~~~~~~~~~~~~~ -LL | let _: Foo = (Foo::B(/* fields */)).Bad(0); - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Foo = Foo.Bad(0); +LL + let _: Foo = (Foo::A(/* fields */)).Bad(0); + | +LL - let _: Foo = Foo.Bad(0); +LL + let _: Foo = (Foo::B(/* fields */)).Bad(0); + | error[E0423]: expected value, found enum `Bar` --> $DIR/enum-expected-value-suggest-variants.rs:32:18 @@ -58,8 +61,9 @@ LL | | } | |_^ help: use the path separator to refer to a variant | -LL | let _: Bar = Bar::C(0); - | ~~ +LL - let _: Bar = Bar.C(0); +LL + let _: Bar = Bar::C(0); + | error[E0423]: expected value, found enum `Bar` --> $DIR/enum-expected-value-suggest-variants.rs:36:18 @@ -79,8 +83,9 @@ LL | | } | |_^ help: use the path separator to refer to a variant | -LL | let _: Bar = Bar::E; - | ~~ +LL - let _: Bar = Bar.E; +LL + let _: Bar = Bar::E; + | error[E0423]: expected value, found enum `Bar` --> $DIR/enum-expected-value-suggest-variants.rs:40:18 @@ -101,15 +106,17 @@ LL | | } help: you might have meant to use one of the following enum variants | LL | let _: Bar = Bar::E.Bad(0); - | ~~~~~~ + | +++ LL | let _: Bar = Bar::F.Bad(0); - | ~~~~~~ + | +++ help: alternatively, the following enum variants are also available | -LL | let _: Bar = (Bar::C(/* fields */)).Bad(0); - | ~~~~~~~~~~~~~~~~~~~~~~ -LL | let _: Bar = (Bar::D(/* fields */)).Bad(0); - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Bar = Bar.Bad(0); +LL + let _: Bar = (Bar::C(/* fields */)).Bad(0); + | +LL - let _: Bar = Bar.Bad(0); +LL + let _: Bar = (Bar::D(/* fields */)).Bad(0); + | error[E0423]: expected value, found enum `Bar` --> $DIR/enum-expected-value-suggest-variants.rs:45:18 @@ -130,15 +137,17 @@ LL | | } help: you might have meant to use one of the following enum variants | LL | let _: Bar = Bar::E.Bad; - | ~~~~~~ + | +++ LL | let _: Bar = Bar::F.Bad; - | ~~~~~~ + | +++ help: alternatively, the following enum variants are also available | -LL | let _: Bar = (Bar::C(/* fields */)).Bad; - | ~~~~~~~~~~~~~~~~~~~~~~ -LL | let _: Bar = (Bar::D(/* fields */)).Bad; - | ~~~~~~~~~~~~~~~~~~~~~~ +LL - let _: Bar = Bar.Bad; +LL + let _: Bar = (Bar::C(/* fields */)).Bad; + | +LL - let _: Bar = Bar.Bad; +LL + let _: Bar = (Bar::D(/* fields */)).Bad; + | error[E0531]: cannot find tuple struct or tuple variant `A` in this scope --> $DIR/enum-expected-value-suggest-variants.rs:51:9 @@ -169,9 +178,9 @@ LL | | } help: try to match against one of the enum's variants | LL | Foo::A(..) => {} - | ~~~~~~ + | +++ LL | Foo::B(..) => {} - | ~~~~~~ + | +++ error[E0423]: expected function, tuple struct or tuple variant, found enum `Foo` --> $DIR/enum-expected-value-suggest-variants.rs:15:18 @@ -191,9 +200,9 @@ LL | | } help: try to construct one of the enum's variants | LL | let _: Foo = Foo::A(0); - | ~~~~~~ + | +++ LL | let _: Foo = Foo::B(0); - | ~~~~~~ + | +++ error[E0423]: expected function, tuple struct or tuple variant, found enum `Bar` --> $DIR/enum-expected-value-suggest-variants.rs:27:18 @@ -215,9 +224,9 @@ LL | | } help: try to construct one of the enum's variants | LL | let _: Bar = Bar::C(0); - | ~~~~~~ + | +++ LL | let _: Bar = Bar::D(0); - | ~~~~~~ + | +++ error: aborting due to 10 previous errors From e24833a4a8789c0acd1850284b3fd660d7a0094a Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 22 Jan 2025 23:59:03 -0800 Subject: [PATCH 16/26] add test revisions for old-edition behavior of feature gates This also adds `#[cfg]` attributes to tests for bindings' types, to make it visually clearer which revisions type successfully. --- .../borrowck-errors.classic2021.stderr | 37 ++ .../borrowck-errors.classic2024.stderr | 22 +- .../experimental/borrowck-errors.rs | 24 +- .../borrowck-errors.stable2021.stderr | 12 +- .../borrowck-errors.structural2021.stderr | 25 ++ .../borrowck-errors.structural2024.stderr | 4 +- .../mut-ref-mut.classic2024.stderr | 6 +- .../experimental/mut-ref-mut.rs | 16 +- .../mut-ref-mut.structural2024.stderr | 6 +- .../pattern-errors.classic2021.stderr | 354 ++++++++++++++++++ .../pattern-errors.classic2024.stderr | 20 +- .../experimental/pattern-errors.rs | 115 +++--- .../pattern-errors.stable2021.stderr | 52 +-- .../pattern-errors.structural2021.stderr | 354 ++++++++++++++++++ .../pattern-errors.structural2024.stderr | 50 +-- ...nding-on-inh-ref-errors.classic2021.stderr | 9 + ...nding-on-inh-ref-errors.classic2024.stderr | 20 +- .../ref-binding-on-inh-ref-errors.rs | 26 +- ...inding-on-inh-ref-errors.stable2021.stderr | 6 +- ...ng-on-inh-ref-errors.structural2021.stderr | 9 + ...ng-on-inh-ref-errors.structural2024.stderr | 46 +-- ...t-inside-shared-ref-pat.classic2021.stderr | 63 ++++ ...ut-inside-shared-ref-pat.classic2024.fixed | 24 +- ...t-inside-shared-ref-pat.classic2024.stderr | 14 +- .../ref-mut-inside-shared-ref-pat.rs | 24 +- ...ut-inside-shared-ref-pat.stable2021.stderr | 12 +- ...nside-shared-ref-pat.structural2021.stderr | 55 +++ ...inside-shared-ref-pat.structural2024.fixed | 24 +- ...nside-shared-ref-pat.structural2024.stderr | 12 +- ...well-typed-edition-2024.classic2021.stderr | 254 +++++++++++++ .../experimental/well-typed-edition-2024.rs | 112 +++--- .../well-typed-edition-2024.stable2021.stderr | 44 +-- ...l-typed-edition-2024.structural2021.stderr | 254 +++++++++++++ 33 files changed, 1783 insertions(+), 322 deletions(-) create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr new file mode 100644 index 0000000000000..355a8af6760f3 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr @@ -0,0 +1,37 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/borrowck-errors.rs:31:29 + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | - ^^^^^^^^^^^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - if let Some(&Some(x)) = Some(&Some(&mut 0)) { +LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { + | + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:36:10 + | +LL | let &ref mut x = &0; + | ^^^^^^^^^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:41:23 + | +LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:46:11 + | +LL | let &[x] = &&mut [0]; + | ^ cannot borrow as mutable + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr index 1c44617830828..d40bdb9111b30 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr @@ -1,25 +1,25 @@ -error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:13:16 +error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:15:16 | LL | let [&x] = &[&mut 0]; | - ^^^^^^^^^ cannot move out of here | | | data moved here - | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait | help: consider borrowing the pattern binding | LL | let [&ref x] = &[&mut 0]; | +++ -error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:19:16 +error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:22:16 | LL | let [&x] = &mut [&mut 0]; | - ^^^^^^^^^^^^^ cannot move out of here | | | data moved here - | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait | help: consider borrowing the pattern binding | @@ -27,7 +27,7 @@ LL | let [&ref x] = &mut [&mut 0]; | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:27:29 + --> $DIR/borrowck-errors.rs:31:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -42,25 +42,25 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:32:10 + --> $DIR/borrowck-errors.rs:36:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:37:23 + --> $DIR/borrowck-errors.rs:41:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:42:11 + --> $DIR/borrowck-errors.rs:46:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:46:20 + --> $DIR/borrowck-errors.rs:50:20 | LL | let [&mut x] = &mut [&mut 0]; | - ^^^^^^^^^^^^^ cannot move out of here diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs index 59cafc50d8661..621ca7cc792eb 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs @@ -1,11 +1,13 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //! Tests for pattern errors not handled by the pattern typing rules, but by borrowck. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] /// These patterns additionally use `&` to match a `&mut` reference type, which causes compilation /// to fail in HIR typeck on stable. As such, they need to be separate from the other tests. @@ -14,13 +16,15 @@ fn errors_caught_in_hir_typeck_on_stable() { //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability //[classic2024]~^^^ ERROR: cannot move out of type - let _: &u32 = x; + #[cfg(any(classic2021, structural2021))] let _: u32 = x; + #[cfg(structural2024)] let _: &u32 = x; let [&x] = &mut [&mut 0]; //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability //[classic2024]~^^^ ERROR: cannot move out of type - let _: &u32 = x; + #[cfg(any(classic2021, structural2021))] let _: u32 = x; + #[cfg(structural2024)] let _: &u32 = x; } pub fn main() { @@ -35,16 +39,16 @@ pub fn main() { // For 2021 edition, this is also a regression test for #136223 // since the maximum mutability is downgraded during the pattern check process. if let &Some(Some(x)) = &Some(&mut Some(0)) { - //[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable - let _: &u32 = x; + //[stable2021,classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] let _: &u32 = x; } let &[x] = &&mut [0]; - //[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable - let _: &u32 = x; + //[stable2021,classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] let _: &u32 = x; let [&mut x] = &mut [&mut 0]; //[classic2024]~^ ERROR: cannot move out of type - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr index deefe21ca7d45..edcf9f3035707 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/borrowck-errors.rs:13:10 + --> $DIR/borrowck-errors.rs:15:10 | LL | let [&x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -15,7 +15,7 @@ LL + let [x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/borrowck-errors.rs:19:10 + --> $DIR/borrowck-errors.rs:22:10 | LL | let [&x] = &mut [&mut 0]; | ^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -31,7 +31,7 @@ LL + let [x] = &mut [&mut 0]; | error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:27:29 + --> $DIR/borrowck-errors.rs:31:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -46,19 +46,19 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:32:10 + --> $DIR/borrowck-errors.rs:36:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:37:23 + --> $DIR/borrowck-errors.rs:41:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:42:11 + --> $DIR/borrowck-errors.rs:46:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr new file mode 100644 index 0000000000000..208f6c8bbed03 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr @@ -0,0 +1,25 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/borrowck-errors.rs:31:29 + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | - ^^^^^^^^^^^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - if let Some(&Some(x)) = Some(&Some(&mut 0)) { +LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { + | + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:36:10 + | +LL | let &ref mut x = &0; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr index 30d2f9f3d702f..208f6c8bbed03 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:27:29 + --> $DIR/borrowck-errors.rs:31:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:32:10 + --> $DIR/borrowck-errors.rs:36:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr index fa95b2b5a575d..6ddced3d16812 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr @@ -1,5 +1,5 @@ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:14:13 + --> $DIR/mut-ref-mut.rs:18:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:19:13 + --> $DIR/mut-ref-mut.rs:23:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -19,7 +19,7 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/mut-ref-mut.rs:24:10 + --> $DIR/mut-ref-mut.rs:28:10 | LL | let [&mut mut x] = &[&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs index fbd6514df73d6..c8e988ad76d97 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs @@ -1,29 +1,33 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[stable2021] run-pass +//@[classic2021] run-pass +//@[structural2021] run-pass //! Test diagnostics for binding with `mut` when the default binding mode is by-ref. #![allow(incomplete_features, unused_assignments, unused_variables)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { struct Foo(u8); let Foo(mut a) = &Foo(0); //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] { a = 42 } + #[cfg(any(stable2021, classic2021, structural2021))] { a = 42 } #[cfg(any(classic2024, structural2024))] { a = &42 } let Foo(mut a) = &mut Foo(0); //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] { a = 42 } + #[cfg(any(stable2021, classic2021, structural2021))] { a = 42 } #[cfg(any(classic2024, structural2024))] { a = &mut 42 } let [&mut mut x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern //[structural2024]~^^^ binding cannot be both mutable and by-reference - #[cfg(stable2021)] { x = 0 } + #[cfg(any(stable2021, classic2021, structural2021))] { x = 0 } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr index fd82da70a18de..c0c0f966b6804 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr @@ -1,5 +1,5 @@ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:14:13 + --> $DIR/mut-ref-mut.rs:18:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:19:13 + --> $DIR/mut-ref-mut.rs:23:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -19,7 +19,7 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:24:15 + --> $DIR/mut-ref-mut.rs:28:15 | LL | let [&mut mut x] = &[&mut 0]; | ^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr new file mode 100644 index 0000000000000..e039884cdb14b --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr @@ -0,0 +1,354 @@ +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:20:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:33:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:45:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:50:17 + | +LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { + | ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected `Option<&mut Option<{integer}>>`, found `&_` + | + = note: expected enum `Option<&mut Option<{integer}>>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:57:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:66:11 + | +LL | let &[&mut x] = &&mut [0]; + | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:66:11 + | +LL | let &[&mut x] = &&mut [0]; + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut x] = &&mut [0]; +LL + let &[x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:73:11 + | +LL | let &[&mut x] = &mut &mut [0]; + | ^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:73:11 + | +LL | let &[&mut x] = &mut &mut [0]; + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut x] = &mut &mut [0]; +LL + let &[x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:80:11 + | +LL | let &[&mut ref x] = &&mut [0]; + | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:80:11 + | +LL | let &[&mut ref x] = &&mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut ref x] = &&mut [0]; +LL + let &[ref x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:87:11 + | +LL | let &[&mut ref x] = &mut &mut [0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:87:11 + | +LL | let &[&mut ref x] = &mut &mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut ref x] = &mut &mut [0]; +LL + let &[ref x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:94:11 + | +LL | let &[&mut mut x] = &&mut [0]; + | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:94:11 + | +LL | let &[&mut mut x] = &&mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut mut x] = &&mut [0]; +LL + let &[mut x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:101:11 + | +LL | let &[&mut mut x] = &mut &mut [0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:101:11 + | +LL | let &[&mut mut x] = &mut &mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut mut x] = &mut &mut [0]; +LL + let &[mut x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:122:11 + | +LL | let [&&mut x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &[&mut 0]; +LL + let [&x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:129:11 + | +LL | let [&&mut x] = &mut [&mut 0]; + | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &mut [&mut 0]; +LL + let [&x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:136:11 + | +LL | let [&&mut ref x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &[&mut 0]; +LL + let [&ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:143:11 + | +LL | let [&&mut ref x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &mut [&mut 0]; +LL + let [&ref x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:150:11 + | +LL | let [&&mut mut x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:157:11 + | +LL | let [&&mut mut x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &mut [&mut 0]; +LL + let [&mut x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:172:15 + | +LL | let [&mut &x] = &[&mut 0]; + | ^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:178:15 + | +LL | let [&mut &ref x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &ref x] = &[&mut 0]; +LL + let [&mut ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:184:15 + | +LL | let [&mut &(mut x)] = &[&mut 0]; + | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &(mut x)] = &[&mut 0]; +LL + let [&mut mut x)] = &[&mut 0]; + | + +error: aborting due to 21 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr index 6726a72631533..b98cfe337efee 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:12:17 + --> $DIR/pattern-errors.rs:14:17 | LL | if let Some(&mut x) = &Some(&mut 0) { | ^^^^^ @@ -12,7 +12,7 @@ LL + if let Some(&x) = &Some(&mut 0) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:18:17 + --> $DIR/pattern-errors.rs:20:17 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^^^^ @@ -25,7 +25,7 @@ LL + if let Some(&Some(&x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:24:22 + --> $DIR/pattern-errors.rs:26:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ @@ -38,7 +38,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&mut 0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:17 + --> $DIR/pattern-errors.rs:33:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -51,7 +51,7 @@ LL + if let Some(&Some(&_)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:41:23 + --> $DIR/pattern-errors.rs:45:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -64,7 +64,7 @@ LL + if let Some(&Some(&_)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:51:17 + --> $DIR/pattern-errors.rs:57:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -77,7 +77,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:147:10 + --> $DIR/pattern-errors.rs:166:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:153:10 + --> $DIR/pattern-errors.rs:172:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:159:10 + --> $DIR/pattern-errors.rs:178:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:165:10 + --> $DIR/pattern-errors.rs:184:10 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index c07c2972cd055..4173b1819cba5 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs @@ -1,170 +1,189 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //! Test cases for poorly-typed patterns in edition 2024 which are caught by HIR typeck. These must //! be separate from cases caught by MIR borrowck or the latter errors may not be emitted. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut x) = &Some(&mut 0) { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - //[stable2021,classic2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&_` + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(structural2024)] let _: u32 = x; } if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&_)) = &Some(&Some(0)) { //~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability + //[stable2021,classic2021,structural2021]~| types differ in mutability //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } - if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - //[stable2021,structural2024]~^ ERROR: mismatched types + if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(classic2024)] let _: u32 = x; } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&mut _` + //[stable2021,classic2021,structural2021]~| expected integer, found `&mut _` //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } - if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { - //[stable2021,structural2024]~^ ERROR: mismatched types + if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` //[structural2024]~| cannot match inherited `&` with `&mut` pattern + // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too + #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold on `classic2021` too } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types - //[stable2021]~| expected `Option<{integer}>`, found `&mut _` + //[stable2021,classic2021,structural2021]~| expected `Option<{integer}>`, found `&mut _` //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern + // TODO: the error on `classic2021` and `structural2021` should be the mutability mismatch } } fn structural_errors_0() { let &[&mut x] = &&mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too + #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too let &[&mut x] = &mut &mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too + #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too let &[&mut ref x] = &&mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too + #[cfg(classic2024)] let _: &u32 = x; // TODO: this should hold for `classic2021` too let &[&mut ref x] = &mut &mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too + #[cfg(classic2024)] let _: &u32 = x; // TODO: this should hold for `classic2021` too let &[&mut mut x] = &&mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too + #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too let &[&mut mut x] = &mut &mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too + #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too } fn structural_errors_1() { let [&(mut x)] = &[&0]; //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(classic2024)] let _: &u32 = x; let [&(mut x)] = &mut [&0]; //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(classic2024)] let _: &u32 = x; } fn structural_errors_2() { let [&&mut x] = &[&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; let [&&mut x] = &mut [&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; let [&&mut ref x] = &[&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(classic2024)] let _: &u32 = x; let [&&mut ref x] = &mut [&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(classic2024)] let _: &u32 = x; let [&&mut mut x] = &[&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; let [&&mut mut x] = &mut [&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; } fn classic_errors_0() { let [&mut x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; let [&mut &x] = &[&mut 0]; - //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(structural2024)] let _: u32 = x; let [&mut &ref x] = &[&mut 0]; - //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(structural2024)] let _: &u32 = x; let [&mut &(mut x)] = &[&mut 0]; - //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(structural2024)] let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr index ad19b122c20d7..ad9541b71a028 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:18:27 + --> $DIR/pattern-errors.rs:20:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -15,7 +15,7 @@ LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:17 + --> $DIR/pattern-errors.rs:33:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -26,9 +26,9 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:36:17 + --> $DIR/pattern-errors.rs:38:17 | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` | | | types differ in mutability @@ -37,7 +37,7 @@ LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:41:23 + --> $DIR/pattern-errors.rs:45:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -48,9 +48,9 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:46:17 + --> $DIR/pattern-errors.rs:50:17 | -LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { +LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { | ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` | | | expected `Option<&mut Option<{integer}>>`, found `&_` @@ -59,7 +59,7 @@ LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:51:17 + --> $DIR/pattern-errors.rs:57:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -70,7 +70,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -80,7 +80,7 @@ LL | let &[&mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ @@ -91,7 +91,7 @@ LL + let &[x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:65:9 + --> $DIR/pattern-errors.rs:73:9 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -102,7 +102,7 @@ LL | let &[&mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:71:11 + --> $DIR/pattern-errors.rs:80:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -112,7 +112,7 @@ LL | let &[&mut ref x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:71:11 + --> $DIR/pattern-errors.rs:80:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ @@ -123,7 +123,7 @@ LL + let &[ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:77:9 + --> $DIR/pattern-errors.rs:87:9 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -134,7 +134,7 @@ LL | let &[&mut ref x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:83:11 + --> $DIR/pattern-errors.rs:94:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -144,7 +144,7 @@ LL | let &[&mut mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:83:11 + --> $DIR/pattern-errors.rs:94:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let &[mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:89:9 + --> $DIR/pattern-errors.rs:101:9 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -166,7 +166,7 @@ LL | let &[&mut mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:109:10 + --> $DIR/pattern-errors.rs:122:10 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -177,7 +177,7 @@ LL | let [&&mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:115:10 + --> $DIR/pattern-errors.rs:129:10 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -188,7 +188,7 @@ LL | let [&&mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:10 + --> $DIR/pattern-errors.rs:136:10 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -199,7 +199,7 @@ LL | let [&&mut ref x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:127:10 + --> $DIR/pattern-errors.rs:143:10 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -210,7 +210,7 @@ LL | let [&&mut ref x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:133:10 + --> $DIR/pattern-errors.rs:150:10 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -221,7 +221,7 @@ LL | let [&&mut mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:139:10 + --> $DIR/pattern-errors.rs:157:10 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -232,7 +232,7 @@ LL | let [&&mut mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:153:15 + --> $DIR/pattern-errors.rs:172:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -248,7 +248,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:159:15 + --> $DIR/pattern-errors.rs:178:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -264,7 +264,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:165:15 + --> $DIR/pattern-errors.rs:184:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr new file mode 100644 index 0000000000000..e039884cdb14b --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr @@ -0,0 +1,354 @@ +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:20:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:33:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:45:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:50:17 + | +LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { + | ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected `Option<&mut Option<{integer}>>`, found `&_` + | + = note: expected enum `Option<&mut Option<{integer}>>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:57:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:66:11 + | +LL | let &[&mut x] = &&mut [0]; + | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:66:11 + | +LL | let &[&mut x] = &&mut [0]; + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut x] = &&mut [0]; +LL + let &[x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:73:11 + | +LL | let &[&mut x] = &mut &mut [0]; + | ^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:73:11 + | +LL | let &[&mut x] = &mut &mut [0]; + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut x] = &mut &mut [0]; +LL + let &[x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:80:11 + | +LL | let &[&mut ref x] = &&mut [0]; + | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:80:11 + | +LL | let &[&mut ref x] = &&mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut ref x] = &&mut [0]; +LL + let &[ref x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:87:11 + | +LL | let &[&mut ref x] = &mut &mut [0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:87:11 + | +LL | let &[&mut ref x] = &mut &mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut ref x] = &mut &mut [0]; +LL + let &[ref x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:94:11 + | +LL | let &[&mut mut x] = &&mut [0]; + | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:94:11 + | +LL | let &[&mut mut x] = &&mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut mut x] = &&mut [0]; +LL + let &[mut x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:101:11 + | +LL | let &[&mut mut x] = &mut &mut [0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:101:11 + | +LL | let &[&mut mut x] = &mut &mut [0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let &[&mut mut x] = &mut &mut [0]; +LL + let &[mut x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:122:11 + | +LL | let [&&mut x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &[&mut 0]; +LL + let [&x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:129:11 + | +LL | let [&&mut x] = &mut [&mut 0]; + | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &mut [&mut 0]; +LL + let [&x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:136:11 + | +LL | let [&&mut ref x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &[&mut 0]; +LL + let [&ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:143:11 + | +LL | let [&&mut ref x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &mut [&mut 0]; +LL + let [&ref x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:150:11 + | +LL | let [&&mut mut x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:157:11 + | +LL | let [&&mut mut x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &mut [&mut 0]; +LL + let [&mut x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:172:15 + | +LL | let [&mut &x] = &[&mut 0]; + | ^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:178:15 + | +LL | let [&mut &ref x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &ref x] = &[&mut 0]; +LL + let [&mut ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:184:15 + | +LL | let [&mut &(mut x)] = &[&mut 0]; + | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &(mut x)] = &[&mut 0]; +LL + let [&mut mut x)] = &[&mut 0]; + | + +error: aborting due to 21 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr index fdf48a5a71b5f..950d9f8b35110 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:17 + --> $DIR/pattern-errors.rs:33:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -12,20 +12,20 @@ LL + if let Some(&Some(&_)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:36:23 + --> $DIR/pattern-errors.rs:38:23 | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^ | = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | -LL - if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { -LL + if let Some(&Some(&_)) = &Some(&mut Some(0)) { +LL - if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(&x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:41:23 + --> $DIR/pattern-errors.rs:45:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -38,20 +38,20 @@ LL + if let Some(&Some(&_)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:46:28 + --> $DIR/pattern-errors.rs:50:28 | -LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { +LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { | ^^^^^ | = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | -LL - if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { -LL + if let Some(&Some(Some(&_))) = &Some(Some(&mut Some(0))) { +LL - if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { +LL + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:51:17 + --> $DIR/pattern-errors.rs:57:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -64,7 +64,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -77,7 +77,7 @@ LL + let &[&x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:65:11 + --> $DIR/pattern-errors.rs:73:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let &[&x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:71:11 + --> $DIR/pattern-errors.rs:80:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let &[&ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:77:11 + --> $DIR/pattern-errors.rs:87:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let &[&ref x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:83:11 + --> $DIR/pattern-errors.rs:94:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -129,7 +129,7 @@ LL + let &[&mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:89:11 + --> $DIR/pattern-errors.rs:101:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -142,7 +142,7 @@ LL + let &[&mut x] = &mut &mut [0]; | error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:97:12 + --> $DIR/pattern-errors.rs:110:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -152,7 +152,7 @@ LL | let [&(mut x)] = &[&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:102:12 + --> $DIR/pattern-errors.rs:115:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -162,7 +162,7 @@ LL | let [&(mut x)] = &mut [&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:109:11 + --> $DIR/pattern-errors.rs:122:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -175,7 +175,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:115:11 + --> $DIR/pattern-errors.rs:129:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -188,7 +188,7 @@ LL + let [&&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:11 + --> $DIR/pattern-errors.rs:136:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -201,7 +201,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:127:11 + --> $DIR/pattern-errors.rs:143:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -214,7 +214,7 @@ LL + let [&&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:133:11 + --> $DIR/pattern-errors.rs:150:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -227,7 +227,7 @@ LL + let [&&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:139:11 + --> $DIR/pattern-errors.rs:157:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr new file mode 100644 index 0000000000000..1dda2dca4a48a --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 56125be2d6fc8..44cb005a748da 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:54:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:58:10 | LL | let [&mut ref x] = &[&mut 0]; | ^^^^^ @@ -12,14 +12,14 @@ LL + let [&ref x] = &[&mut 0]; | error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:9 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^^^ this matches on type `&_` @@ -29,20 +29,20 @@ LL | let &[ref mut x] = &[0]; | + error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 | LL | let [ref x] = &[0]; | ^^^^^^^ this matches on type `&_` @@ -52,14 +52,14 @@ LL | let &[ref x] = &[0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 | LL | let [ref x] = &mut [0]; | ^^^^^^^ this matches on type `&mut _` @@ -69,14 +69,14 @@ LL | let &mut [ref x] = &mut [0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:10 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:9 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^^^^^ this matches on type `&mut _` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs index 4e048570c33c2..ea6f028fe4b8b 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs @@ -1,35 +1,37 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //! Tests for errors from binding with `ref x` under a by-ref default binding mode in edition 2024. //! These can't be in the same body as tests for other errors, since they're emitted during THIR //! construction. The errors on stable edition 2021 Rust are unrelated. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] /// These only fail on the eat-inner variant of the new edition 2024 pattern typing rules. /// The eat-outer variant eats the inherited reference, so binding with `ref` isn't a problem. fn errors_from_eating_the_real_reference() { let [&ref x] = &[&0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; let [&ref x] = &mut [&0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; let [&mut ref x] = &mut [&mut 0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&mut ref mut x] = &mut [&mut 0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &mut u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &mut u32 = x; #[cfg(classic2024)] let _: &mut &mut u32 = x; } @@ -40,12 +42,14 @@ fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() { //[stable2021]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&ref x] = &mut [&mut 0]; //[stable2021]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; } @@ -55,7 +59,7 @@ fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; } /// These should be errors in all editions. In edition 2024, they should be caught by the pattern @@ -74,13 +78,13 @@ fn borrowck_errors_in_old_editions() { pub fn main() { let [ref x] = &[0]; //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; let [ref x] = &mut [0]; //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; let [ref mut x] = &mut [0]; //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &mut u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr index 26095d8460572..2ec6650dd7d0b 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:39:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:41:10 | LL | let [&ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -15,7 +15,7 @@ LL + let [ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:45:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:48:10 | LL | let [&ref x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -31,7 +31,7 @@ LL + let [ref x] = &mut [&mut 0]; | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr new file mode 100644 index 0000000000000..1dda2dca4a48a --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index 31930e8c03371..6f62ad06cc493 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -1,12 +1,12 @@ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:15:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:17:11 | LL | let [&ref x] = &[&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:15:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:17:9 | LL | let [&ref x] = &[&0]; | ^^^^^^^^ this matches on type `&_` @@ -16,14 +16,14 @@ LL | let &[&ref x] = &[&0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:20:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:22:11 | LL | let [&ref x] = &mut [&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:20:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:22:9 | LL | let [&ref x] = &mut [&0]; | ^^^^^^^^ this matches on type `&mut _` @@ -33,14 +33,14 @@ LL | let &mut [&ref x] = &mut [&0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:25:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:27:15 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:25:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:27:9 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^^^ this matches on type `&mut _` @@ -50,14 +50,14 @@ LL | let &mut [&mut ref x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:30:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:32:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:30:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:32:9 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^^^^^^^^^^ this matches on type `&mut _` @@ -67,14 +67,14 @@ LL | let &mut [&mut ref mut x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:39:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:41:11 | LL | let [&ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:39:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:41:9 | LL | let [&ref x] = &[&mut 0]; | ^^^^^^^^ this matches on type `&_` @@ -84,14 +84,14 @@ LL | let &[&ref x] = &[&mut 0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:45:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:48:11 | LL | let [&ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:45:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:48:9 | LL | let [&ref x] = &mut [&mut 0]; | ^^^^^^^^ this matches on type `&mut _` @@ -101,14 +101,14 @@ LL | let &mut [&ref x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:54:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:58:15 | LL | let [&mut ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:54:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:58:9 | LL | let [&mut ref x] = &[&mut 0]; | ^^^^^^^^^^^^ this matches on type `&_` @@ -118,14 +118,14 @@ LL | let &[&mut ref x] = &[&mut 0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:9 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^^^ this matches on type `&_` @@ -135,20 +135,20 @@ LL | let &[ref mut x] = &[0]; | + error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 | LL | let [ref x] = &[0]; | ^^^^^^^ this matches on type `&_` @@ -158,14 +158,14 @@ LL | let &[ref x] = &[0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 | LL | let [ref x] = &mut [0]; | ^^^^^^^ this matches on type `&mut _` @@ -175,14 +175,14 @@ LL | let &mut [ref x] = &mut [0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:10 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:9 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^^^^^ this matches on type `&mut _` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr new file mode 100644 index 0000000000000..379ba4a11c554 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr @@ -0,0 +1,63 @@ +error[E0308]: mismatched types + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:17 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types + | ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 + | +LL | let &pat!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:43:11 + | +LL | let &[x] = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0308, E0596. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed index c01784d5076b7..105313a14896d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-rustfix @@ -7,19 +9,19 @@ //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { - //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types + //[stable2021,classic2021,structural2021]~^ ERROR: mismatched types + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -28,18 +30,18 @@ pub fn main() { } let &mut pat!(x) = &mut 0; //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; let &mut (ref mut a, ref mut b) = &mut (true, false); //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern - //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &mut [x] = &mut &mut [0]; //[stable2021]~^ ERROR: mismatched types - //[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr index 5e98b77be40cd..93ddf4d60fd5c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr @@ -1,13 +1,13 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types | - ^ | | | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:20:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -15,7 +15,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:29:15 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 | LL | let &pat!(x) = &mut 0; | - ^ @@ -23,7 +23,7 @@ LL | let &pat!(x) = &mut 0; | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:19 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -31,7 +31,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:30 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -39,7 +39,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:41:11 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:43:11 | LL | let &[x] = &mut &mut [0]; | - ^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs index fe40dabb55394..800aca06396cb 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-rustfix @@ -7,19 +9,19 @@ //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { - //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types + //[stable2021,classic2021,structural2021]~^ ERROR: mismatched types + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -28,18 +30,18 @@ pub fn main() { } let &pat!(x) = &mut 0; //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; let &(ref mut a, ref mut b) = &mut (true, false); //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern - //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &[x] = &mut &mut [0]; //[stable2021]~^ ERROR: mismatched types - //[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr index 72c6c05e18443..9a3b896d4f842 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:17 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:17 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types | ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` | | | expected `Option<{integer}>`, found `&_` @@ -10,7 +10,7 @@ LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:20:12 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:12 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | ^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` @@ -21,7 +21,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:29:9 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:9 | LL | let &pat!(x) = &mut 0; | ^^^^^^^^ ------ this expression has type `&mut {integer}` @@ -32,7 +32,7 @@ LL | let &pat!(x) = &mut 0; found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:9 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:9 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | ^^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut (bool, bool)` @@ -43,7 +43,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:41:9 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:43:9 | LL | let &[x] = &mut &mut [0]; | ^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr new file mode 100644 index 0000000000000..1a138494b85a0 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr @@ -0,0 +1,55 @@ +error[E0308]: mismatched types + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:17 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types + | ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 + | +LL | let &pat!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0596. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed index 4ee849b38c53b..78fbffdb27033 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-rustfix @@ -7,19 +9,19 @@ //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { - //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types + //[stable2021,classic2021,structural2021]~^ ERROR: mismatched types + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -28,18 +30,18 @@ pub fn main() { } let &mut pat!(x) = &mut 0; //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; let &mut (ref mut a, ref mut b) = &mut (true, false); //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern - //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &[x] = &mut &mut [0]; //[stable2021]~^ ERROR: mismatched types - //[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr index 69cb6c438b6ed..11e39abb860b7 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr @@ -1,13 +1,13 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types | - ^ | | | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:20:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -15,7 +15,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:29:15 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 | LL | let &pat!(x) = &mut 0; | - ^ @@ -23,7 +23,7 @@ LL | let &pat!(x) = &mut 0; | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:19 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -31,7 +31,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:30 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr new file mode 100644 index 0000000000000..c9195dbfbf5f8 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr @@ -0,0 +1,254 @@ +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:32:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:39:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&x)) = &Some(&Some(0)) { +LL + if let Some(Some(x)) = &Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:44:17 + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:49:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:49:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { +LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:63:23 + | +LL | if let Some(&Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&Some(0)) { +LL + if let Some(&Some(x)) = &Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:70:17 + | +LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { + | ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected `Option<&mut Option<{integer}>>`, found `&_` + | + = note: expected enum `Option<&mut Option<{integer}>>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:75:17 + | +LL | if let Some(&Some(x)) = &mut Some(Some(0)) { + | ^^^^^^^^ ------------------ this expression has type `&mut Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:82:23 + | +LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:88:23 + | +LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { + | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &mut Some(&Some(0)) { +LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:96:10 + | +LL | let [&mut x] = &mut [&0]; + | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:96:10 + | +LL | let [&mut x] = &mut [&0]; + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut x] = &mut [&0]; +LL + let [x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:102:10 + | +LL | let [&mut ref x] = &mut [&0]; + | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:102:10 + | +LL | let [&mut ref x] = &mut [&0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut ref x] = &mut [&0]; +LL + let [ref x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:108:10 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:108:10 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut ref mut x] = &mut [&0]; +LL + let [ref mut x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:114:10 + | +LL | let [&mut mut x] = &mut [&0]; + | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:114:10 + | +LL | let [&mut mut x] = &mut [&0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut mut x] = &mut [&0]; +LL + let [mut x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:120:10 + | +LL | let [&mut &x] = &mut [&0]; + | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:126:10 + | +LL | let [&mut &ref x] = &mut [&0]; + | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:132:10 + | +LL | let [&mut &(mut x)] = &mut [&0]; + | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` + +error: aborting due to 16 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 3114b9d3bf8cb..e61aa5f35c9a2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-pass @@ -7,8 +9,8 @@ //! Test cases for well-typed patterns in edition 2024. These are in their own file to ensure we //! pass both HIR typeck and MIR borrowck, as we may skip the latter if grouped with failing tests. #![allow(incomplete_features, unused_mut)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { // Tests not using match ergonomics. These should always succeed with the same bindings. @@ -18,110 +20,118 @@ pub fn main() { // Tests for differences in how many layers of reference are eaten by reference patterns if let Some(Some(&x)) = &Some(Some(&0)) { - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; } if let Some(&Some(x)) = &mut Some(&Some(0)) { // This additionally tests that `&` patterns can eat inherited `&mut` refs. // This is possible on stable when the real reference being eaten is of a `&` type. - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; } if let Some(Some(&&x)) = &Some(Some(&0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } // Tests for eating a lone inherited reference if let Some(Some(&x)) = &Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` } if let Some(&Some(x)) = &Some(Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected `Option<{integer}>`, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected `Option<{integer}>`, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` } if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&mut _` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&mut _` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` } // Tests for `&` patterns matching real `&mut` reference types if let Some(&Some(&x)) = Some(&Some(&mut 0)) { //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: u32 = x; + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests for eating only one layer and also eating a lone inherited reference if let Some(&Some(&x)) = &Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } // Tests for `&` matching a lone inherited possibly-`&mut` reference if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { - //[stable2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~^ mismatched types //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` - let _: u32 = x; + #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` } if let Some(&Some(x)) = &mut Some(Some(0)) { - //[stable2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~^ mismatched types //[stable2021]~| expected `Option<{integer}>`, found `&_` - let _: u32 = x; + #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` } // Tests eating one layer, eating a lone inherited ref, and `&` eating `&mut` (realness varies) if let Some(&Some(&x)) = &Some(&mut Some(0)) { - //[stable2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: u32 = x; + //[classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(&x)) = &mut Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } // Tests for eat-inner rulesets matching on the outer reference if matching on the inner // reference causes a mutability mismatch, i.e. `Deref(EatInner, FallbackToOuter)`: let [&mut x] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: &u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| types differ in mutability + // TODO: on `structural2021` `x` should have type `u32` + #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut ref x] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: &&u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| types differ in mutability + // TODO: on `structural2021` `x` should have type `&u32` + #[cfg(any(classic2024, structural2024))] let _: &&u32 = x; let [&mut ref mut x] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: &mut &u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| types differ in mutability + // TODO: this should be a mut borrow behind shared borrow error on `structural2021` + #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x; let [&mut mut x] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: &u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| types differ in mutability + // TODO: on `structural2021` `x` should have type `u32` + #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &x] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| types differ in mutability + // TODO: [structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; let [&mut &ref x] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: &u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| types differ in mutability + // TODO: [structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &(mut x)] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| types differ in mutability + // TODO: [structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr index b1a8024397bdc..fb99e3983e8cc 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:30:23 + --> $DIR/well-typed-edition-2024.rs:32:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -15,7 +15,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:37:22 + --> $DIR/well-typed-edition-2024.rs:39:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -31,7 +31,7 @@ LL + if let Some(Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:42:17 + --> $DIR/well-typed-edition-2024.rs:44:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -42,7 +42,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:47:22 + --> $DIR/well-typed-edition-2024.rs:49:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -52,7 +52,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:47:22 + --> $DIR/well-typed-edition-2024.rs:49:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -63,7 +63,7 @@ LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:54:23 + --> $DIR/well-typed-edition-2024.rs:56:23 | LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) { | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` @@ -79,7 +79,7 @@ LL + if let Some(&Some(x)) = Some(&Some(&mut 0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:61:23 + --> $DIR/well-typed-edition-2024.rs:63:23 | LL | if let Some(&Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -95,7 +95,7 @@ LL + if let Some(&Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:68:17 + --> $DIR/well-typed-edition-2024.rs:70:17 | LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` @@ -106,7 +106,7 @@ LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:73:17 + --> $DIR/well-typed-edition-2024.rs:75:17 | LL | if let Some(&Some(x)) = &mut Some(Some(0)) { | ^^^^^^^^ ------------------ this expression has type `&mut Option>` @@ -117,7 +117,7 @@ LL | if let Some(&Some(x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:80:17 + --> $DIR/well-typed-edition-2024.rs:82:17 | LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -128,7 +128,7 @@ LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:85:23 + --> $DIR/well-typed-edition-2024.rs:88:23 | LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -144,7 +144,7 @@ LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:93:10 + --> $DIR/well-typed-edition-2024.rs:96:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -154,7 +154,7 @@ LL | let [&mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:93:10 + --> $DIR/well-typed-edition-2024.rs:96:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ @@ -165,7 +165,7 @@ LL + let [x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:98:10 + --> $DIR/well-typed-edition-2024.rs:102:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -175,7 +175,7 @@ LL | let [&mut ref x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:98:10 + --> $DIR/well-typed-edition-2024.rs:102:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ @@ -186,7 +186,7 @@ LL + let [ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:103:10 + --> $DIR/well-typed-edition-2024.rs:108:10 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -196,7 +196,7 @@ LL | let [&mut ref mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:103:10 + --> $DIR/well-typed-edition-2024.rs:108:10 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL + let [ref mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:108:10 + --> $DIR/well-typed-edition-2024.rs:114:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -217,7 +217,7 @@ LL | let [&mut mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:108:10 + --> $DIR/well-typed-edition-2024.rs:114:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ @@ -228,7 +228,7 @@ LL + let [mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:113:10 + --> $DIR/well-typed-edition-2024.rs:120:10 | LL | let [&mut &x] = &mut [&0]; | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -239,7 +239,7 @@ LL | let [&mut &x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:118:10 + --> $DIR/well-typed-edition-2024.rs:126:10 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -250,7 +250,7 @@ LL | let [&mut &ref x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:123:10 + --> $DIR/well-typed-edition-2024.rs:132:10 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr new file mode 100644 index 0000000000000..c9195dbfbf5f8 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr @@ -0,0 +1,254 @@ +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:32:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:39:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&x)) = &Some(&Some(0)) { +LL + if let Some(Some(x)) = &Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:44:17 + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:49:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:49:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { +LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:63:23 + | +LL | if let Some(&Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&Some(0)) { +LL + if let Some(&Some(x)) = &Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:70:17 + | +LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { + | ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected `Option<&mut Option<{integer}>>`, found `&_` + | + = note: expected enum `Option<&mut Option<{integer}>>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:75:17 + | +LL | if let Some(&Some(x)) = &mut Some(Some(0)) { + | ^^^^^^^^ ------------------ this expression has type `&mut Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:82:23 + | +LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:88:23 + | +LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { + | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &mut Some(&Some(0)) { +LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:96:10 + | +LL | let [&mut x] = &mut [&0]; + | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:96:10 + | +LL | let [&mut x] = &mut [&0]; + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut x] = &mut [&0]; +LL + let [x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:102:10 + | +LL | let [&mut ref x] = &mut [&0]; + | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:102:10 + | +LL | let [&mut ref x] = &mut [&0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut ref x] = &mut [&0]; +LL + let [ref x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:108:10 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:108:10 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut ref mut x] = &mut [&0]; +LL + let [ref mut x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:114:10 + | +LL | let [&mut mut x] = &mut [&0]; + | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:114:10 + | +LL | let [&mut mut x] = &mut [&0]; + | ^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut mut x] = &mut [&0]; +LL + let [mut x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:120:10 + | +LL | let [&mut &x] = &mut [&0]; + | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:126:10 + | +LL | let [&mut &ref x] = &mut [&0]; + | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:132:10 + | +LL | let [&mut &(mut x)] = &mut [&0]; + | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` + +error: aborting due to 16 previous errors + +For more information about this error, try `rustc --explain E0308`. From 3e77657312dbd7da6a398825860b01e838893b3c Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 23 Jan 2025 00:21:17 -0800 Subject: [PATCH 17/26] remove old edition-2021-specific tests These are superseded by the old-edition revisions on the shared tests. --- .../ref_pat_eat_one_layer_2021.rs | 17 --- .../ref_pat_eat_one_layer_2021_fail.rs | 37 ----- .../ref_pat_eat_one_layer_2021_fail.stderr | 133 ------------------ 3 files changed, 187 deletions(-) delete mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs delete mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs delete mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs deleted file mode 100644 index ab3264704acc0..0000000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -//@ edition: 2021 -//@ revisions: classic structural -#![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] - -pub fn main() { - #[cfg(structural)] - if let &Some(Some(x)) = &Some(&mut Some(0)) { - let _: &u32 = x; - } - - if let Some(&x) = Some(&mut 0) { - let _: u32 = x; - } -} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs deleted file mode 100644 index d28567f2859a3..0000000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ edition: 2021 -#![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] -pub fn main() { - if let Some(Some(&x)) = &Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&x)) = &Some(Some(&0)) { - let _: &u32 = x; - //~^ ERROR: mismatched types - } - if let Some(Some(&&x)) = &Some(Some(&0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&Some(x)) = &Some(Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&x)) = &Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } -} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr deleted file mode 100644 index 0158ed0f42357..0000000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr +++ /dev/null @@ -1,133 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:5:22 - | -LL | if let Some(Some(&x)) = &Some(&Some(0)) { - | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&x)) = &Some(&Some(0)) { -LL + if let Some(Some(x)) = &Some(&Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:10:23 - | -LL | let _: &u32 = x; - | ---- ^ expected `&u32`, found integer - | | - | expected due to this - | -help: consider borrowing here - | -LL | let _: &u32 = &x; - | + - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:13:23 - | -LL | if let Some(Some(&&x)) = &Some(Some(&0)) { - | ^^ --------------- this expression has type `&Option>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&&x)) = &Some(Some(&0)) { -LL + if let Some(Some(&x)) = &Some(Some(&0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:17:17 - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { -LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:25:22 - | -LL | if let Some(Some(&x)) = &Some(&Some(0)) { - | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&x)) = &Some(&Some(0)) { -LL + if let Some(Some(x)) = &Some(&Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:29:27 - | -LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { -LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 - | -LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { - | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 - | -LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { -LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { - | - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0308`. From 8dc64a405d53f30fef4a080afb68d10e59318a3d Mon Sep 17 00:00:00 2001 From: dianne Date: Sat, 25 Jan 2025 23:32:12 -0800 Subject: [PATCH 18/26] "classic2021" and "structural2021" rulesets: add eat-inherited-ref-alone deref rules --- compiler/rustc_hir_typeck/src/pat.rs | 39 +++- .../pattern-errors.classic2021.stderr | 167 ++---------------- .../pattern-errors.classic2024.stderr | 10 +- .../experimental/pattern-errors.rs | 54 +++--- .../pattern-errors.stable2021.stderr | 38 ++-- .../pattern-errors.structural2021.stderr | 154 ++++++---------- .../pattern-errors.structural2024.stderr | 30 ++-- ...t-inside-shared-ref-pat.classic2021.stderr | 18 +- ...ut-inside-shared-ref-pat.classic2024.fixed | 4 +- ...t-inside-shared-ref-pat.classic2024.stderr | 2 +- .../ref-mut-inside-shared-ref-pat.rs | 4 +- ...ut-inside-shared-ref-pat.stable2021.stderr | 2 +- ...nside-shared-ref-pat.structural2021.stderr | 18 +- ...inside-shared-ref-pat.structural2024.fixed | 4 +- ...nside-shared-ref-pat.structural2024.stderr | 2 +- ...well-typed-edition-2024.classic2021.stderr | 72 +------- .../experimental/well-typed-edition-2024.rs | 26 +-- ...l-typed-edition-2024.structural2021.stderr | 72 +------- 18 files changed, 195 insertions(+), 521 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ae00bb4e218ab..47175cda63b88 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -230,10 +230,12 @@ enum InheritedRefMatchRule { /// underlying type is not a reference type, the inherited reference will be consumed. EatInner, /// When the underlying type is a reference type, reference patterns consume both layers of - /// reference, i.e. they both reset the binding mode and consume the reference type. Reference - /// patterns are not permitted when there is no underlying reference type, i.e. they can't eat - /// only an inherited reference. This is the current stable Rust behavior. - EatBoth, + /// reference, i.e. they both reset the binding mode and consume the reference type. + EatBoth { + /// Whether to allow reference patterns to consume only an inherited reference when matching + /// against a non-reference type. This is `false` for stable Rust. + eat_inherited_ref_alone: bool, + }, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -259,10 +261,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Currently, matching against an inherited ref on edition 2024 is an error. // Use `EatBoth` as a fallback to be similar to stable Rust. - InheritedRefMatchRule::EatBoth + InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: false } } } else { - InheritedRefMatchRule::EatBoth + InheritedRefMatchRule::EatBoth { + eat_inherited_ref_alone: self.tcx.features().ref_pat_eat_one_layer_2024() + || self.tcx.features().ref_pat_eat_one_layer_2024_structural(), + } } } @@ -2381,9 +2386,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - InheritedRefMatchRule::EatBoth => { + InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: true } => { // Reset binding mode on old editions pat_info.binding_mode = ByRef::No; + + if let ty::Ref(_, _, _) = *expected.kind() { + // Consume both the inherited and inner references. + } else { + // The expected type isn't a reference type, so only match against the + // inherited reference. + if pat_mutbl > inh_mut { + // We can't match a lone inherited shared reference with `&mut`. + self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span); + } + + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; + } + } + InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: false } => { + // Reset binding mode on stable Rust. This will be a type error below if + // `expected` is not a reference type. + pat_info.binding_mode = ByRef::No; self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr index e039884cdb14b..a856a0eaf2a7c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr @@ -58,155 +58,20 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:50:17 - | -LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { - | ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` - | | - | expected `Option<&mut Option<{integer}>>`, found `&_` - | - = note: expected enum `Option<&mut Option<{integer}>>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:57:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&mut _` - | - = note: expected enum `Option<{integer}>` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:66:11 - | -LL | let &[&mut x] = &&mut [0]; - | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:66:11 - | -LL | let &[&mut x] = &&mut [0]; - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let &[&mut x] = &&mut [0]; -LL + let &[x] = &&mut [0]; - | - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:73:11 - | -LL | let &[&mut x] = &mut &mut [0]; - | ^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:73:11 - | -LL | let &[&mut x] = &mut &mut [0]; - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let &[&mut x] = &mut &mut [0]; -LL + let &[x] = &mut &mut [0]; - | - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:80:11 - | -LL | let &[&mut ref x] = &&mut [0]; - | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:80:11 - | -LL | let &[&mut ref x] = &&mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let &[&mut ref x] = &&mut [0]; -LL + let &[ref x] = &&mut [0]; - | - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:87:11 - | -LL | let &[&mut ref x] = &mut &mut [0]; - | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:87:11 - | -LL | let &[&mut ref x] = &mut &mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let &[&mut ref x] = &mut &mut [0]; -LL + let &[ref x] = &mut &mut [0]; - | - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:94:11 + | ^^^^^ | -LL | let &[&mut mut x] = &&mut [0]; - | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:94:11 - | -LL | let &[&mut mut x] = &&mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let &[&mut mut x] = &&mut [0]; -LL + let &[mut x] = &&mut [0]; - | - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:11 - | -LL | let &[&mut mut x] = &mut &mut [0]; - | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:101:11 - | -LL | let &[&mut mut x] = &mut &mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | -LL - let &[&mut mut x] = &mut &mut [0]; -LL + let &[mut x] = &mut &mut [0]; +LL - if let Some(&mut Some(x)) = &Some(Some(0)) { +LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:122:11 + --> $DIR/pattern-errors.rs:114:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -222,7 +87,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:129:11 + --> $DIR/pattern-errors.rs:121:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -238,7 +103,7 @@ LL + let [&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:136:11 + --> $DIR/pattern-errors.rs:128:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -254,7 +119,7 @@ LL + let [&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:143:11 + --> $DIR/pattern-errors.rs:135:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -270,7 +135,7 @@ LL + let [&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:150:11 + --> $DIR/pattern-errors.rs:142:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -286,7 +151,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:157:11 + --> $DIR/pattern-errors.rs:149:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -302,7 +167,7 @@ LL + let [&mut x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:172:15 + --> $DIR/pattern-errors.rs:164:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -318,7 +183,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:178:15 + --> $DIR/pattern-errors.rs:170:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -334,7 +199,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:184:15 + --> $DIR/pattern-errors.rs:176:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -349,6 +214,6 @@ LL - let [&mut &(mut x)] = &[&mut 0]; LL + let [&mut mut x)] = &[&mut 0]; | -error: aborting due to 21 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr index b98cfe337efee..90510d23e6614 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr @@ -64,7 +64,7 @@ LL + if let Some(&Some(&_)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:57:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -77,7 +77,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:166:10 + --> $DIR/pattern-errors.rs:158:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:172:10 + --> $DIR/pattern-errors.rs:164:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:178:10 + --> $DIR/pattern-errors.rs:170:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:184:10 + --> $DIR/pattern-errors.rs:176:10 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index 4173b1819cba5..5e677445644a6 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs @@ -48,62 +48,54 @@ pub fn main() { //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { - //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too - #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold on `classic2021` too + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types - //[stable2021,classic2021,structural2021]~| expected `Option<{integer}>`, found `&mut _` - //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `classic2021` and `structural2021` should be the mutability mismatch + //[stable2021]~| expected `Option<{integer}>`, found `&mut _` + //[classic2021,structural2021,classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } } fn structural_errors_0() { let &[&mut x] = &&mut [0]; - //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too - #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut x] = &mut &mut [0]; - //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too - #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut ref x] = &&mut [0]; - //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too - #[cfg(classic2024)] let _: &u32 = x; // TODO: this should hold for `classic2021` too + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: &u32 = x; let &[&mut ref x] = &mut &mut [0]; - //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too - #[cfg(classic2024)] let _: &u32 = x; // TODO: this should hold for `classic2021` too + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: &u32 = x; let &[&mut mut x] = &&mut [0]; - //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too - #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut mut x] = &mut &mut [0]; - //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - // TODO: the error on `structural2021` should be an inherited ref mutability mismatch too - #[cfg(classic2024)] let _: u32 = x; // TODO: this should hold for `classic2021` too + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; } fn structural_errors_1() { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr index ad9541b71a028..76e6d2f562a27 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr @@ -59,7 +59,7 @@ LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:57:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -70,7 +70,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:66:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -80,7 +80,7 @@ LL | let &[&mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:66:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ @@ -91,7 +91,7 @@ LL + let &[x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:73:9 + --> $DIR/pattern-errors.rs:70:9 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -102,7 +102,7 @@ LL | let &[&mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:80:11 + --> $DIR/pattern-errors.rs:76:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -112,7 +112,7 @@ LL | let &[&mut ref x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:80:11 + --> $DIR/pattern-errors.rs:76:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ @@ -123,7 +123,7 @@ LL + let &[ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:87:9 + --> $DIR/pattern-errors.rs:82:9 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -134,7 +134,7 @@ LL | let &[&mut ref x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:94:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -144,7 +144,7 @@ LL | let &[&mut mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:94:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let &[mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:9 + --> $DIR/pattern-errors.rs:94:9 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -166,7 +166,7 @@ LL | let &[&mut mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:122:10 + --> $DIR/pattern-errors.rs:114:10 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -177,7 +177,7 @@ LL | let [&&mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:129:10 + --> $DIR/pattern-errors.rs:121:10 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -188,7 +188,7 @@ LL | let [&&mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:136:10 + --> $DIR/pattern-errors.rs:128:10 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -199,7 +199,7 @@ LL | let [&&mut ref x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:143:10 + --> $DIR/pattern-errors.rs:135:10 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -210,7 +210,7 @@ LL | let [&&mut ref x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:150:10 + --> $DIR/pattern-errors.rs:142:10 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -221,7 +221,7 @@ LL | let [&&mut mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:157:10 + --> $DIR/pattern-errors.rs:149:10 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -232,7 +232,7 @@ LL | let [&&mut mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:172:15 + --> $DIR/pattern-errors.rs:164:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -248,7 +248,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:178:15 + --> $DIR/pattern-errors.rs:170:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -264,7 +264,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:184:15 + --> $DIR/pattern-errors.rs:176:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr index e039884cdb14b..1ca6bff3f38c3 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr @@ -58,155 +58,111 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:50:17 + --> $DIR/pattern-errors.rs:50:28 | LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { - | ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` - | | - | expected `Option<&mut Option<{integer}>>`, found `&_` + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { +LL + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | - = note: expected enum `Option<&mut Option<{integer}>>` - found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:57:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&mut _` + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - if let Some(&mut Some(x)) = &Some(Some(0)) { +LL + if let Some(&Some(x)) = &Some(Some(0)) { | - = note: expected enum `Option<{integer}>` - found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:66:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut x] = &&mut [0]; - | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` - | | - | expected integer, found `&mut _` + | ^^^^^ | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:66:11 - | -LL | let &[&mut x] = &&mut [0]; - | ^^^^^^ -help: consider removing `&mut` from the pattern + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | LL - let &[&mut x] = &&mut [0]; -LL + let &[x] = &&mut [0]; +LL + let &[&x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:73:11 + --> $DIR/pattern-errors.rs:70:11 | LL | let &[&mut x] = &mut &mut [0]; - | ^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` - | | - | expected integer, found `&mut _` + | ^^^^^ | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:73:11 - | -LL | let &[&mut x] = &mut &mut [0]; - | ^^^^^^ -help: consider removing `&mut` from the pattern + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | LL - let &[&mut x] = &mut &mut [0]; -LL + let &[x] = &mut &mut [0]; +LL + let &[&x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:80:11 + --> $DIR/pattern-errors.rs:76:11 | LL | let &[&mut ref x] = &&mut [0]; - | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` - | | - | expected integer, found `&mut _` + | ^^^^^ | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:80:11 - | -LL | let &[&mut ref x] = &&mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | LL - let &[&mut ref x] = &&mut [0]; -LL + let &[ref x] = &&mut [0]; +LL + let &[&ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:87:11 + --> $DIR/pattern-errors.rs:82:11 | LL | let &[&mut ref x] = &mut &mut [0]; - | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` - | | - | expected integer, found `&mut _` + | ^^^^^ | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:87:11 - | -LL | let &[&mut ref x] = &mut &mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | LL - let &[&mut ref x] = &mut &mut [0]; -LL + let &[ref x] = &mut &mut [0]; +LL + let &[&ref x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:94:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let &[&mut mut x] = &&mut [0]; - | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` - | | - | expected integer, found `&mut _` + | ^^^^^ | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:94:11 - | -LL | let &[&mut mut x] = &&mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | LL - let &[&mut mut x] = &&mut [0]; -LL + let &[mut x] = &&mut [0]; +LL + let &[&mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:11 + --> $DIR/pattern-errors.rs:94:11 | LL | let &[&mut mut x] = &mut &mut [0]; - | ^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` - | | - | expected integer, found `&mut _` + | ^^^^^ | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:101:11 - | -LL | let &[&mut mut x] = &mut &mut [0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | LL - let &[&mut mut x] = &mut &mut [0]; -LL + let &[mut x] = &mut &mut [0]; +LL + let &[&mut x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:122:11 + --> $DIR/pattern-errors.rs:114:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -222,7 +178,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:129:11 + --> $DIR/pattern-errors.rs:121:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -238,7 +194,7 @@ LL + let [&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:136:11 + --> $DIR/pattern-errors.rs:128:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -254,7 +210,7 @@ LL + let [&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:143:11 + --> $DIR/pattern-errors.rs:135:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -270,7 +226,7 @@ LL + let [&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:150:11 + --> $DIR/pattern-errors.rs:142:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -286,7 +242,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:157:11 + --> $DIR/pattern-errors.rs:149:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -302,7 +258,7 @@ LL + let [&mut x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:172:15 + --> $DIR/pattern-errors.rs:164:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -318,7 +274,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:178:15 + --> $DIR/pattern-errors.rs:170:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -334,7 +290,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:184:15 + --> $DIR/pattern-errors.rs:176:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr index 950d9f8b35110..3658893df9cc1 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr @@ -51,7 +51,7 @@ LL + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:57:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -64,7 +64,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:66:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -77,7 +77,7 @@ LL + let &[&x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:73:11 + --> $DIR/pattern-errors.rs:70:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let &[&x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:80:11 + --> $DIR/pattern-errors.rs:76:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let &[&ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:87:11 + --> $DIR/pattern-errors.rs:82:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let &[&ref x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:94:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -129,7 +129,7 @@ LL + let &[&mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:11 + --> $DIR/pattern-errors.rs:94:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -142,7 +142,7 @@ LL + let &[&mut x] = &mut &mut [0]; | error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:110:12 + --> $DIR/pattern-errors.rs:102:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -152,7 +152,7 @@ LL | let [&(mut x)] = &[&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:115:12 + --> $DIR/pattern-errors.rs:107:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -162,7 +162,7 @@ LL | let [&(mut x)] = &mut [&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:122:11 + --> $DIR/pattern-errors.rs:114:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -175,7 +175,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:129:11 + --> $DIR/pattern-errors.rs:121:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -188,7 +188,7 @@ LL + let [&&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:136:11 + --> $DIR/pattern-errors.rs:128:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -201,7 +201,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:143:11 + --> $DIR/pattern-errors.rs:135:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -214,7 +214,7 @@ LL + let [&&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:150:11 + --> $DIR/pattern-errors.rs:142:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -227,7 +227,7 @@ LL + let [&&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:157:11 + --> $DIR/pattern-errors.rs:149:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr index 379ba4a11c554..8127ca92e025e 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr @@ -1,18 +1,7 @@ -error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:17 - | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types - | ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - error[E0596]: cannot borrow as mutable inside an `&` pattern --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ | | | help: replace this `&` with `&mut`: `&mut` @@ -57,7 +46,6 @@ LL | let &[x] = &mut &mut [0]; | | | help: replace this `&` with `&mut`: `&mut` -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0308, E0596. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed index 105313a14896d..57de9cb4c10d0 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed @@ -13,8 +13,8 @@ #![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types - //[stable2021,classic2021,structural2021]~^ ERROR: mismatched types + if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { + //[stable2021]~^ ERROR: mismatched types //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr index 93ddf4d60fd5c..8127ca92e025e 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr @@ -1,7 +1,7 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ | | | help: replace this `&` with `&mut`: `&mut` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs index 800aca06396cb..277ff90b673ce 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs @@ -13,8 +13,8 @@ #![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types - //[stable2021,classic2021,structural2021]~^ ERROR: mismatched types + if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + //[stable2021]~^ ERROR: mismatched types //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr index 9a3b896d4f842..5fbaacd7281d2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr @@ -1,7 +1,7 @@ error[E0308]: mismatched types --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:17 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` | | | expected `Option<{integer}>`, found `&_` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr index 1a138494b85a0..e735cfed2492f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr @@ -1,18 +1,7 @@ -error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:17 - | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types - | ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - error[E0596]: cannot borrow as mutable inside an `&` pattern --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ | | | help: replace this `&` with `&mut`: `&mut` @@ -49,7 +38,6 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | | | help: replace this `&` with `&mut`: `&mut` -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0308, E0596. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed index 78fbffdb27033..bcde4b90f592c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed @@ -13,8 +13,8 @@ #![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types - //[stable2021,classic2021,structural2021]~^ ERROR: mismatched types + if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { + //[stable2021]~^ ERROR: mismatched types //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr index 11e39abb860b7..e735cfed2492f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr @@ -1,7 +1,7 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | -LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { // TODO: `classic2021` and `structural2021` shouldn't have mismatched types +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ | | | help: replace this `&` with `&mut`: `&mut` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr index c9195dbfbf5f8..f784d7e9988db 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr @@ -14,54 +14,6 @@ LL - if let Some(Some(&&x)) = &Some(Some(&0)) { LL + if let Some(Some(&x)) = &Some(Some(&0)) { | -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:39:22 - | -LL | if let Some(Some(&x)) = &Some(&Some(0)) { - | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&x)) = &Some(&Some(0)) { -LL + if let Some(Some(x)) = &Some(&Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:44:17 - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:49:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:49:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { -LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { - | - error[E0308]: mismatched types --> $DIR/well-typed-edition-2024.rs:63:23 | @@ -78,28 +30,6 @@ LL - if let Some(&Some(&x)) = &Some(&Some(0)) { LL + if let Some(&Some(x)) = &Some(&Some(0)) { | -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:70:17 - | -LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { - | ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` - | | - | expected `Option<&mut Option<{integer}>>`, found `&_` - | - = note: expected enum `Option<&mut Option<{integer}>>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:75:17 - | -LL | if let Some(&Some(x)) = &mut Some(Some(0)) { - | ^^^^^^^^ ------------------ this expression has type `&mut Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - error[E0308]: mismatched types --> $DIR/well-typed-edition-2024.rs:82:23 | @@ -249,6 +179,6 @@ LL | let [&mut &(mut x)] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` -error: aborting due to 16 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index e61aa5f35c9a2..851011918fe95 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -37,19 +37,19 @@ pub fn main() { // Tests for eating a lone inherited reference if let Some(Some(&x)) = &Some(&Some(0)) { - //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| expected integer, found `&_` - #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&_` + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(x)) = &Some(Some(0)) { - //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| expected `Option<{integer}>`, found `&_` - #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` + //[stable2021]~^ mismatched types + //[stable2021]~| expected `Option<{integer}>`, found `&_` + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| expected integer, found `&mut _` - #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&mut _` + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests for `&` patterns matching real `&mut` reference types @@ -68,14 +68,14 @@ pub fn main() { // Tests for `&` matching a lone inherited possibly-`&mut` reference if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { - //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021]~^ mismatched types //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` - #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(x)) = &mut Some(Some(0)) { - //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021]~^ mismatched types //[stable2021]~| expected `Option<{integer}>`, found `&_` - #[cfg(any(classic2024, structural2024))] let _: u32 = x; // TODO: this should hold on `classic2021` and `structural2021` + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests eating one layer, eating a lone inherited ref, and `&` eating `&mut` (realness varies) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr index c9195dbfbf5f8..f784d7e9988db 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr @@ -14,54 +14,6 @@ LL - if let Some(Some(&&x)) = &Some(Some(&0)) { LL + if let Some(Some(&x)) = &Some(Some(&0)) { | -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:39:22 - | -LL | if let Some(Some(&x)) = &Some(&Some(0)) { - | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&x)) = &Some(&Some(0)) { -LL + if let Some(Some(x)) = &Some(&Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:44:17 - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:49:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:49:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { -LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { - | - error[E0308]: mismatched types --> $DIR/well-typed-edition-2024.rs:63:23 | @@ -78,28 +30,6 @@ LL - if let Some(&Some(&x)) = &Some(&Some(0)) { LL + if let Some(&Some(x)) = &Some(&Some(0)) { | -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:70:17 - | -LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { - | ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` - | | - | expected `Option<&mut Option<{integer}>>`, found `&_` - | - = note: expected enum `Option<&mut Option<{integer}>>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:75:17 - | -LL | if let Some(&Some(x)) = &mut Some(Some(0)) { - | ^^^^^^^^ ------------------ this expression has type `&mut Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - error[E0308]: mismatched types --> $DIR/well-typed-edition-2024.rs:82:23 | @@ -249,6 +179,6 @@ LL | let [&mut &(mut x)] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` -error: aborting due to 16 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0308`. From 443c51d5d6eb0903e3eef9a44e1dfb017e69958d Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 26 Jan 2025 00:27:37 -0800 Subject: [PATCH 19/26] "structural2021" ruleset: add fallback-to-outer (eat both) deref rule --- compiler/rustc_hir_typeck/src/pat.rs | 43 +++++- ...well-typed-edition-2024.classic2021.stderr | 52 +++---- .../experimental/well-typed-edition-2024.rs | 47 +++--- .../well-typed-edition-2024.stable2021.stderr | 52 +++---- ...l-typed-edition-2024.structural2021.stderr | 136 +++++------------- 5 files changed, 151 insertions(+), 179 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 47175cda63b88..be72af63fe50f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -235,6 +235,9 @@ enum InheritedRefMatchRule { /// Whether to allow reference patterns to consume only an inherited reference when matching /// against a non-reference type. This is `false` for stable Rust. eat_inherited_ref_alone: bool, + /// Whether to allow a `&mut` reference pattern to eat a `&` reference type if it's also + /// able to consume a mutable inherited reference. This is `false` for stable Rust. + fallback_to_outer: bool, }, } @@ -261,12 +264,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Currently, matching against an inherited ref on edition 2024 is an error. // Use `EatBoth` as a fallback to be similar to stable Rust. - InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: false } + InheritedRefMatchRule::EatBoth { + eat_inherited_ref_alone: false, + fallback_to_outer: false, + } } } else { + let has_structural_gate = self.tcx.features().ref_pat_eat_one_layer_2024_structural(); InheritedRefMatchRule::EatBoth { - eat_inherited_ref_alone: self.tcx.features().ref_pat_eat_one_layer_2024() - || self.tcx.features().ref_pat_eat_one_layer_2024_structural(), + eat_inherited_ref_alone: has_structural_gate + || self.tcx.features().ref_pat_eat_one_layer_2024(), + fallback_to_outer: has_structural_gate, } } } @@ -2386,12 +2394,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: true } => { + InheritedRefMatchRule::EatBoth { + eat_inherited_ref_alone: true, + fallback_to_outer, + } => { // Reset binding mode on old editions pat_info.binding_mode = ByRef::No; - if let ty::Ref(_, _, _) = *expected.kind() { + if let ty::Ref(_, inner_ty, _) = *expected.kind() { // Consume both the inherited and inner references. + if fallback_to_outer && inh_mut.is_mut() { + // If we can fall back to matching the inherited reference, the expected + // type is a reference type (of any mutability), and the inherited + // reference is mutable, we'll always be able to match. We handle that + // here to avoid adding fallback-to-outer to the common logic below. + // NB: This way of phrasing the logic will catch more cases than those + // that need to fall back to matching the inherited reference. However, + // as long as `&` patterns can match mutable (inherited) references + // (RFC 3627, Rule 5) this should be sound. + debug_assert!(ref_pat_matches_mut_ref); + self.check_pat(inner, inner_ty, pat_info); + return expected; + } else { + // Otherwise, use the common logic below for matching the inner + // reference type. + } } else { // The expected type isn't a reference type, so only match against the // inherited reference. @@ -2405,9 +2432,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - InheritedRefMatchRule::EatBoth { eat_inherited_ref_alone: false } => { + rule @ InheritedRefMatchRule::EatBoth { + eat_inherited_ref_alone: false, + fallback_to_outer, + } => { // Reset binding mode on stable Rust. This will be a type error below if // `expected` is not a reference type. + debug_assert!(!fallback_to_outer, "typing rule `{rule:?}` is unimplemented."); pat_info.binding_mode = ByRef::No; self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr index f784d7e9988db..086d4bb133ba2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr @@ -105,28 +105,7 @@ LL + let [ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:108:10 - | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:108:10 - | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut ref mut x] = &mut [&0]; -LL + let [ref mut x] = &mut [&0]; - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:114:10 + --> $DIR/well-typed-edition-2024.rs:117:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -136,7 +115,7 @@ LL | let [&mut mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:114:10 + --> $DIR/well-typed-edition-2024.rs:117:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ @@ -147,7 +126,7 @@ LL + let [mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:120:10 + --> $DIR/well-typed-edition-2024.rs:123:10 | LL | let [&mut &x] = &mut [&0]; | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -158,7 +137,7 @@ LL | let [&mut &x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:126:10 + --> $DIR/well-typed-edition-2024.rs:129:10 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -169,7 +148,7 @@ LL | let [&mut &ref x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:132:10 + --> $DIR/well-typed-edition-2024.rs:135:10 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -179,6 +158,27 @@ LL | let [&mut &(mut x)] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:109:14 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:109:14 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut ref mut x] = &mut [&0]; +LL + let [ref mut x] = &mut [&0]; + | + error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 851011918fe95..63a09fe90c9f2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -91,47 +91,50 @@ pub fn main() { #[cfg(any(classic2024, structural2024))] let _: u32 = x; } - // Tests for eat-inner rulesets matching on the outer reference if matching on the inner - // reference causes a mutability mismatch, i.e. `Deref(EatInner, FallbackToOuter)`: + // Tests for eat-inner and eat-both rulesets matching on the outer reference if matching on the + // inner reference causes a mutability mismatch. i.e. tests for "fallback-to-outer" deref rules. let [&mut x] = &mut [&0]; - //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - // TODO: on `structural2021` `x` should have type `u32` + //[stable2021,classic2021]~^ mismatched types + //[stable2021,classic2021]~| types differ in mutability + #[cfg(structural2021)] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut ref x] = &mut [&0]; - //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - // TODO: on `structural2021` `x` should have type `&u32` + //[stable2021,classic2021]~^ mismatched types + //[stable2021,classic2021]~| types differ in mutability + #[cfg(structural2021)] let _: &u32 = x; #[cfg(any(classic2024, structural2024))] let _: &&u32 = x; - let [&mut ref mut x] = &mut [&0]; - //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - // TODO: this should be a mut borrow behind shared borrow error on `structural2021` - #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x; + fn borrowck_error_on_structural2021() { + let [&mut ref mut x] = &mut [&0]; + //[stable2021,classic2021]~^ mismatched types + //[stable2021,classic2021]~| types differ in mutability + //[structural2021]~^^^ cannot borrow data in a `&` reference as mutable + #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x; + } + borrowck_error_on_structural2021(); let [&mut mut x] = &mut [&0]; - //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - // TODO: on `structural2021` `x` should have type `u32` + //[stable2021,classic2021]~^ mismatched types + //[stable2021,classic2021]~| types differ in mutability + #[cfg(structural2021)] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &x] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - // TODO: [structural2021]~| expected integer, found `&_` + //[stable2021,classic2021]~| types differ in mutability + //[structural2021]~| expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; let [&mut &ref x] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - // TODO: [structural2021]~| expected integer, found `&_` + //[stable2021,classic2021]~| types differ in mutability + //[structural2021]~| expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &(mut x)] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021,structural2021]~| types differ in mutability - // TODO: [structural2021]~| expected integer, found `&_` + //[stable2021,classic2021]~| types differ in mutability + //[structural2021]~| expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr index fb99e3983e8cc..adb47172f34cc 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr @@ -186,28 +186,7 @@ LL + let [ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:108:10 - | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:108:10 - | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut ref mut x] = &mut [&0]; -LL + let [ref mut x] = &mut [&0]; - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:114:10 + --> $DIR/well-typed-edition-2024.rs:117:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -217,7 +196,7 @@ LL | let [&mut mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:114:10 + --> $DIR/well-typed-edition-2024.rs:117:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ @@ -228,7 +207,7 @@ LL + let [mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:120:10 + --> $DIR/well-typed-edition-2024.rs:123:10 | LL | let [&mut &x] = &mut [&0]; | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -239,7 +218,7 @@ LL | let [&mut &x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:126:10 + --> $DIR/well-typed-edition-2024.rs:129:10 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -250,7 +229,7 @@ LL | let [&mut &ref x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:132:10 + --> $DIR/well-typed-edition-2024.rs:135:10 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -260,6 +239,27 @@ LL | let [&mut &(mut x)] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:109:14 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:109:14 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut ref mut x] = &mut [&0]; +LL + let [ref mut x] = &mut [&0]; + | + error: aborting due to 17 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr index f784d7e9988db..f8c2bd9a92128 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr @@ -63,122 +63,60 @@ LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:96:10 + --> $DIR/well-typed-edition-2024.rs:123:15 | -LL | let [&mut x] = &mut [&0]; - | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:96:10 - | -LL | let [&mut x] = &mut [&0]; - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut x] = &mut [&0]; -LL + let [x] = &mut [&0]; - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:102:10 - | -LL | let [&mut ref x] = &mut [&0]; - | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:102:10 - | -LL | let [&mut ref x] = &mut [&0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut ref x] = &mut [&0]; -LL + let [ref x] = &mut [&0]; - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:108:10 - | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:108:10 +LL | let [&mut &x] = &mut [&0]; + | ^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern | -LL - let [&mut ref mut x] = &mut [&0]; -LL + let [ref mut x] = &mut [&0]; +LL - let [&mut &x] = &mut [&0]; +LL + let [&mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:114:10 - | -LL | let [&mut mut x] = &mut [&0]; - | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability + --> $DIR/well-typed-edition-2024.rs:129:15 | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:114:10 +LL | let [&mut &ref x] = &mut [&0]; + | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` | -LL | let [&mut mut x] = &mut [&0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern | -LL - let [&mut mut x] = &mut [&0]; -LL + let [mut x] = &mut [&0]; +LL - let [&mut &ref x] = &mut [&0]; +LL + let [&mut ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:120:10 + --> $DIR/well-typed-edition-2024.rs:135:15 | -LL | let [&mut &x] = &mut [&0]; - | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability +LL | let [&mut &(mut x)] = &mut [&0]; + | ^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` | - = note: expected reference `&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:126:10 + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern | -LL | let [&mut &ref x] = &mut [&0]; - | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability +LL - let [&mut &(mut x)] = &mut [&0]; +LL + let [&mut mut x)] = &mut [&0]; | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:132:10 - | -LL | let [&mut &(mut x)] = &mut [&0]; - | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/well-typed-edition-2024.rs:109:19 | - = note: expected reference `&{integer}` - found mutable reference `&mut _` +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^ cannot borrow as mutable -error: aborting due to 11 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0596. +For more information about an error, try `rustc --explain E0308`. From 1ed74aaf0c6d673c8dbd345b178c3faf769c7e85 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 26 Jan 2025 03:16:17 -0800 Subject: [PATCH 20/26] add mixed-edition tests --- .../auxiliary/mixed-editions-macros.rs | 48 +++++++ .../mixed-editions.classic2021.stderr | 103 +++++++++++++++ .../mixed-editions.classic2024.stderr | 97 ++++++++++++++ .../experimental/mixed-editions.rs | 122 ++++++++++++++++++ .../mixed-editions.structural2021.stderr | 61 +++++++++ .../mixed-editions.structural2024.stderr | 55 ++++++++ 6 files changed, 486 insertions(+) create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/auxiliary/mixed-editions-macros.rs create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/auxiliary/mixed-editions-macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/auxiliary/mixed-editions-macros.rs new file mode 100644 index 0000000000000..14d26be91a082 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/auxiliary/mixed-editions-macros.rs @@ -0,0 +1,48 @@ +//@[classic2021] edition: 2024 +//@[structural2021] edition: 2024 +//@[classic2024] edition: 2021 +//@[structural2024] edition: 2021 +//! This contains macros in an edition *different* to the one used in `../mixed-editions.rs`, in +//! order to test typing mixed-edition patterns. + +#[macro_export] +macro_rules! match_ctor { + ($p:pat) => { + [$p] + }; +} + +#[macro_export] +macro_rules! match_ref { + ($p:pat) => { + &$p + }; +} + +#[macro_export] +macro_rules! bind { + ($i:ident) => { + $i + } +} + +#[macro_export] +macro_rules! bind_ref { + ($i:ident) => { + ref $i + } +} + +#[macro_export] +macro_rules! bind_mut { + ($i:ident) => { + mut $i + } +} + +#[macro_export] +macro_rules! bind_ref_mut { + ($i:ident) => { + ref mut $i + } +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr new file mode 100644 index 0000000000000..7e3caaf979748 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr @@ -0,0 +1,103 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:41:10 + | +LL | let [bind_mut!(y)] = &[0]; + | ^^^^^^^^^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: this error originates in the macro `bind_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:76:21 + | +LL | let match_ref!([x]) = &mut &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:80:22 + | +LL | let &match_ctor!(y) = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:84:17 + | +LL | let &[bind!(z)] = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:30:10 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^ occurs within macro expansion + | + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/mixed-editions.rs:30:9 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^^^ this matches on type `&_` + = note: this error originates in the macro `bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) +help: make the implied reference pattern explicit + | +LL | let &[bind_ref!(y)] = &[0]; + | + + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:61:21 + | +LL | let match_ref!([x]) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:65:22 + | +LL | let &match_ctor!(y) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:69:11 + | +LL | let &[bind!(z)] = &&mut [0]; + | ^^^^^^^^ cannot borrow as mutable + | + = note: this error originates in the macro `bind` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr new file mode 100644 index 0000000000000..466993a1671f4 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr @@ -0,0 +1,97 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:37:21 + | +LL | let match_ctor!(mut x) = &[0]; + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:76:21 + | +LL | let match_ref!([x]) = &mut &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:80:22 + | +LL | let &match_ctor!(y) = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:84:17 + | +LL | let &[bind!(z)] = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:26:21 + | +LL | let match_ctor!(ref x) = &[0]; + | ^^^ binding modifier not allowed under `ref` default binding mode + | + = note: for more information, see +help: make the implied reference pattern explicit + --> $DIR/auxiliary/mixed-editions-macros.rs:11:9 + | +LL | &[$p] + | + + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:61:21 + | +LL | let match_ref!([x]) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:65:22 + | +LL | let &match_ctor!(y) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:69:11 + | +LL | let &[bind!(z)] = &&mut [0]; + | ^^^^^^^^ cannot borrow as mutable + | + = note: this error originates in the macro `bind` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs new file mode 100644 index 0000000000000..0a22b55ab6374 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs @@ -0,0 +1,122 @@ +//@ revisions: classic2021 structural2021 classic2024 structural2024 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 +//@ aux-build:mixed-editions-macros.rs +//! Tests for typing mixed-edition patterns under the `ref_pat_eat_one_layer_2024` and +//! `ref_pat_eat_one_layer_2024_structural` feature gates. +//! This is meant both to check that patterns are typed with edition-appropriate typing rules and +//! that we keep our internal state consistent when mixing editions. +#![allow(incomplete_features, unused)] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] + +extern crate mixed_editions_macros; +use mixed_editions_macros::*; + +// Tests type equality in a way that avoids coercing `&&T` to `&T`. +trait Eq {} +impl Eq for T {} +fn assert_type_eq>(_: T, _: U) {} + +/// Make sure binding with `ref` in the presence of an inherited reference is forbidden when and +/// only when the binding is from edition 2024. +fn ref_binding_tests() { + let match_ctor!(ref x) = &[0]; + //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2021, structural2021))] assert_type_eq(x, &0u32); + + let [bind_ref!(y)] = &[0]; + //[classic2021,structural2021]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2024, structural2024))] assert_type_eq(y, &0u32); +} + +/// Likewise, when binding with `mut`. +fn mut_binding_tests() { + let match_ctor!(mut x) = &[0]; + //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference + #[cfg(any(classic2021, structural2021))] assert_type_eq(x, 0u32); + + let [bind_mut!(y)] = &[0]; + //[classic2021,structural2021]~^ ERROR: binding cannot be both mutable and by-reference + #[cfg(any(classic2024, structural2024))] assert_type_eq(y, 0u32); +} + +/// Make sure reference patterns correspond to one deref on edition 2024 and two on edition 2021. +fn layers_eaten_tests() { + let match_ctor!(&x) = &[&0]; + #[cfg(any(classic2021, structural2021))] assert_type_eq(x, 0u32); + #[cfg(any(classic2024, structural2024))] assert_type_eq(x, &0u32); + + let [match_ref!(y)] = &[&0]; + #[cfg(any(classic2021, structural2021))] assert_type_eq(y, &0u32); + #[cfg(any(classic2024, structural2024))] assert_type_eq(y, 0u32); +} + +/// Make sure downgrading mutable binding modes inside shared refs ("Rule 3") doesn't break. +/// This only applies to `ref_pat_eat_one_layer_2024_structural`, which has Rule 3 in all editions; +/// under `ref_pat_eat_one_layer_2024`, these should be errors. +fn rule_3_tests() { + let match_ref!([x]) = &&mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] assert_type_eq(x, &0u32); + + let &match_ctor!(y) = &&mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] assert_type_eq(y, &0u32); + + let &[bind!(z)] = &&mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] assert_type_eq(z, &0u32); +} + +/// Test that the interaction between Rules 3 and 5 doesn't break. +fn rules_3_and_5_tests() { + let match_ref!([x]) = &mut &mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + #[cfg(any(structural2021, structural2024))] assert_type_eq(x, &0u32); + + let &match_ctor!(y) = &mut &mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + #[cfg(any(structural2021, structural2024))] assert_type_eq(y, &0u32); + + let &[bind!(z)] = &mut &mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + #[cfg(any(structural2021, structural2024))] assert_type_eq(z, &0u32); +} + +/// Make sure matching a lone shared reference with a `&` ("Rule 4") doesn't break. +fn rule_4_tests() { + let match_ref!([x]) = &[0]; + assert_type_eq(x, 0u32); + + let &match_ctor!(y) = &[0]; + assert_type_eq(y, 0u32); +} + +/// Make sure matching a `&mut` reference with a `&` pattern ("Rule 5") doesn't break. +fn rule_5_tests() { + let match_ref!(x) = &mut 0; + assert_type_eq(x, 0u32); + + // also test inherited references (assumes rule 4) + let [match_ref!(y)] = &mut [0]; + assert_type_eq(y, 0u32); +} + +/// Make sure binding with `ref mut` is an error within a `&` pattern matching a `&mut` reference. +fn rule_5_mutability_error_tests() { + let match_ref!(ref mut x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let &bind_ref_mut!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + + // also test inherited references (assumes rule 4) + let [match_ref!(ref mut x)] = &mut [0]; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let [&bind_ref_mut!(x)] = &mut [0]; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern +} + +fn main() {} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr new file mode 100644 index 0000000000000..4075dc9529da1 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr @@ -0,0 +1,61 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:41:10 + | +LL | let [bind_mut!(y)] = &[0]; + | ^^^^^^^^^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: this error originates in the macro `bind_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:30:10 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^ occurs within macro expansion + | + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/mixed-editions.rs:30:9 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^^^ this matches on type `&_` + = note: this error originates in the macro `bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) +help: make the implied reference pattern explicit + | +LL | let &[bind_ref!(y)] = &[0]; + | + + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr new file mode 100644 index 0000000000000..819a54299ea1c --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr @@ -0,0 +1,55 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:37:21 + | +LL | let match_ctor!(mut x) = &[0]; + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:26:21 + | +LL | let match_ctor!(ref x) = &[0]; + | ^^^ binding modifier not allowed under `ref` default binding mode + | + = note: for more information, see +help: make the implied reference pattern explicit + --> $DIR/auxiliary/mixed-editions-macros.rs:11:9 + | +LL | &[$p] + | + + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. From 2c595d649aa3ca7cb07ddbbd07ec38a753d6a70d Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 26 Jan 2025 03:33:48 -0800 Subject: [PATCH 21/26] update unstable book --- .../ref-pat-eat-one-layer-2024-structural.md | 5 +++-- .../src/language-features/ref-pat-eat-one-layer-2024.md | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md index bc58768611175..bfdb579cd3523 100644 --- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md @@ -10,10 +10,11 @@ This feature is incomplete and not yet intended for general use. This implements experimental, Edition-dependent match ergonomics under consideration for inclusion in Rust. -For more information, see the corresponding typing rules for [Editions 2024 and later]. -On earlier Editions, the current behavior is unspecified. +For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For alternative experimental match ergonomics, see the feature [`ref_pat_eat_one_layer_2024`](./ref-pat-eat-one-layer-2024.md). +[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQEBAAAAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md index 43de1849a5ebb..58d8d2905030c 100644 --- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md @@ -10,10 +10,11 @@ This feature is incomplete and not yet intended for general use. This implements experimental, Edition-dependent match ergonomics under consideration for inclusion in Rust. -For more information, see the corresponding typing rules for [Editions 2024 and later]. -On earlier Editions, the current behavior is unspecified. +For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For alternative experimental match ergonomics, see the feature [`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md). +[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQABAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false From 799e0f76903f694632db29bf7fc38c8a7f1453b6 Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 30 Jan 2025 16:03:02 -0800 Subject: [PATCH 22/26] add FIXMEs for diagnostic improvements --- compiler/rustc_hir_typeck/src/pat.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index be72af63fe50f..1e28571807e72 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2384,6 +2384,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // NB: This assumes that `&` patterns can match against mutable // references (RFC 3627, Rule 5). If we implement a pattern typing // ruleset with Rule 4 but not Rule 5, we'll need to check that here. + // FIXME(ref_pat_eat_one_layer_2024_structural): If we already tried + // matching the real reference, the error message should explain that + // falling back to the inherited reference didn't work. This should be + // the same error as the old-Edition version below. debug_assert!(ref_pat_matches_mut_ref); self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span); } @@ -2418,6 +2422,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Otherwise, use the common logic below for matching the inner // reference type. + // FIXME(ref_pat_eat_one_layer_2024_structural): If this results in a + // mutability mismatch, the error message should explain that falling + // back to the inherited reference didn't work. This should be the same + // error as the Edition 2024 version above. } } else { // The expected type isn't a reference type, so only match against the From 20149629ba8b143f0529295be22450488e173f30 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 26 Jan 2025 04:20:30 -0800 Subject: [PATCH 23/26] "classic2021" ruleset: experimentally add fallback-to-outer (eat both) My reasoning: the ruleset implemented by the same feature gate in Edition 2024 always tries to eat the inherited reference first. For consistency, it makes sense to me to say across all editions that users should consider the inherited reference's mutability when wondering if a `&mut` pattern will type. --- compiler/rustc_hir_typeck/src/pat.rs | 46 +++--- .../ref-pat-eat-one-layer-2024.md | 2 +- ...well-typed-edition-2024.classic2021.stderr | 134 +++++------------- .../experimental/well-typed-edition-2024.rs | 36 ++--- 4 files changed, 73 insertions(+), 145 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 1e28571807e72..4201ef6674120 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -232,12 +232,13 @@ enum InheritedRefMatchRule { /// When the underlying type is a reference type, reference patterns consume both layers of /// reference, i.e. they both reset the binding mode and consume the reference type. EatBoth { - /// Whether to allow reference patterns to consume only an inherited reference when matching - /// against a non-reference type. This is `false` for stable Rust. - eat_inherited_ref_alone: bool, - /// Whether to allow a `&mut` reference pattern to eat a `&` reference type if it's also - /// able to consume a mutable inherited reference. This is `false` for stable Rust. - fallback_to_outer: bool, + /// This represents two behaviors implemented by both the `ref_pat_eat_one_layer_2024` and + /// `ref_pat_eat_one_layer_2024_structural` feature gates, and is false for stable Rust. + /// - Whether to allow reference patterns to consume only an inherited reference when + /// matching against a non-reference type. + /// - Whether to allow a `&mut` reference pattern to eat a `&` reference type if it's also + /// able to consume a mutable inherited reference. + consider_inherited_ref_first: bool, }, } @@ -264,17 +265,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Currently, matching against an inherited ref on edition 2024 is an error. // Use `EatBoth` as a fallback to be similar to stable Rust. - InheritedRefMatchRule::EatBoth { - eat_inherited_ref_alone: false, - fallback_to_outer: false, - } + InheritedRefMatchRule::EatBoth { consider_inherited_ref_first: false } } } else { - let has_structural_gate = self.tcx.features().ref_pat_eat_one_layer_2024_structural(); InheritedRefMatchRule::EatBoth { - eat_inherited_ref_alone: has_structural_gate - || self.tcx.features().ref_pat_eat_one_layer_2024(), - fallback_to_outer: has_structural_gate, + consider_inherited_ref_first: self.tcx.features().ref_pat_eat_one_layer_2024() + || self.tcx.features().ref_pat_eat_one_layer_2024_structural(), } } } @@ -2398,20 +2394,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - InheritedRefMatchRule::EatBoth { - eat_inherited_ref_alone: true, - fallback_to_outer, - } => { + InheritedRefMatchRule::EatBoth { consider_inherited_ref_first: true } => { // Reset binding mode on old editions pat_info.binding_mode = ByRef::No; if let ty::Ref(_, inner_ty, _) = *expected.kind() { // Consume both the inherited and inner references. - if fallback_to_outer && inh_mut.is_mut() { - // If we can fall back to matching the inherited reference, the expected - // type is a reference type (of any mutability), and the inherited - // reference is mutable, we'll always be able to match. We handle that - // here to avoid adding fallback-to-outer to the common logic below. + if inh_mut.is_mut() { + // If the expected type is a reference type (of any mutability) and the + // inherited ref is mutable, we'll be able to match, since we can fall + // back to matching the inherited ref if the real reference isn't + // mutable enough for our pattern. We handle that here to avoid adding + // fallback-to-outer to the common logic below. // NB: This way of phrasing the logic will catch more cases than those // that need to fall back to matching the inherited reference. However, // as long as `&` patterns can match mutable (inherited) references @@ -2440,13 +2434,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - rule @ InheritedRefMatchRule::EatBoth { - eat_inherited_ref_alone: false, - fallback_to_outer, - } => { + InheritedRefMatchRule::EatBoth { consider_inherited_ref_first: false } => { // Reset binding mode on stable Rust. This will be a type error below if // `expected` is not a reference type. - debug_assert!(!fallback_to_outer, "typing rule `{rule:?}` is unimplemented."); pat_info.binding_mode = ByRef::No; self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md index 58d8d2905030c..0c90cec0dbddb 100644 --- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md @@ -16,5 +16,5 @@ For more information, see the corresponding typing rules for [Editions 2021 and For alternative experimental match ergonomics, see the feature [`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md). -[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQABAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false +[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr index 086d4bb133ba2..f8c2bd9a92128 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr @@ -63,122 +63,60 @@ LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:96:10 + --> $DIR/well-typed-edition-2024.rs:123:15 | -LL | let [&mut x] = &mut [&0]; - | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:96:10 - | -LL | let [&mut x] = &mut [&0]; - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut x] = &mut [&0]; -LL + let [x] = &mut [&0]; - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:102:10 - | -LL | let [&mut ref x] = &mut [&0]; - | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:102:10 - | -LL | let [&mut ref x] = &mut [&0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut ref x] = &mut [&0]; -LL + let [ref x] = &mut [&0]; - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:117:10 - | -LL | let [&mut mut x] = &mut [&0]; - | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:117:10 +LL | let [&mut &x] = &mut [&0]; + | ^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` | -LL | let [&mut mut x] = &mut [&0]; - | ^^^^^^^^^^ -help: consider removing `&mut` from the pattern + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern | -LL - let [&mut mut x] = &mut [&0]; -LL + let [mut x] = &mut [&0]; +LL - let [&mut &x] = &mut [&0]; +LL + let [&mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:123:10 + --> $DIR/well-typed-edition-2024.rs:129:15 | -LL | let [&mut &x] = &mut [&0]; - | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability +LL | let [&mut &ref x] = &mut [&0]; + | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` | - = note: expected reference `&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:129:10 + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern | -LL | let [&mut &ref x] = &mut [&0]; - | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability +LL - let [&mut &ref x] = &mut [&0]; +LL + let [&mut ref x] = &mut [&0]; | - = note: expected reference `&{integer}` - found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:135:10 + --> $DIR/well-typed-edition-2024.rs:135:15 | LL | let [&mut &(mut x)] = &mut [&0]; - | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability + | ^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` | - = note: expected reference `&{integer}` - found mutable reference `&mut _` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:109:14 + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability +LL - let [&mut &(mut x)] = &mut [&0]; +LL + let [&mut mut x)] = &mut [&0]; | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:109:14 + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/well-typed-edition-2024.rs:109:19 | LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut ref mut x] = &mut [&0]; -LL + let [ref mut x] = &mut [&0]; - | + | ^^^^^^^^^ cannot borrow as mutable -error: aborting due to 11 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0596. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 63a09fe90c9f2..62c1c28022b7d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -94,47 +94,47 @@ pub fn main() { // Tests for eat-inner and eat-both rulesets matching on the outer reference if matching on the // inner reference causes a mutability mismatch. i.e. tests for "fallback-to-outer" deref rules. let [&mut x] = &mut [&0]; - //[stable2021,classic2021]~^ mismatched types - //[stable2021,classic2021]~| types differ in mutability - #[cfg(structural2021)] let _: u32 = x; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability + #[cfg(any(classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut ref x] = &mut [&0]; - //[stable2021,classic2021]~^ mismatched types - //[stable2021,classic2021]~| types differ in mutability - #[cfg(structural2021)] let _: &u32 = x; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability + #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(any(classic2024, structural2024))] let _: &&u32 = x; fn borrowck_error_on_structural2021() { let [&mut ref mut x] = &mut [&0]; - //[stable2021,classic2021]~^ mismatched types - //[stable2021,classic2021]~| types differ in mutability - //[structural2021]~^^^ cannot borrow data in a `&` reference as mutable + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability + //[classic2021,structural2021]~^^^ cannot borrow data in a `&` reference as mutable #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x; } borrowck_error_on_structural2021(); let [&mut mut x] = &mut [&0]; - //[stable2021,classic2021]~^ mismatched types - //[stable2021,classic2021]~| types differ in mutability - #[cfg(structural2021)] let _: u32 = x; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability + #[cfg(any(classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &x] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021]~| types differ in mutability - //[structural2021]~| expected integer, found `&_` + //[stable2021]~| types differ in mutability + //[classic2021,structural2021]~| expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; let [&mut &ref x] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021]~| types differ in mutability - //[structural2021]~| expected integer, found `&_` + //[stable2021]~| types differ in mutability + //[classic2021,structural2021]~| expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &(mut x)] = &mut [&0]; //[stable2021,classic2021,structural2021]~^ mismatched types - //[stable2021,classic2021]~| types differ in mutability - //[structural2021]~| expected integer, found `&_` + //[stable2021]~| types differ in mutability + //[classic2021,structural2021]~| expected integer, found `&_` #[cfg(any(classic2024, structural2024))] let _: u32 = x; } From 37bcc1cc5ccd6b87257388e11a7573df61ebc990 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 16 Feb 2025 16:20:52 -0800 Subject: [PATCH 24/26] clarify wording on doc comment Co-authored-by: Nadrieril --- compiler/rustc_hir_typeck/src/pat.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 4201ef6674120..40df87188cd32 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -232,12 +232,15 @@ enum InheritedRefMatchRule { /// When the underlying type is a reference type, reference patterns consume both layers of /// reference, i.e. they both reset the binding mode and consume the reference type. EatBoth { - /// This represents two behaviors implemented by both the `ref_pat_eat_one_layer_2024` and - /// `ref_pat_eat_one_layer_2024_structural` feature gates, and is false for stable Rust. - /// - Whether to allow reference patterns to consume only an inherited reference when - /// matching against a non-reference type. - /// - Whether to allow a `&mut` reference pattern to eat a `&` reference type if it's also - /// able to consume a mutable inherited reference. + /// If `true`, an inherited reference will be considered when determining whether a reference + /// pattern matches a given type: + /// - If the underlying type is not a reference, a reference pattern may eat the inherited reference; + /// - If the underlying type is a reference, a reference pattern matches if it can eat either one + /// of the underlying and inherited references. E.g. a `&mut` pattern is allowed if either the + /// underlying type is `&mut` or the inherited reference is `&mut`. + /// If `false`, a reference pattern is only matched against the underlying type. + /// This is `false` for stable Rust and `true` for both the `ref_pat_eat_one_layer_2024` and + /// `ref_pat_eat_one_layer_2024_structural` feature gates. consider_inherited_ref_first: bool, }, } From 0e758c4ba6d9165106f6db768e23f01fabfd2d8c Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 16 Feb 2025 17:04:26 -0800 Subject: [PATCH 25/26] rename `consider_inherited_ref_first` -> `consider_inherited_ref` --- compiler/rustc_hir_typeck/src/pat.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 40df87188cd32..9456247de887f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -241,7 +241,7 @@ enum InheritedRefMatchRule { /// If `false`, a reference pattern is only matched against the underlying type. /// This is `false` for stable Rust and `true` for both the `ref_pat_eat_one_layer_2024` and /// `ref_pat_eat_one_layer_2024_structural` feature gates. - consider_inherited_ref_first: bool, + consider_inherited_ref: bool, }, } @@ -268,11 +268,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Currently, matching against an inherited ref on edition 2024 is an error. // Use `EatBoth` as a fallback to be similar to stable Rust. - InheritedRefMatchRule::EatBoth { consider_inherited_ref_first: false } + InheritedRefMatchRule::EatBoth { consider_inherited_ref: false } } } else { InheritedRefMatchRule::EatBoth { - consider_inherited_ref_first: self.tcx.features().ref_pat_eat_one_layer_2024() + consider_inherited_ref: self.tcx.features().ref_pat_eat_one_layer_2024() || self.tcx.features().ref_pat_eat_one_layer_2024_structural(), } } @@ -2397,7 +2397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - InheritedRefMatchRule::EatBoth { consider_inherited_ref_first: true } => { + InheritedRefMatchRule::EatBoth { consider_inherited_ref: true } => { // Reset binding mode on old editions pat_info.binding_mode = ByRef::No; @@ -2437,7 +2437,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - InheritedRefMatchRule::EatBoth { consider_inherited_ref_first: false } => { + InheritedRefMatchRule::EatBoth { consider_inherited_ref: false } => { // Reset binding mode on stable Rust. This will be a type error below if // `expected` is not a reference type. pat_info.binding_mode = ByRef::No; From 0a15bfb340430075703689630ab99d3bc22a96d5 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 16 Feb 2025 18:48:07 -0800 Subject: [PATCH 26/26] simplify fallback-to-outer condition on old editions --- compiler/rustc_hir_typeck/src/pat.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 9456247de887f..73a1432b06ce6 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2403,17 +2403,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::Ref(_, inner_ty, _) = *expected.kind() { // Consume both the inherited and inner references. - if inh_mut.is_mut() { - // If the expected type is a reference type (of any mutability) and the - // inherited ref is mutable, we'll be able to match, since we can fall - // back to matching the inherited ref if the real reference isn't - // mutable enough for our pattern. We handle that here to avoid adding - // fallback-to-outer to the common logic below. - // NB: This way of phrasing the logic will catch more cases than those - // that need to fall back to matching the inherited reference. However, - // as long as `&` patterns can match mutable (inherited) references - // (RFC 3627, Rule 5) this should be sound. - debug_assert!(ref_pat_matches_mut_ref); + if pat_mutbl.is_mut() && inh_mut.is_mut() { + // As a special case, a `&mut` reference pattern will be able to match + // against a reference type of any mutability if the inherited ref is + // mutable. Since this allows us to match against a shared reference + // type, we refer to this as "falling back" to matching the inherited + // reference, though we consume the real reference as well. We handle + // this here to avoid adding this case to the common logic below. self.check_pat(inner, inner_ty, pat_info); return expected; } else {