From 7d0518c380e9dfed78855aad68d19e2e530bdcc0 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Fri, 27 Dec 2024 15:02:34 +0100 Subject: [PATCH 01/71] Implement `int_from_ascii` (#134821) Provides unstable `T::from_ascii()` and `T::from_ascii_radix()` for integer types `T`, as drafted in tracking issue #134821. To deduplicate documentation without additional macros, implementations of `isize` and `usize` no longer delegate to equivalent integer types. After #132870 they are inlined anyway. --- library/core/src/num/mod.rs | 220 +++++++++++-------- tests/ui/consts/const-eval/parse_ints.stderr | 12 +- 2 files changed, 139 insertions(+), 93 deletions(-) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 357a85ae843..25c92b2d8d3 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1453,20 +1453,6 @@ pub enum FpCategory { Normal, } -macro_rules! from_str_radix_int_impl { - ($($t:ty)*) => {$( - #[stable(feature = "rust1", since = "1.0.0")] - impl FromStr for $t { - type Err = ParseIntError; - #[inline] - fn from_str(src: &str) -> Result { - <$t>::from_str_radix(src, 10) - } - } - )*} -} -from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } - /// Determines if a string of text of that length of that radix could be guaranteed to be /// stored in the given type T. /// Note that if the radix is known to the compiler, it is just the check of digits.len that @@ -1482,18 +1468,58 @@ pub const fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -const fn from_str_radix_panic(radix: u32) -> ! { +const fn from_ascii_radix_panic(radix: u32) -> ! { const_panic!( - "from_str_radix_int: must lie in the range `[2, 36]`", - "from_str_radix_int: must lie in the range `[2, 36]` - found {radix}", + "from_ascii_radix: radix must lie in the range `[2, 36]`", + "from_ascii_radix: radix must lie in the range `[2, 36]` - found {radix}", radix: u32 = radix, ) } -macro_rules! from_str_radix { +macro_rules! from_str_int_impl { ($signedness:ident $($int_ty:ty)+) => {$( + #[stable(feature = "rust1", since = "1.0.0")] + impl FromStr for $int_ty { + type Err = ParseIntError; + + /// Parses an integer from a string slice with decimal digits. + /// + /// The characters are expected to be an optional + #[doc = sign_dependent_expr!{ + $signedness ? + if signed { + " `+` or `-` " + } + if unsigned { + " `+` " + } + }] + /// sign followed by only digits. Leading and trailing non-digit characters (including + /// whitespace) represent an error. Underscores (which are accepted in Rust literals) + /// also represent an error. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + /// use std::str::FromStr; + /// + #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_str(\"+10\"), Ok(10));")] + /// ``` + /// Trailing space returns error: + /// ``` + /// # use std::str::FromStr; + /// # + #[doc = concat!("assert!(", stringify!($int_ty), "::from_str(\"1 \").is_err());")] + /// ``` + #[inline] + fn from_str(src: &str) -> Result<$int_ty, ParseIntError> { + <$int_ty>::from_str_radix(src, 10) + } + } + impl $int_ty { - /// Converts a string slice in a given base to an integer. + /// Parses an integer from a string slice with digits in a given base. /// /// The string is expected to be an optional #[doc = sign_dependent_expr!{ @@ -1506,7 +1532,7 @@ macro_rules! from_str_radix { } }] /// sign followed by only digits. Leading and trailing non-digit characters (including - /// whitespace) represent an error. Underscores (which are accepted in rust literals) + /// whitespace) represent an error. Underscores (which are accepted in Rust literals) /// also represent an error. /// /// Digits are a subset of these characters, depending on `radix`: @@ -1532,11 +1558,92 @@ macro_rules! from_str_radix { #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")] #[inline] pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> { + <$int_ty>::from_ascii_radix(src.as_bytes(), radix) + } + + /// Parses an integer from an ASCII-byte slice with decimal digits. + /// + /// The characters are expected to be an optional + #[doc = sign_dependent_expr!{ + $signedness ? + if signed { + " `+` or `-` " + } + if unsigned { + " `+` " + } + }] + /// sign followed by only digits. Leading and trailing non-digit characters (including + /// whitespace) represent an error. Underscores (which are accepted in Rust literals) + /// also represent an error. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + /// #![feature(int_from_ascii)] + /// + #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_ascii(b\"+10\"), Ok(10));")] + /// ``` + /// Trailing space returns error: + /// ``` + /// # #![feature(int_from_ascii)] + /// # + #[doc = concat!("assert!(", stringify!($int_ty), "::from_ascii(b\"1 \").is_err());")] + /// ``` + #[unstable(feature = "int_from_ascii", issue = "134821")] + #[inline] + pub const fn from_ascii(src: &[u8]) -> Result<$int_ty, ParseIntError> { + <$int_ty>::from_ascii_radix(src, 10) + } + + /// Parses an integer from an ASCII-byte slice with digits in a given base. + /// + /// The characters are expected to be an optional + #[doc = sign_dependent_expr!{ + $signedness ? + if signed { + " `+` or `-` " + } + if unsigned { + " `+` " + } + }] + /// sign followed by only digits. Leading and trailing non-digit characters (including + /// whitespace) represent an error. Underscores (which are accepted in Rust literals) + /// also represent an error. + /// + /// Digits are a subset of these characters, depending on `radix`: + /// * `0-9` + /// * `a-z` + /// * `A-Z` + /// + /// # Panics + /// + /// This function panics if `radix` is not in the range from 2 to 36. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + /// #![feature(int_from_ascii)] + /// + #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_ascii_radix(b\"A\", 16), Ok(10));")] + /// ``` + /// Trailing space returns error: + /// ``` + /// # #![feature(int_from_ascii)] + /// # + #[doc = concat!("assert!(", stringify!($int_ty), "::from_ascii_radix(b\"1 \", 10).is_err());")] + /// ``` + #[unstable(feature = "int_from_ascii", issue = "134821")] + #[inline] + pub const fn from_ascii_radix(src: &[u8], radix: u32) -> Result<$int_ty, ParseIntError> { use self::IntErrorKind::*; use self::ParseIntError as PIE; if 2 > radix || radix > 36 { - from_str_radix_panic(radix); + from_ascii_radix_panic(radix); } if src.is_empty() { @@ -1546,12 +1653,6 @@ macro_rules! from_str_radix { #[allow(unused_comparisons)] let is_signed_ty = 0 > <$int_ty>::MIN; - // all valid digits are ascii, so we will just iterate over the utf8 bytes - // and cast them to chars. .to_digit() will safely return None for anything - // other than a valid ascii digit for the given radix, including the first-byte - // of multi-byte sequences - let src = src.as_bytes(); - let (is_positive, mut digits) = match src { [b'+' | b'-'] => { return Err(PIE { kind: InvalidDigit }); @@ -1627,67 +1728,8 @@ macro_rules! from_str_radix { Ok(result) } } - )+} + )*} } -from_str_radix! { unsigned u8 u16 u32 u64 u128 } -from_str_radix! { signed i8 i16 i32 i64 i128 } - -// Re-use the relevant implementation of from_str_radix for isize and usize to avoid outputting two -// identical functions. -macro_rules! from_str_radix_size_impl { - ($($signedness:ident $t:ident $size:ty),*) => {$( - impl $size { - /// Converts a string slice in a given base to an integer. - /// - /// The string is expected to be an optional - #[doc = sign_dependent_expr!{ - $signedness ? - if signed { - " `+` or `-` " - } - if unsigned { - " `+` " - } - }] - /// sign followed by only digits. Leading and trailing non-digit characters (including - /// whitespace) represent an error. Underscores (which are accepted in rust literals) - /// also represent an error. - /// - /// Digits are a subset of these characters, depending on `radix`: - /// * `0-9` - /// * `a-z` - /// * `A-Z` - /// - /// # Panics - /// - /// This function panics if `radix` is not in the range from 2 to 36. - /// - /// # Examples - /// - /// Basic usage: - /// ``` - #[doc = concat!("assert_eq!(", stringify!($size), "::from_str_radix(\"A\", 16), Ok(10));")] - /// ``` - /// Trailing space returns error: - /// ``` - #[doc = concat!("assert!(", stringify!($size), "::from_str_radix(\"1 \", 10).is_err());")] - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")] - #[inline] - pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntError> { - match <$t>::from_str_radix(src, radix) { - Ok(x) => Ok(x as $size), - Err(e) => Err(e), - } - } - })*} -} - -#[cfg(target_pointer_width = "16")] -from_str_radix_size_impl! { signed i16 isize, unsigned u16 usize } -#[cfg(target_pointer_width = "32")] -from_str_radix_size_impl! { signed i32 isize, unsigned u32 usize } -#[cfg(target_pointer_width = "64")] -from_str_radix_size_impl! { signed i64 isize, unsigned u64 usize } +from_str_int_impl! { signed isize i8 i16 i32 i64 i128 } +from_str_int_impl! { unsigned usize u8 u16 u32 u64 u128 } diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr index ec9249ece8e..189d3c3958b 100644 --- a/tests/ui/consts/const-eval/parse_ints.stderr +++ b/tests/ui/consts/const-eval/parse_ints.stderr @@ -1,8 +1,10 @@ error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/num/mod.rs:LL:COL | - = note: the evaluated program panicked at 'from_str_radix_int: must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL + = note: the evaluated program panicked at 'from_ascii_radix: radix must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL | +note: inside `core::num::::from_ascii_radix` + --> $SRC_DIR/core/src/num/mod.rs:LL:COL note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL note: inside `_TOO_LOW` @@ -10,13 +12,15 @@ note: inside `_TOO_LOW` | LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `from_str_radix` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/num/mod.rs:LL:COL | - = note: the evaluated program panicked at 'from_str_radix_int: must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL + = note: the evaluated program panicked at 'from_ascii_radix: radix must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL | +note: inside `core::num::::from_ascii_radix` + --> $SRC_DIR/core/src/num/mod.rs:LL:COL note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL note: inside `_TOO_HIGH` @@ -24,7 +28,7 @@ note: inside `_TOO_HIGH` | LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `from_str_radix` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors From 436e4fb647bca08bd5cb7eea6f8450bb56515c10 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Thu, 2 Jan 2025 13:10:11 +0100 Subject: [PATCH 02/71] Cast global variables to default address space Pointers for variables all need to be in the same address space for correct compilation. Therefore ensure that even if a global variable is created in a different address space, it is casted to the default address space before its value is used. This is necessary for the amdgpu target and others where the default address space for global variables is not 0. For example `core` does not compile in debug mode when not casting the address space to the default one because it tries to emit the following (simplified) LLVM IR, containing a type mismatch: ```llvm @alloc_0 = addrspace(1) constant <{ [6 x i8] }> <{ [6 x i8] c"bit.rs" }>, align 1 @alloc_1 = addrspace(1) constant <{ ptr }> <{ ptr addrspace(1) @alloc_0 }>, align 8 ; ^ here a struct containing a `ptr` is needed, but it is created using a `ptr addrspace(1)` ``` For this to compile, we need to insert a constant `addrspacecast` before we use a global variable: ```llvm @alloc_0 = addrspace(1) constant <{ [6 x i8] }> <{ [6 x i8] c"bit.rs" }>, align 1 @alloc_1 = addrspace(1) constant <{ ptr }> <{ ptr addrspacecast (ptr addrspace(1) @alloc_0 to ptr) }>, align 8 ``` As vtables are global variables as well, they are also created with an `addrspacecast`. In the SSA backend, after a vtable global is created, metadata is added to it. To add metadata, we need the non-casted global variable. Therefore we strip away an addrspacecast if there is one, to get the underlying global. --- compiler/rustc_codegen_llvm/src/builder.rs | 4 +- compiler/rustc_codegen_llvm/src/common.rs | 7 +- compiler/rustc_codegen_llvm/src/consts.rs | 48 ++++++++---- .../src/debuginfo/metadata.rs | 15 ++++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 77 +++++++++++++++++++ 5 files changed, 130 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index ab0e43e60a4..1b99fea8d51 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1225,7 +1225,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> { fn get_static(&mut self, def_id: DefId) -> &'ll Value { // Forward to the `get_static` method of `CodegenCx` - self.cx().get_static(def_id) + let s = self.cx().get_static(def_id); + // Cast to default address space if statics are in a different addrspace + self.cx().const_pointercast(s, self.type_ptr()) } } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index adfe8aeb5c5..bd792c02810 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -221,6 +221,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global); } llvm::set_linkage(g, llvm::Linkage::InternalLinkage); + let g = self.const_pointercast(g, self.type_ptr()); (s.to_owned(), g) }) .1; @@ -285,7 +286,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let alloc = alloc.inner(); let value = match alloc.mutability { Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None), - _ => self.static_addr_of(init, alloc.align, None), + _ => self.static_addr_of_impl(init, alloc.align, None), }; if !self.sess().fewer_names() && llvm::get_value_name(value).is_empty() { @@ -311,7 +312,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { .global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal()))) .unwrap_memory(); let init = const_alloc_to_llvm(self, alloc, /*static*/ false); - let value = self.static_addr_of(init, alloc.inner().align, None); + let value = self.static_addr_of_impl(init, alloc.inner().align, None); (value, AddressSpace::DATA) } GlobalAlloc::Static(def_id) => { @@ -323,7 +324,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let llval = unsafe { llvm::LLVMConstInBoundsGEP2( self.type_i8(), - self.const_bitcast(base_addr, self.type_ptr_ext(base_addr_space)), + self.const_pointercast(base_addr, self.type_ptr_ext(base_addr_space)), &self.const_usize(offset.bytes()), 1, ) diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index c7114480d8b..b88fd133e8e 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -210,6 +210,10 @@ impl<'ll> CodegenCx<'ll, '_> { unsafe { llvm::LLVMConstBitCast(val, ty) } } + pub(crate) fn const_pointercast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { + unsafe { llvm::LLVMConstPointerCast(val, ty) } + } + pub(crate) fn static_addr_of_mut( &self, cv: &'ll Value, @@ -233,6 +237,31 @@ impl<'ll> CodegenCx<'ll, '_> { gv } + pub(crate) fn static_addr_of_impl( + &self, + cv: &'ll Value, + align: Align, + kind: Option<&str>, + ) -> &'ll Value { + if let Some(&gv) = self.const_globals.borrow().get(&cv) { + unsafe { + // Upgrade the alignment in cases where the same constant is used with different + // alignment requirements + let llalign = align.bytes() as u32; + if llalign > llvm::LLVMGetAlignment(gv) { + llvm::LLVMSetAlignment(gv, llalign); + } + } + return gv; + } + let gv = self.static_addr_of_mut(cv, align, kind); + unsafe { + llvm::LLVMSetGlobalConstant(gv, True); + } + self.const_globals.borrow_mut().insert(cv, gv); + gv + } + #[instrument(level = "debug", skip(self))] pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value { let instance = Instance::mono(self.tcx, def_id); @@ -506,23 +535,8 @@ impl<'ll> CodegenCx<'ll, '_> { impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> { fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value { - if let Some(&gv) = self.const_globals.borrow().get(&cv) { - unsafe { - // Upgrade the alignment in cases where the same constant is used with different - // alignment requirements - let llalign = align.bytes() as u32; - if llalign > llvm::LLVMGetAlignment(gv) { - llvm::LLVMSetAlignment(gv, llalign); - } - } - return gv; - } - let gv = self.static_addr_of_mut(cv, align, kind); - unsafe { - llvm::LLVMSetGlobalConstant(gv, True); - } - self.const_globals.borrow_mut().insert(cv, gv); - gv + let gv = self.static_addr_of_impl(cv, align, kind); + self.const_pointercast(gv, self.type_ptr()) } fn codegen_static(&self, def_id: DefId) { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 40248a9009a..e4da540da5c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1500,6 +1500,18 @@ fn build_vtable_type_di_node<'ll, 'tcx>( .di_node } +fn find_vtable_behind_cast<'ll>(vtable: &'ll Value) -> &'ll Value { + // The vtable is a global variable, which may be behind an addrspacecast. + unsafe { + if let Some(c) = llvm::LLVMIsAConstantExpr(vtable) { + if llvm::LLVMGetConstOpcode(c) == llvm::Opcode::AddrSpaceCast { + return llvm::LLVMGetOperand(c, 0).unwrap(); + } + } + } + vtable +} + pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, @@ -1520,6 +1532,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( let Some(trait_ref) = trait_ref else { return }; + let vtable = find_vtable_behind_cast(vtable); let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); let trait_ref_self = cx.tcx.erase_regions(trait_ref_self); let trait_def_id = trait_ref_self.def_id(); @@ -1593,6 +1606,8 @@ pub(crate) fn create_vtable_di_node<'ll, 'tcx>( return; } + let vtable = find_vtable_behind_cast(vtable); + // When full debuginfo is enabled, we want to try and prevent vtables from being // merged. Otherwise debuggers will have a hard time mapping from dyn pointer // to concrete type. diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 472d4a3a72b..8ae9c1e5017 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -660,6 +660,79 @@ pub enum MemoryEffects { InaccessibleMemOnly, } +/// LLVMOpcode +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub enum Opcode { + Ret = 1, + Br = 2, + Switch = 3, + IndirectBr = 4, + Invoke = 5, + Unreachable = 7, + CallBr = 67, + FNeg = 66, + Add = 8, + FAdd = 9, + Sub = 10, + FSub = 11, + Mul = 12, + FMul = 13, + UDiv = 14, + SDiv = 15, + FDiv = 16, + URem = 17, + SRem = 18, + FRem = 19, + Shl = 20, + LShr = 21, + AShr = 22, + And = 23, + Or = 24, + Xor = 25, + Alloca = 26, + Load = 27, + Store = 28, + GetElementPtr = 29, + Trunc = 30, + ZExt = 31, + SExt = 32, + FPToUI = 33, + FPToSI = 34, + UIToFP = 35, + SIToFP = 36, + FPTrunc = 37, + FPExt = 38, + PtrToInt = 39, + IntToPtr = 40, + BitCast = 41, + AddrSpaceCast = 60, + ICmp = 42, + FCmp = 43, + PHI = 44, + Call = 45, + Select = 46, + UserOp1 = 47, + UserOp2 = 48, + VAArg = 49, + ExtractElement = 50, + InsertElement = 51, + ShuffleVector = 52, + ExtractValue = 53, + InsertValue = 54, + Freeze = 68, + Fence = 55, + AtomicCmpXchg = 56, + AtomicRMW = 57, + Resume = 58, + LandingPad = 59, + CleanupRet = 61, + CatchRet = 62, + CatchPad = 63, + CleanupPad = 64, + CatchSwitch = 65, +} + unsafe extern "C" { type Opaque; } @@ -975,7 +1048,10 @@ unsafe extern "C" { pub fn LLVMConstPtrToInt<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstIntToPtr<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstBitCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; + pub fn LLVMConstPointerCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMGetAggregateElement(ConstantVal: &Value, Idx: c_uint) -> Option<&Value>; + pub fn LLVMGetConstOpcode(ConstantVal: &Value) -> Opcode; + pub fn LLVMIsAConstantExpr(Val: &Value) -> Option<&Value>; // Operations on global variables, functions, and aliases (globals) pub fn LLVMIsDeclaration(Global: &Value) -> Bool; @@ -1032,6 +1108,7 @@ unsafe extern "C" { // Operations on instructions pub fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>; pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock; + pub fn LLVMGetOperand(Val: &Value, Index: c_uint) -> Option<&Value>; // Operations on call sites pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint); From 53238c3db6b293546f0b3bbd835ca85517ae9d8f Mon Sep 17 00:00:00 2001 From: Flakebi Date: Thu, 2 Jan 2025 13:15:21 +0100 Subject: [PATCH 03/71] Target option to require explicit cpu Some targets have many different CPUs and no generic CPU that can be used as a default. For these targets, the user needs to explicitly specify a CPU through `-C target-cpu=`. Add an option for targets and an error message if no CPU is set. This affects the proposed amdgpu and avr targets. --- compiler/rustc_codegen_ssa/messages.ftl | 2 ++ compiler/rustc_codegen_ssa/src/base.rs | 5 +++++ compiler/rustc_codegen_ssa/src/errors.rs | 4 ++++ compiler/rustc_target/src/spec/json.rs | 2 ++ compiler/rustc_target/src/spec/mod.rs | 4 ++++ .../run-make/target-specs/require-explicit-cpu.json | 11 +++++++++++ tests/run-make/target-specs/rmake.rs | 13 +++++++++++++ 7 files changed, 41 insertions(+) create mode 100644 tests/run-make/target-specs/require-explicit-cpu.json diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 56188714b44..60e97910e19 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -30,6 +30,8 @@ codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error} codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error} +codegen_ssa_cpu_required = target requires explicitly specifying a cpu with `-C target-cpu` + codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} codegen_ssa_dlltool_fail_import_library = diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 77e1fed720d..9c31cde259f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -616,6 +616,11 @@ pub fn codegen_crate( return ongoing_codegen; } + if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() { + // The target has no default cpu, but none is set explicitly + tcx.dcx().emit_fatal(errors::CpuRequired); + } + let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); // Run the monomorphization collector and partition the collected items into diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index c7213bbc801..7132219fb3d 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -491,6 +491,10 @@ pub(crate) struct CheckInstalledVisualStudio; #[diag(codegen_ssa_insufficient_vs_code_product)] pub(crate) struct InsufficientVSCodeProduct; +#[derive(Diagnostic)] +#[diag(codegen_ssa_cpu_required)] +pub(crate) struct CpuRequired; + #[derive(Diagnostic)] #[diag(codegen_ssa_processing_dymutil_failed)] #[note] diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index 9cdc0801b1f..015ea97f2ac 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -546,6 +546,7 @@ impl Target { key!(link_env_remove, list); key!(asm_args, list); key!(cpu); + key!(need_explicit_cpu, bool); key!(features); key!(dynamic_linking, bool); key!(direct_access_external_data, Option); @@ -720,6 +721,7 @@ impl ToJson for Target { target_option_val!(link_env_remove); target_option_val!(asm_args); target_option_val!(cpu); + target_option_val!(need_explicit_cpu); target_option_val!(features); target_option_val!(dynamic_linking); target_option_val!(direct_access_external_data); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 02962d55a60..b017145daa3 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2240,6 +2240,9 @@ pub struct TargetOptions { /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults /// to "generic". pub cpu: StaticCow, + /// Whether a cpu needs to be explicitly set. + /// Set to true if there is no default cpu. Defaults to false. + pub need_explicit_cpu: bool, /// Default target features to pass to LLVM. These features overwrite /// `-Ctarget-cpu` but can be overwritten with `-Ctarget-features`. /// Corresponds to `llc -mattr=$features`. @@ -2676,6 +2679,7 @@ impl Default for TargetOptions { link_script: None, asm_args: cvs![], cpu: "generic".into(), + need_explicit_cpu: false, features: "".into(), direct_access_external_data: None, dynamic_linking: false, diff --git a/tests/run-make/target-specs/require-explicit-cpu.json b/tests/run-make/target-specs/require-explicit-cpu.json new file mode 100644 index 00000000000..5cbb9573b3f --- /dev/null +++ b/tests/run-make/target-specs/require-explicit-cpu.json @@ -0,0 +1,11 @@ +{ + "data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128", + "linker-flavor": "gcc", + "llvm-target": "i686-unknown-linux-gnu", + "target-endian": "little", + "target-pointer-width": "32", + "target-c-int-width": "32", + "arch": "x86", + "os": "linux", + "need-explicit-cpu": true +} diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 79c888ab340..f36a5784c89 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs @@ -63,4 +63,17 @@ fn main() { .crate_type("lib") .run_fail() .assert_stderr_contains("data-layout for target"); + rustc() + .input("foo.rs") + .target("require-explicit-cpu") + .crate_type("lib") + .run_fail() + .assert_stderr_contains("target requires explicitly specifying a cpu"); + rustc() + .input("foo.rs") + .target("require-explicit-cpu") + .crate_type("lib") + .arg("-Ctarget-cpu=generic") + .run(); + rustc().target("require-explicit-cpu").arg("--print=target-cpus").run(); } From c1790b14bcd62df7bccdfa7d7fbe4533dfdcdc8c Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 14 Jan 2025 11:40:22 +0530 Subject: [PATCH 04/71] uefi: Implement path UEFI paths can be of 4 types: 1. Absolute Shell Path: Uses shell mappings 2. Absolute Device Path: this is what we want 3: Relative root: path relative to the current root. 4: Relative Absolute shell path can be identified with `:` and Absolute Device path can be identified with `/`. Relative root path will start with `\`. The algorithm is mostly taken from edk2 UEFI shell implementation and is somewhat simple. Check for the path type in order. For Absolute Shell path, use `EFI_SHELL->GetDevicePathFromMap` to get a BorrowedDevicePath for the volume. For Relative paths, we use the current working directory to construct the new path. BorrowedDevicePath abstraction is needed to interact with `EFI_SHELL->GetDevicePathFromMap` which returns a Device Path Protocol with the lifetime of UEFI shell. Absolute Shell paths cannot exist if UEFI shell is missing. Signed-off-by: Ayush Singh --- library/std/src/sys/pal/uefi/helpers.rs | 50 ++++++++++- library/std/src/sys/path/mod.rs | 8 +- library/std/src/sys/path/uefi.rs | 105 ++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 library/std/src/sys/path/uefi.rs diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index 7504a0f7ad7..dccc137d6f5 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -14,10 +14,12 @@ use r_efi::protocols::{device_path, device_path_to_text, shell}; use crate::ffi::{OsStr, OsString}; use crate::io::{self, const_error}; +use crate::marker::PhantomData; use crate::mem::{MaybeUninit, size_of}; use crate::os::uefi::env::boot_services; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::os::uefi::{self}; +use crate::path::Path; use crate::ptr::NonNull; use crate::slice; use crate::sync::atomic::{AtomicPtr, Ordering}; @@ -278,6 +280,10 @@ impl OwnedDevicePath { pub(crate) const fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol { self.0.as_ptr() } + + pub(crate) const fn borrow<'a>(&'a self) -> BorrowedDevicePath<'a> { + BorrowedDevicePath::new(self.0) + } } impl Drop for OwnedDevicePath { @@ -293,13 +299,37 @@ impl Drop for OwnedDevicePath { impl crate::fmt::Debug for OwnedDevicePath { fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { - match device_path_to_text(self.0) { + match self.borrow().to_text() { Ok(p) => p.fmt(f), Err(_) => f.debug_struct("OwnedDevicePath").finish_non_exhaustive(), } } } +pub(crate) struct BorrowedDevicePath<'a> { + protocol: NonNull, + phantom: PhantomData<&'a r_efi::protocols::device_path::Protocol>, +} + +impl<'a> BorrowedDevicePath<'a> { + pub(crate) const fn new(protocol: NonNull) -> Self { + Self { protocol, phantom: PhantomData } + } + + pub(crate) fn to_text(&self) -> io::Result { + device_path_to_text(self.protocol) + } +} + +impl<'a> crate::fmt::Debug for BorrowedDevicePath<'a> { + fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result { + match self.to_text() { + Ok(p) => p.fmt(f), + Err(_) => f.debug_struct("BorrowedDevicePath").finish_non_exhaustive(), + } + } +} + pub(crate) struct OwnedProtocol { guid: r_efi::efi::Guid, handle: NonNull, @@ -452,3 +482,21 @@ pub(crate) fn open_shell() -> Option> { None } + +/// Get device path protocol associated with shell mapping. +/// +/// returns None in case no such mapping is exists +pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result> { + let shell = + open_shell().ok_or(io::const_error!(io::ErrorKind::NotFound, "UEFI Shell not found"))?; + let mut path = os_string_to_raw(map.as_os_str()) + .ok_or(io::const_error!(io::ErrorKind::InvalidFilename, "Invalid UEFI shell mapping"))?; + + // The Device Path Protocol pointer returned by UEFI shell is owned by the shell and is not + // freed throughout it's lifetime. So it has a 'static lifetime. + let protocol = unsafe { ((*shell.as_ptr()).get_device_path_from_map)(path.as_mut_ptr()) }; + let protocol = NonNull::new(protocol) + .ok_or(io::const_error!(io::ErrorKind::NotFound, "UEFI Shell mapping not found"))?; + + Ok(BorrowedDevicePath::new(protocol)) +} diff --git a/library/std/src/sys/path/mod.rs b/library/std/src/sys/path/mod.rs index 24a94ec7828..1fa4e80d678 100644 --- a/library/std/src/sys/path/mod.rs +++ b/library/std/src/sys/path/mod.rs @@ -5,12 +5,12 @@ cfg_if::cfg_if! { } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { mod sgx; pub use sgx::*; - } else if #[cfg(any( - target_os = "uefi", - target_os = "solid_asp3", - ))] { + } else if #[cfg(target_os = "solid_asp3")] { mod unsupported_backslash; pub use unsupported_backslash::*; + } else if #[cfg(target_os = "uefi")] { + mod uefi; + pub use uefi::*; } else { mod unix; pub use unix::*; diff --git a/library/std/src/sys/path/uefi.rs b/library/std/src/sys/path/uefi.rs new file mode 100644 index 00000000000..a3f4a3bfe1b --- /dev/null +++ b/library/std/src/sys/path/uefi.rs @@ -0,0 +1,105 @@ +#![forbid(unsafe_op_in_unsafe_fn)] +use crate::ffi::OsStr; +use crate::io; +use crate::path::{Path, PathBuf, Prefix}; +use crate::sys::{helpers, unsupported_err}; + +const FORWARD_SLASH: u8 = b'/'; +const COLON: u8 = b':'; + +#[inline] +pub fn is_sep_byte(b: u8) -> bool { + b == b'\\' +} + +#[inline] +pub fn is_verbatim_sep(b: u8) -> bool { + b == b'\\' +} + +pub fn parse_prefix(_: &OsStr) -> Option> { + None +} + +pub const MAIN_SEP_STR: &str = "\\"; +pub const MAIN_SEP: char = '\\'; + +/// UEFI paths can be of 4 types: +/// +/// 1. Absolute Shell Path: Uses shell mappings (eg: `FS0:`). Does not exist if UEFI shell not present. +/// It can be identified with `:`. +/// Eg: FS0:\abc\run.efi +/// +/// 2. Absolute Device Path: this is what we want +/// It can be identified with `/`. +/// Eg: PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)/\abc\run.efi +/// +/// 3: Relative root: path relative to the current volume. +/// It will start with `\`. +/// Eg: \abc\run.efi +/// +/// 4: Relative +/// Eg: run.efi +/// +/// The algorithm is mostly taken from edk2 UEFI shell implementation and is +/// somewhat simple. Check for the path type in order. +/// +/// The volume mapping in Absolute Shell Path (not the rest of the path) can be converted to Device +/// Path Protocol using `EFI_SHELL->GetDevicePathFromMap`. The rest of the path (Relative root +/// path), can just be appended to the remaining path. +/// +/// For Relative root, we get the current volume (either in Shell Mapping, or Device Path Protocol +/// form) and join it with the relative root path. We then recurse the function to resolve the Shell +/// Mapping if present. +/// +/// For Relative paths, we use the current working directory to construct +/// the new path and recurse the function to resolve the Shell mapping if present. +/// +/// Finally, at the end, we get the 2nd form, i.e. Absolute Device Path, which can be used in the +/// normal UEFI APIs such as file, process, etc. +/// Eg: PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)/\abc\run.efi +pub(crate) fn absolute(path: &Path) -> io::Result { + // Absolute Shell Path + if path.as_os_str().as_encoded_bytes().contains(&COLON) { + let mut path_components = path.components(); + // Since path is not empty, it has at least one Component + let prefix = path_components.next().unwrap(); + + let dev_path = helpers::get_device_path_from_map(prefix.as_ref())?; + let mut dev_path_text = dev_path.to_text().map_err(|_| unsupported_err())?; + + // UEFI Shell does not seem to end device path with `/` + if *dev_path_text.as_encoded_bytes().last().unwrap() != FORWARD_SLASH { + dev_path_text.push("/"); + } + + let mut ans = PathBuf::from(dev_path_text); + ans.push(path_components); + + return Ok(ans); + } + + // Absolute Device Path + if path.as_os_str().as_encoded_bytes().contains(&FORWARD_SLASH) { + return Ok(path.to_path_buf()); + } + + // cur_dir() always returns something + let cur_dir = crate::env::current_dir().unwrap(); + let mut path_components = path.components(); + + // Relative Root + if path_components.next().unwrap() == crate::path::Component::RootDir { + let mut ans = PathBuf::new(); + ans.push(cur_dir.components().next().unwrap()); + ans.push(path_components); + return absolute(&ans); + } + + absolute(&cur_dir.join(path)) +} + +pub(crate) fn is_absolute(path: &Path) -> bool { + let temp = path.as_os_str().as_encoded_bytes(); + temp.contains(&COLON) || temp.contains(&FORWARD_SLASH) +} From a56f9ad574773c06c511b0caee89382494ee24db Mon Sep 17 00:00:00 2001 From: dianne Date: Thu, 2 Jan 2025 21:47:54 -0800 Subject: [PATCH 05/71] remove Rule 3 from `ref_pat_eat_one_layer_2024` The debug assertion ensuring that the pattern mutability cap holds assumes the presence of Rule 3, so it now checks for that. I considered going back to only tracking the mutability cap when Rule 3 is present, but since the mutability cap is used in Rule 5's implementation too, the debug assertion would still need to check which typing rules are present. This also required some changes to tests: - `ref_pat_eat_one_layer_2021.rs` had a test for Rule 3; I'll be handling tests for earlier editions in a later commit, so as a stopgap I've #[cfg]ed it out. - One test case had to be moved from `well-typed-edition-2024.rs` to `borrowck-errors.rs` in order to get borrowck to run on it and emit an error. --- compiler/rustc_hir_typeck/src/pat.rs | 8 +++--- .../borrowck-errors.classic.stderr | 8 +++++- .../experimental/borrowck-errors.rs | 5 ++++ .../pattern-errors.classic.stderr | 26 +------------------ .../experimental/pattern-errors.rs | 4 +-- .../ref_pat_eat_one_layer_2021.rs | 2 ++ .../experimental/well-typed-edition-2024.rs | 3 --- 7 files changed, 22 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index cbd1db2ca25..cf9921312d5 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -243,8 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn downgrade_mut_inside_shared(&self) -> bool { // NB: RFC 3627 proposes stabilizing Rule 3 in all editions. If we adopt the same behavior // across all editions, this may be removed. - self.tcx.features().ref_pat_eat_one_layer_2024() - || self.tcx.features().ref_pat_eat_one_layer_2024_structural() + self.tcx.features().ref_pat_eat_one_layer_2024_structural() } /// Experimental pattern feature: when do reference patterns match against inherited references? @@ -425,7 +424,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { max_ref_mutbl: MutblCap, ) -> (Ty<'tcx>, ByRef, MutblCap) { #[cfg(debug_assertions)] - if def_br == ByRef::Yes(Mutability::Mut) && max_ref_mutbl != MutblCap::Mut { + if def_br == ByRef::Yes(Mutability::Mut) + && max_ref_mutbl != MutblCap::Mut + && self.downgrade_mut_inside_shared() + { span_bug!(pat.span, "Pattern mutability cap violated!"); } match adjust_mode { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr index c6246114075..f26151fe4f7 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr @@ -19,7 +19,13 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable -error: aborting due to 2 previous errors +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:17:23 + | +LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { + | ^ cannot borrow as mutable + +error: aborting due to 3 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.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs index a01e9ca2657..79581936418 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 @@ -13,4 +13,9 @@ pub fn main() { let &ref mut x = &0; //~^ cannot borrow data in a `&` reference as mutable [E0596] + + if let &Some(Some(x)) = &Some(&mut Some(0)) { + //[classic]~^ ERROR: cannot borrow data in a `&` reference as mutable + let _: &u32 = x; + } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr index 2bc3ecb7636..9b8a1e0ff39 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr @@ -46,18 +46,6 @@ help: replace this `&mut` pattern with `&` LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:23 - | -LL | if let Some(&Some(&mut _)) = &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(0)) { - | ~ - error[E0308]: mismatched types --> $DIR/pattern-errors.rs:34:23 | @@ -70,18 +58,6 @@ help: replace this `&mut` pattern with `&` LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:37:29 - | -LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { - | ~ - error[E0308]: mismatched types --> $DIR/pattern-errors.rs:40:17 | @@ -106,6 +82,6 @@ help: replace this `&mut` pattern with `&` LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ -error: aborting due to 9 previous errors +error: aborting due to 7 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.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index 3535ba9c701..f9cc8504d55 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 @@ -29,13 +29,13 @@ pub fn main() { //~^ ERROR: mismatched types } if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - //~^ ERROR: mismatched types + //[structural]~^ ERROR: mismatched types } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types } if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - //~^ ERROR: mismatched types + //[structural]~^ ERROR: mismatched types } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types 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 index 9372049a2b2..ab3264704ac 100644 --- 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 @@ -6,9 +6,11 @@ #![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/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 077b52d8f27..28e008a779b 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 @@ -35,9 +35,6 @@ pub fn main() { if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) { let _: &u32 = x; } - if let &Some(Some(x)) = &Some(&mut Some(0)) { - let _: &u32 = x; - } if let Some(&Some(&x)) = &Some(&mut Some(0)) { let _: u32 = x; } From c57708a58dbb7fbf3605dcc33d03d4e1d33747e3 Mon Sep 17 00:00:00 2001 From: dianne Date: Sat, 4 Jan 2025 01:38:17 -0800 Subject: [PATCH 06/71] add more tests where the rulesets disagree These come directly from the "Compare" tab of Typing Rust Patterns, though they had to be split across multiple files. They're not comprehensive, but they do provide some previously-missing coverage and are easier to check against the spec. Possibly they should be split up some more, since `pattern-errors.rs` is getting a bit unwieldy, but I'm not sure how best to go about that. --- .../borrowck-errors.classic.stderr | 52 ++- .../experimental/borrowck-errors.rs | 16 + .../pattern-errors.classic.stderr | 50 ++- .../experimental/pattern-errors.rs | 92 +++++ .../pattern-errors.structural.stderr | 319 +++++++++++++++++- .../ref-binding-on-inh-ref-errors.rs | 40 +++ ...inding-on-inh-ref-errors.structural.stderr | 74 ++++ ...ef-mut-inside-shared-ref-pat.classic.fixed | 4 + ...f-mut-inside-shared-ref-pat.classic.stderr | 10 +- .../ref-mut-inside-shared-ref-pat.rs | 4 + ...mut-inside-shared-ref-pat.structural.fixed | 4 + 11 files changed, 659 insertions(+), 6 deletions(-) create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr index f26151fe4f7..65b03f7a610 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr @@ -25,7 +25,55 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable -error: aborting due to 3 previous errors +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:22:11 + | +LL | let &[x] = &&mut [0]; + | ^ cannot borrow as mutable -Some errors have detailed explanations: E0507, E0596. +error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:26: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 + | +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:31: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 + | +help: consider borrowing the pattern binding + | +LL | let [&ref x] = &mut [&mut 0]; + | +++ + +error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:34:20 + | +LL | let [&mut 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 + | +help: consider borrowing the pattern binding + | +LL | let [&mut ref x] = &mut [&mut 0]; + | +++ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0507, E0508, 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.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs index 79581936418..7645c145b65 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 @@ -18,4 +18,20 @@ pub fn main() { //[classic]~^ ERROR: cannot borrow data in a `&` reference as mutable let _: &u32 = x; } + + let &[x] = &&mut [0]; + //[classic]~^ ERROR: cannot borrow data in a `&` reference as mutable + let _: &u32 = x; + + let [&x] = &[&mut 0]; + //[classic]~^ ERROR: cannot move out of type + let _: &u32 = x; + + #[cfg(classic)] // TODO: this should pass on `structural` but doesn't + let [&x] = &mut [&mut 0]; //[classic]~ ERROR: cannot move out of type + let _: &u32 = x; + + let [&mut x] = &mut [&mut 0]; + //[classic]~^ ERROR: cannot move out of type + let _: &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr index 9b8a1e0ff39..fbb9a35443a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr @@ -82,6 +82,54 @@ help: replace this `&mut` pattern with `&` LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ -error: aborting due to 7 previous errors +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:119:10 + | +LL | let [&mut x] = &[&mut 0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | let [&x] = &[&mut 0]; + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:124:10 + | +LL | let [&mut &x] = &[&mut 0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | let [&&x] = &[&mut 0]; + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:129:10 + | +LL | let [&mut &ref x] = &[&mut 0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | let [&&ref x] = &[&mut 0]; + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:134:10 + | +LL | let [&mut &(mut x)] = &[&mut 0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | let [&&(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/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index f9cc8504d55..b5e8bd112aa 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 @@ -44,3 +44,95 @@ pub fn main() { //~^ ERROR: mismatched types } } + +// TODO: these should be mutability mismatches on `structural` +fn structural_errors_0() { + let &[&mut x] = &&mut [0]; + //[structural]~^ ERROR: mismatched types + let _: u32 = x; + //[structural]~^ ERROR: mismatched types + + let &[&mut x] = &mut &mut [0]; + //[structural]~^ ERROR: mismatched types + let _: u32 = x; + //[structural]~^ ERROR: mismatched types + + let &[&mut ref x] = &&mut [0]; + //[structural]~^ ERROR: mismatched types + let _: &u32 = x; + + let &[&mut ref x] = &mut &mut [0]; + //[structural]~^ ERROR: mismatched types + let _: &u32 = x; + + let &[&mut mut x] = &&mut [0]; + //[structural]~^ ERROR: mismatched types + //[structural]~| ERROR: binding cannot be both mutable and by-reference + let _: u32 = x; + //[structural]~^ ERROR: mismatched types + + let &[&mut mut x] = &mut &mut [0]; + //[structural]~^ ERROR: mismatched types + //[structural]~| ERROR: binding cannot be both mutable and by-reference + let _: u32 = x; + //[structural]~^ ERROR: mismatched types +} + +fn structural_errors_1() { + let [&(mut x)] = &[&0]; + //[structural]~^ ERROR: binding cannot be both mutable and by-reference + let _: &u32 = x; + + let [&(mut x)] = &mut [&0]; + //[structural]~^ ERROR: binding cannot be both mutable and by-reference + let _: &u32 = x; +} + +// TODO: these should be mutability mismatches on `structural` +fn structural_errors_2() { + let [&&mut x] = &[&mut 0]; + //[structural]~^ ERROR: mismatched types + let _: u32 = x; + //[structural]~^ ERROR: mismatched types + + let [&&mut x] = &mut [&mut 0]; + let _: u32 = x; + + let [&&mut ref x] = &[&mut 0]; + //[structural]~^ ERROR: mismatched types + let _: &u32 = x; + + let [&&mut ref x] = &mut [&mut 0]; + let _: &u32 = x; + + let [&&mut mut x] = &[&mut 0]; + //[structural]~^ ERROR: binding cannot be both mutable and by-reference + //[structural]~| ERROR: mismatched types + let _: u32 = x; + //[structural]~^ ERROR: mismatched types + + let [&&mut mut x] = &mut [&mut 0]; + let _: u32 = x; +} + +fn classic_errors_0() { + let [&mut x] = &[&mut 0]; + //[classic]~^ ERROR: mismatched types + //[classic]~| cannot match inherited `&` with `&mut` pattern + let _: &u32 = x; + + let [&mut &x] = &[&mut 0]; + //[classic]~^ ERROR: mismatched types + //[classic]~| cannot match inherited `&` with `&mut` pattern + let _: u32 = x; + + let [&mut &ref x] = &[&mut 0]; + //[classic]~^ ERROR: mismatched types + //[classic]~| cannot match inherited `&` with `&mut` pattern + let _: &u32 = x; + + let [&mut &(mut x)] = &[&mut 0]; + //[classic]~^ ERROR: mismatched types + //[classic]~| cannot match inherited `&` with `&mut` pattern + let _: u32 = x; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr index 59d65553fae..4eabb8b1b0a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr @@ -84,6 +84,321 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { = note: expected enum `Option<{integer}>` found mutable reference `&mut _` -error: aborting due to 7 previous errors +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:50: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:50: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]; + | -For more information about this error, try `rustc --explain E0308`. +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:52:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:55: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:55: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:57:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:60: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:60: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:64: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:64: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:68: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:68: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[E0658]: binding cannot be both mutable and by-reference + --> $DIR/pattern-errors.rs:68:16 + | +LL | let &[&mut mut x] = &&mut [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[E0308]: mismatched types + --> $DIR/pattern-errors.rs:71:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:74: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:74: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[E0658]: binding cannot be both mutable and by-reference + --> $DIR/pattern-errors.rs:74:16 + | +LL | let &[&mut mut x] = &mut &mut [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[E0308]: mismatched types + --> $DIR/pattern-errors.rs:77:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/pattern-errors.rs:82:12 + | +LL | let [&(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[E0658]: binding cannot be both mutable and by-reference + --> $DIR/pattern-errors.rs:86:12 + | +LL | let [&(mut x)] = &mut [&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[E0308]: mismatched types + --> $DIR/pattern-errors.rs:93: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:95:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:101: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:108: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[E0658]: binding cannot be both mutable and by-reference + --> $DIR/pattern-errors.rs:108:16 + | +LL | let [&&mut mut x] = &[&mut 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[E0308]: mismatched types + --> $DIR/pattern-errors.rs:111:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error: aborting due to 27 previous errors + +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. 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 new file mode 100644 index 00000000000..3b27aa0f6ac --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs @@ -0,0 +1,40 @@ +//@ edition: 2024 +//@ revisions: classic structural +//@[classic] run-pass +//! Tests for errors from binding with `ref x` under a by-ref default binding mode. These can't be +//! in the same body as tests for other errors, since they're emitted during THIR construction. +#![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() { + let [&ref x] = &[&0]; + //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic)] let _: &&u32 = x; + + let [&ref x] = &[&mut 0]; + //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic)] let _: &&mut u32 = x; + + let [&ref x] = &mut [&0]; + //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic)] let _: &&u32 = x; + + let [&ref x] = &mut [&mut 0]; + //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic)] let _: &&mut u32 = x; + + let [&mut ref x] = &mut [&mut 0]; + //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic)] let _: &&mut u32 = x; + + let [&mut ref mut x] = &mut [&mut 0]; + //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic)] let _: &mut &mut u32 = x; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural.stderr new file mode 100644 index 00000000000..a952f72f08e --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural.stderr @@ -0,0 +1,74 @@ +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:11:11 + | +LL | let [&ref x] = &[&0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[&ref x] = &[&0]; + | + + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:16:11 + | +LL | let [&ref x] = &[&mut 0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[&ref x] = &[&mut 0]; + | + + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:21:11 + | +LL | let [&ref x] = &mut [&0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [&ref x] = &mut [&0]; + | ++++ + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:26:11 + | +LL | let [&ref x] = &mut [&mut 0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [&ref x] = &mut [&mut 0]; + | ++++ + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:31:15 + | +LL | let [&mut ref x] = &mut [&mut 0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [&mut ref x] = &mut [&mut 0]; + | ++++ + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:36:15 + | +LL | let [&mut ref mut x] = &mut [&mut 0]; + | ^^^^^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [&mut ref mut x] = &mut [&mut 0]; + | ++++ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed index 4f4941975d8..c7216d06bb7 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed @@ -30,4 +30,8 @@ pub fn main() { //~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; + + let &mut [x] = &mut &mut [0]; + //[classic]~^ 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.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr index 6c384a51fac..42a4a8597f7 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr @@ -38,6 +38,14 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | | | help: replace this `&` with `&mut`: `&mut` -error: aborting due to 5 previous errors +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:11 + | +LL | let &[x] = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 6 previous errors 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.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs index b29bff7603f..138de4f8eac 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 @@ -30,4 +30,8 @@ pub fn main() { //~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; + + let &[x] = &mut &mut [0]; + //[classic]~^ 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.structural.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed index 4f4941975d8..24fb99ae029 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed @@ -30,4 +30,8 @@ pub fn main() { //~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; + + let &[x] = &mut &mut [0]; + //[classic]~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &u32 = x; } From c03769524bc52b0761385cab4b0a5c5e8fd96bd7 Mon Sep 17 00:00:00 2001 From: dianne Date: Sat, 4 Jan 2025 22:01:01 -0800 Subject: [PATCH 07/71] "structural" ruleset: account for dbm mutability cap in Deref(EatInner) rules --- compiler/rustc_hir_typeck/src/pat.rs | 7 +- .../borrowck-errors.classic.stderr | 2 +- .../experimental/borrowck-errors.rs | 4 +- .../pattern-errors.classic.stderr | 8 +- .../experimental/pattern-errors.rs | 6 ++ .../pattern-errors.structural.stderr | 98 ++++++++++++++++++- 6 files changed, 112 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index cf9921312d5..1cbeb6d1fd0 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2344,7 +2344,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { InheritedRefMatchRule::EatInner => { if let ty::Ref(_, _, r_mutbl) = *expected.kind() { // Match against the reference type; don't consume the inherited ref. - pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl); + // NB: For RFC 3627's Rule 3, we limit the default binding mode's ref + // mutability to `pat_info.max_ref_mutbl`. If we implement a pattern typing + // ruleset with Rule 4 but not Rule 3, we'll need to check that here. + debug_assert!(self.downgrade_mut_inside_shared()); + let mutbl_cap = cmp::min(r_mutbl, pat_info.max_ref_mutbl.as_mutbl()); + pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(mutbl_cap); } else { // The expected type isn't a reference, so match against the inherited ref. if pat_mutbl > inh_mut { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr index 65b03f7a610..d72539eeeb2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr @@ -46,7 +46,7 @@ LL | let [&ref x] = &[&mut 0]; | +++ error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:31:16 + --> $DIR/borrowck-errors.rs:30:16 | LL | let [&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 7645c145b65..60f3a1dc18c 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 @@ -27,8 +27,8 @@ pub fn main() { //[classic]~^ ERROR: cannot move out of type let _: &u32 = x; - #[cfg(classic)] // TODO: this should pass on `structural` but doesn't - let [&x] = &mut [&mut 0]; //[classic]~ ERROR: cannot move out of type + let [&x] = &mut [&mut 0]; + //[classic]~^ ERROR: cannot move out of type let _: &u32 = x; let [&mut x] = &mut [&mut 0]; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr index fbb9a35443a..939eb4ea430 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr @@ -83,7 +83,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:119:10 + --> $DIR/pattern-errors.rs:125:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -95,7 +95,7 @@ LL | let [&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:124:10 + --> $DIR/pattern-errors.rs:130:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -107,7 +107,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:129:10 + --> $DIR/pattern-errors.rs:135:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -119,7 +119,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:134:10 + --> $DIR/pattern-errors.rs:140: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 b5e8bd112aa..90f77df871d 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 @@ -96,13 +96,16 @@ fn structural_errors_2() { //[structural]~^ ERROR: mismatched types let [&&mut x] = &mut [&mut 0]; + //[structural]~^ ERROR: mismatched types let _: u32 = x; + //[structural]~^ ERROR: mismatched types let [&&mut ref x] = &[&mut 0]; //[structural]~^ ERROR: mismatched types let _: &u32 = x; let [&&mut ref x] = &mut [&mut 0]; + //[structural]~^ ERROR: mismatched types let _: &u32 = x; let [&&mut mut x] = &[&mut 0]; @@ -112,7 +115,10 @@ fn structural_errors_2() { //[structural]~^ ERROR: mismatched types let [&&mut mut x] = &mut [&mut 0]; + //[structural]~^ ERROR: binding cannot be both mutable and by-reference + //[structural]~| ERROR: mismatched types let _: u32 = x; + //[structural]~^ ERROR: mismatched types } fn classic_errors_0() { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr index 4eabb8b1b0a..ed7e09c937a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr @@ -342,7 +342,38 @@ LL | let _: u32 = *x; | + error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:11 + --> $DIR/pattern-errors.rs:98: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:100:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:103:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -358,7 +389,23 @@ LL + let [&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:108:11 + --> $DIR/pattern-errors.rs:107: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:111:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -374,7 +421,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:108:16 + --> $DIR/pattern-errors.rs:111:16 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^ @@ -384,7 +431,7 @@ LL | let [&&mut 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:111:18 + --> $DIR/pattern-errors.rs:114:18 | LL | let _: u32 = x; | --- ^ expected `u32`, found `&_` @@ -398,7 +445,48 @@ help: consider dereferencing the borrow LL | let _: u32 = *x; | + -error: aborting due to 27 previous errors +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:117: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[E0658]: binding cannot be both mutable and by-reference + --> $DIR/pattern-errors.rs:117:16 + | +LL | let [&&mut mut x] = &mut [&mut 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[E0308]: mismatched types + --> $DIR/pattern-errors.rs:120:18 + | +LL | let _: u32 = x; + | --- ^ expected `u32`, found `&_` + | | + | expected due to this + | + = note: expected type `u32` + found reference `&_` +help: consider dereferencing the borrow + | +LL | let _: u32 = *x; + | + + +error: aborting due to 33 previous errors Some errors have detailed explanations: E0308, E0658. For more information about an error, try `rustc --explain E0308`. From f8315ae3b586fcd476e3dafd85b5891ddc70cc33 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 5 Jan 2025 19:42:26 -0800 Subject: [PATCH 08/71] "structural" ruleset: use the "classic" ruleset's diagnostic and fallback for inherited ref mutability mismatches I think the diagnostic could use some work, but it's more helpful than the alternative. The previous error was misleading, since it ignored the inherited reference altogether. --- compiler/rustc_hir_typeck/src/pat.rs | 58 +-- .../pattern-errors.classic.stderr | 8 +- .../experimental/pattern-errors.rs | 30 +- .../pattern-errors.structural.stderr | 437 ++++-------------- 4 files changed, 151 insertions(+), 382 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 1cbeb6d1fd0..ba5ba7a7452 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2318,22 +2318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // (RFC 3627, Rule 5). If we implement a pattern typing ruleset with Rule 4E // but not Rule 5, we'll need to check that here. debug_assert!(ref_pat_matches_mut_ref); - let err_msg = "mismatched types"; - let err = if let Some(span) = pat_prefix_span { - let mut err = self.dcx().struct_span_err(span, err_msg); - err.code(E0308); - err.note("cannot match inherited `&` with `&mut` pattern"); - err.span_suggestion_verbose( - span, - "replace this `&mut` pattern with `&`", - "&", - Applicability::MachineApplicable, - ); - err - } else { - self.dcx().struct_span_err(pat.span, err_msg) - }; - err.emit(); + self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span); } pat_info.binding_mode = ByRef::No; @@ -2353,22 +2338,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // The expected type isn't a reference, so match against the inherited ref. if pat_mutbl > inh_mut { - // We can't match an inherited shared reference with `&mut`. This will - // be a type error later, since we're matching a reference pattern - // against a non-reference type. + // We can't match an inherited shared reference with `&mut`. // 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. debug_assert!(ref_pat_matches_mut_ref); - } else { - pat_info.binding_mode = ByRef::No; - self.typeck_results - .borrow_mut() - .skipped_ref_pats_mut() - .insert(pat.hir_id); - self.check_pat(inner, expected, pat_info); - return expected; + self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span); } + + pat_info.binding_mode = ByRef::No; + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; } } InheritedRefMatchRule::EatBoth => { @@ -2442,6 +2423,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_ref(self.tcx, region, ty, mutbl) } + fn error_inherited_ref_mutability_mismatch( + &self, + pat: &'tcx Pat<'tcx>, + pat_prefix_span: Option, + ) -> ErrorGuaranteed { + let err_msg = "mismatched types"; + let err = if let Some(span) = pat_prefix_span { + let mut err = self.dcx().struct_span_err(span, err_msg); + err.code(E0308); + err.note("cannot match inherited `&` with `&mut` pattern"); + err.span_suggestion_verbose( + span, + "replace this `&mut` pattern with `&`", + "&", + Applicability::MachineApplicable, + ); + err + } else { + self.dcx().struct_span_err(pat.span, err_msg) + }; + err.emit() + } + fn try_resolve_slice_ty_to_array_ty( &self, before: &'tcx [Pat<'tcx>], diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr index 939eb4ea430..6993e724be2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr @@ -83,7 +83,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:125:10 + --> $DIR/pattern-errors.rs:123:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -95,7 +95,7 @@ LL | let [&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:130:10 + --> $DIR/pattern-errors.rs:128:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -107,7 +107,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:135:10 + --> $DIR/pattern-errors.rs:133:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -119,7 +119,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:140:10 + --> $DIR/pattern-errors.rs:138: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 90f77df871d..bbaa717e8bd 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 @@ -45,37 +45,36 @@ pub fn main() { } } -// TODO: these should be mutability mismatches on `structural` fn structural_errors_0() { let &[&mut x] = &&mut [0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; - //[structural]~^ ERROR: mismatched types let &[&mut x] = &mut &mut [0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; - //[structural]~^ ERROR: mismatched types let &[&mut ref x] = &&mut [0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let &[&mut ref x] = &mut &mut [0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let &[&mut mut x] = &&mut [0]; //[structural]~^ ERROR: mismatched types - //[structural]~| ERROR: binding cannot be both mutable and by-reference + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; - //[structural]~^ ERROR: mismatched types let &[&mut mut x] = &mut &mut [0]; //[structural]~^ ERROR: mismatched types - //[structural]~| ERROR: binding cannot be both mutable and by-reference + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; - //[structural]~^ ERROR: mismatched types } fn structural_errors_1() { @@ -88,37 +87,36 @@ fn structural_errors_1() { let _: &u32 = x; } -// TODO: these should be mutability mismatches on `structural` fn structural_errors_2() { let [&&mut x] = &[&mut 0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; - //[structural]~^ ERROR: mismatched types let [&&mut x] = &mut [&mut 0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; - //[structural]~^ ERROR: mismatched types let [&&mut ref x] = &[&mut 0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&&mut ref x] = &mut [&mut 0]; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&&mut mut x] = &[&mut 0]; - //[structural]~^ ERROR: binding cannot be both mutable and by-reference - //[structural]~| ERROR: mismatched types - let _: u32 = x; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern + let _: u32 = x; let [&&mut mut x] = &mut [&mut 0]; - //[structural]~^ ERROR: binding cannot be both mutable and by-reference - //[structural]~| ERROR: mismatched types - let _: u32 = x; //[structural]~^ ERROR: mismatched types + //[structural]~| cannot match inherited `&` with `&mut` pattern + let _: u32 = x; } fn classic_errors_0() { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr index ed7e09c937a..d835a3abe37 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr @@ -33,265 +33,136 @@ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:31:23 | LL | if let Some(&Some(&mut _)) = &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: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:34: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 _` + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:37:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - | ^^^^^^ ------------------------- this expression has type `&Option>>` - | | - | expected integer, found `&mut _` + | ^^^^^ | - = note: expected type `{integer}` - found mutable reference `&mut _` + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:40: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 _` + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:43: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 _` + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:50:11 + --> $DIR/pattern-errors.rs:49: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:50: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let &[&x] = &&mut [0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:52:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:55:11 + --> $DIR/pattern-errors.rs:54: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:55: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let &[&x] = &mut &mut [0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:57:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:60:11 + --> $DIR/pattern-errors.rs:59: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:60: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let &[&ref x] = &&mut [0]; + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:64: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:64: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let &[&ref x] = &mut &mut [0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:68:11 + --> $DIR/pattern-errors.rs:69: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:68:11 + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | -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[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:68:16 - | -LL | let &[&mut mut x] = &&mut [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[E0308]: mismatched types - --> $DIR/pattern-errors.rs:71:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + +LL | let &[&mut x] = &&mut [0]; + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:74: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:74: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let &[&mut x] = &mut &mut [0]; + | ~ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:74:16 - | -LL | let &[&mut mut x] = &mut &mut [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[E0308]: mismatched types - --> $DIR/pattern-errors.rs:77:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:82:12 + --> $DIR/pattern-errors.rs:81:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -301,7 +172,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:86:12 + --> $DIR/pattern-errors.rs:85:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -311,182 +182,78 @@ 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:93:11 + --> $DIR/pattern-errors.rs:91: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let [&&x] = &[&mut 0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:95:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:98:11 + --> $DIR/pattern-errors.rs:96: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let [&&x] = &mut [&mut 0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:100:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:103:11 + --> $DIR/pattern-errors.rs:101: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let [&&ref x] = &[&mut 0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:107:11 + --> $DIR/pattern-errors.rs:106: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let [&&ref x] = &mut [&mut 0]; + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:111: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 + = 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]; - | - -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:111:16 - | -LL | let [&&mut mut x] = &[&mut 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 +LL | let [&&mut x] = &[&mut 0]; + | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:114:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:117:11 + --> $DIR/pattern-errors.rs:116: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]; + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | +LL | let [&&mut x] = &mut [&mut 0]; + | ~ -error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:117:16 - | -LL | let [&&mut mut x] = &mut [&mut 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[E0308]: mismatched types - --> $DIR/pattern-errors.rs:120:18 - | -LL | let _: u32 = x; - | --- ^ expected `u32`, found `&_` - | | - | expected due to this - | - = note: expected type `u32` - found reference `&_` -help: consider dereferencing the borrow - | -LL | let _: u32 = *x; - | + - -error: aborting due to 33 previous errors +error: aborting due to 21 previous errors Some errors have detailed explanations: E0308, E0658. For more information about an error, try `rustc --explain E0308`. From 586ff158a25f421983be7b9f41437a73e56ef3cc Mon Sep 17 00:00:00 2001 From: dianne Date: Mon, 13 Jan 2025 00:07:16 -0800 Subject: [PATCH 09/71] "structural" ruleset: match against the inherited ref when a reference pattern doesn't match the mutability of an inner reference This is the `Deref(EatInner, FallbackToOuter)` rule in Typing Rust Patterns. --- compiler/rustc_hir_typeck/src/pat.rs | 13 +++- .../pattern-errors.classic.stderr | 22 +++--- .../experimental/pattern-errors.rs | 5 -- .../pattern-errors.structural.stderr | 71 +++++++------------ .../experimental/well-typed-edition-2024.rs | 25 ++++++- 5 files changed, 72 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ba5ba7a7452..992ab8cefc0 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2327,8 +2327,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } InheritedRefMatchRule::EatInner => { - if let ty::Ref(_, _, r_mutbl) = *expected.kind() { + if let ty::Ref(_, _, r_mutbl) = *expected.kind() + && pat_mutbl <= r_mutbl + { // Match against the reference type; don't consume the inherited ref. + // NB: The check for compatible pattern and ref type mutability assumes that + // `&` patterns can match against mutable references (RFC 3627, Rule 5). If + // we implement a pattern typing ruleset with Rule 4 (including the fallback + // to matching the inherited ref when the inner ref can't match) but not + // Rule 5, we'll need to check that here. + debug_assert!(ref_pat_matches_mut_ref); // NB: For RFC 3627's Rule 3, we limit the default binding mode's ref // mutability to `pat_info.max_ref_mutbl`. If we implement a pattern typing // ruleset with Rule 4 but not Rule 3, we'll need to check that here. @@ -2336,7 +2344,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mutbl_cap = cmp::min(r_mutbl, pat_info.max_ref_mutbl.as_mutbl()); pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(mutbl_cap); } else { - // The expected type isn't a reference, so match against the inherited ref. + // The reference pattern can't match against the expected type, so try + // matching against the inherited ref instead. if pat_mutbl > inh_mut { // We can't match an inherited shared reference with `&mut`. // NB: This assumes that `&` patterns can match against mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr index 6993e724be2..45ee489c520 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:15:17 + --> $DIR/pattern-errors.rs:10:17 | LL | if let Some(&mut x) = &Some(&mut 0) { | ^^^^^ @@ -11,7 +11,7 @@ LL | if let Some(&x) = &Some(&mut 0) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:19:17 + --> $DIR/pattern-errors.rs:14:17 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^^^^ @@ -23,7 +23,7 @@ LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:23:22 + --> $DIR/pattern-errors.rs:18:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ @@ -35,7 +35,7 @@ LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:28:17 + --> $DIR/pattern-errors.rs:23:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -47,7 +47,7 @@ LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:34:23 + --> $DIR/pattern-errors.rs:29:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -59,7 +59,7 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:40:17 + --> $DIR/pattern-errors.rs:35:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -71,7 +71,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:43:17 + --> $DIR/pattern-errors.rs:38:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -83,7 +83,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:123:10 + --> $DIR/pattern-errors.rs:118:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -95,7 +95,7 @@ LL | let [&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:128:10 + --> $DIR/pattern-errors.rs:123:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -107,7 +107,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:133:10 + --> $DIR/pattern-errors.rs:128:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -119,7 +119,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:138:10 + --> $DIR/pattern-errors.rs:133: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 bbaa717e8bd..1e170b7d3f8 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 @@ -7,11 +7,6 @@ #![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(&mut x) = &mut Some(&0) { - //[structural]~^ ERROR: mismatched types - let _: &u32 = x; - } - if let Some(&mut x) = &Some(&mut 0) { //[classic]~^ ERROR: mismatched types let _: &u32 = x; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr index d835a3abe37..3396d414819 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr @@ -1,36 +1,17 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:10:17 + --> $DIR/pattern-errors.rs:23:17 | -LL | if let Some(&mut x) = &mut Some(&0) { - | ^^^^^^ ------------- this expression has type `&mut Option<&{integer}>` - | | - | types differ in mutability +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^ | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:10:17 + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` | -LL | if let Some(&mut x) = &mut Some(&0) { - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL | if let Some(x) = &mut Some(&0) { +LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:28: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:31:23 + --> $DIR/pattern-errors.rs:26:23 | LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { | ^^^^^ @@ -42,7 +23,7 @@ LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:34:23 + --> $DIR/pattern-errors.rs:29:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -54,7 +35,7 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:37:29 + --> $DIR/pattern-errors.rs:32:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { | ^^^^^ @@ -66,7 +47,7 @@ LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:40:17 + --> $DIR/pattern-errors.rs:35:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -78,7 +59,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:43:17 + --> $DIR/pattern-errors.rs:38:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -90,7 +71,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:49:11 + --> $DIR/pattern-errors.rs:44:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -102,7 +83,7 @@ LL | let &[&x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:54:11 + --> $DIR/pattern-errors.rs:49:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -114,7 +95,7 @@ LL | let &[&x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:54:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -126,7 +107,7 @@ LL | let &[&ref x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:64:11 + --> $DIR/pattern-errors.rs:59:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -138,7 +119,7 @@ LL | let &[&ref x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:69:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -150,7 +131,7 @@ LL | let &[&mut x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:74:11 + --> $DIR/pattern-errors.rs:69:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -162,7 +143,7 @@ LL | let &[&mut x] = &mut &mut [0]; | ~ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:81:12 + --> $DIR/pattern-errors.rs:76:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -172,7 +153,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:85:12 + --> $DIR/pattern-errors.rs:80:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -182,7 +163,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:91:11 + --> $DIR/pattern-errors.rs:86:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -194,7 +175,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:96:11 + --> $DIR/pattern-errors.rs:91:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -206,7 +187,7 @@ LL | let [&&x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:11 + --> $DIR/pattern-errors.rs:96:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -218,7 +199,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:106:11 + --> $DIR/pattern-errors.rs:101:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -230,7 +211,7 @@ LL | let [&&ref x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:111:11 + --> $DIR/pattern-errors.rs:106:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -242,7 +223,7 @@ LL | let [&&mut x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:116:11 + --> $DIR/pattern-errors.rs:111:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^ @@ -253,7 +234,7 @@ help: replace this `&mut` pattern with `&` LL | let [&&mut x] = &mut [&mut 0]; | ~ -error: aborting due to 21 previous errors +error: aborting due to 20 previous errors Some errors have detailed explanations: E0308, E0658. 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 28e008a779b..1db7abc473e 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 @@ -3,7 +3,7 @@ //@ run-pass //! 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)] +#![allow(incomplete_features, unused_mut)] #![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] #![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] @@ -53,4 +53,27 @@ pub fn main() { if let Some(&Some(x)) = &mut Some(Some(0)) { 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]; + let _: &u32 = x; + + let [&mut ref x] = &mut [&0]; + let _: &&u32 = x; + + let [&mut ref mut x] = &mut [&0]; + let _: &mut &u32 = x; + + let [&mut mut x] = &mut [&0]; + let _: &u32 = x; + + let [&mut &x] = &mut [&0]; + let _: u32 = x; + + let [&mut &ref x] = &mut [&0]; + let _: &u32 = x; + + let [&mut &(mut x)] = &mut [&0]; + let _: u32 = x; } From 3f9b198dcbb09f189d6d2781401c526077f19fbe Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 15 Jan 2025 01:21:35 -0800 Subject: [PATCH 10/71] rename tests' revisions to allow testing multiple editions --- ...err => borrowck-errors.classic2024.stderr} | 0 .../experimental/borrowck-errors.rs | 16 ++-- ... => borrowck-errors.structural2024.stderr} | 0 ...tably-deref-shared-ref.classic2024.stderr} | 0 .../cannot-mutably-deref-shared-ref.rs | 6 +- ...ly-deref-shared-ref.structural2024.stderr} | 0 ....stderr => mut-ref-mut.classic2024.stderr} | 0 .../experimental/mut-ref-mut.rs | 6 +- ...derr => mut-ref-mut.structural2024.stderr} | 0 ...derr => pattern-errors.classic2024.stderr} | 0 .../experimental/pattern-errors.rs | 84 +++++++++---------- ...r => pattern-errors.structural2024.stderr} | 0 .../ref-binding-on-inh-ref-errors.rs | 44 +++++----- ...g-on-inh-ref-errors.structural2024.stderr} | 0 ...t-inside-shared-ref-pat.classic2024.fixed} | 8 +- ...-inside-shared-ref-pat.classic2024.stderr} | 0 .../ref-mut-inside-shared-ref-pat.rs | 8 +- ...nside-shared-ref-pat.structural2024.fixed} | 8 +- ...side-shared-ref-pat.structural2024.stderr} | 0 .../experimental/well-typed-edition-2024.rs | 6 +- 20 files changed, 93 insertions(+), 93 deletions(-) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{borrowck-errors.classic.stderr => borrowck-errors.classic2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{borrowck-errors.structural.stderr => borrowck-errors.structural2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{cannot-mutably-deref-shared-ref.classic.stderr => cannot-mutably-deref-shared-ref.classic2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{cannot-mutably-deref-shared-ref.structural.stderr => cannot-mutably-deref-shared-ref.structural2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{mut-ref-mut.classic.stderr => mut-ref-mut.classic2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{mut-ref-mut.structural.stderr => mut-ref-mut.structural2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{pattern-errors.classic.stderr => pattern-errors.classic2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{pattern-errors.structural.stderr => pattern-errors.structural2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{ref-binding-on-inh-ref-errors.structural.stderr => ref-binding-on-inh-ref-errors.structural2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{ref-mut-inside-shared-ref-pat.classic.fixed => ref-mut-inside-shared-ref-pat.classic2024.fixed} (79%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{ref-mut-inside-shared-ref-pat.classic.stderr => ref-mut-inside-shared-ref-pat.classic2024.stderr} (100%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{ref-mut-inside-shared-ref-pat.structural.fixed => ref-mut-inside-shared-ref-pat.structural2024.fixed} (79%) rename tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/{ref-mut-inside-shared-ref-pat.structural.stderr => ref-mut-inside-shared-ref-pat.structural2024.stderr} (100%) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr 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 60f3a1dc18c..9107d3ebf6a 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,9 +1,9 @@ //@ edition: 2024 -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //! Tests for pattern errors not handled by the pattern typing rules, but by borrowck. #![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&Some(x)) = Some(&Some(&mut 0)) { @@ -15,23 +15,23 @@ pub fn main() { //~^ cannot borrow data in a `&` reference as mutable [E0596] if let &Some(Some(x)) = &Some(&mut Some(0)) { - //[classic]~^ ERROR: cannot borrow data in a `&` reference as mutable + //[classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable let _: &u32 = x; } let &[x] = &&mut [0]; - //[classic]~^ ERROR: cannot borrow data in a `&` reference as mutable + //[classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable let _: &u32 = x; let [&x] = &[&mut 0]; - //[classic]~^ ERROR: cannot move out of type + //[classic2024]~^ ERROR: cannot move out of type let _: &u32 = x; let [&x] = &mut [&mut 0]; - //[classic]~^ ERROR: cannot move out of type + //[classic2024]~^ ERROR: cannot move out of type let _: &u32 = x; let [&mut x] = &mut [&mut 0]; - //[classic]~^ ERROR: cannot move out of type + //[classic2024]~^ ERROR: cannot move out of type let _: &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.classic2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs index e22bd1f8f6c..a493b672c92 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.rs @@ -1,9 +1,9 @@ //@ edition: 2024 -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //! Test that `&mut` patterns don't match shared reference types under new typing rules in Rust 2024 #![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { let &mut _ = &&0; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/cannot-mutably-deref-shared-ref.structural2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr 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 786587984ba..c2fb3f28709 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,9 +1,9 @@ //@ edition: 2024 -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //! Test diagnostics for binding with `mut` when the default binding mode is by-ref. #![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { struct Foo(u8); diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr 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 1e170b7d3f8..22ff0708d93 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,22 +1,22 @@ //@ edition: 2024 -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //! 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(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut x) = &Some(&mut 0) { - //[classic]~^ ERROR: mismatched types + //[classic2024]~^ ERROR: mismatched types let _: &u32 = x; } if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - //[classic]~^ ERROR: mismatched types + //[classic2024]~^ ERROR: mismatched types let _: u32 = x; } if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { - //[classic]~^ ERROR: mismatched types + //[classic2024]~^ ERROR: mismatched types let _: &u32 = x; } @@ -24,13 +24,13 @@ pub fn main() { //~^ ERROR: mismatched types } if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - //[structural]~^ ERROR: mismatched types + //[structural2024]~^ ERROR: mismatched types } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types } if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - //[structural]~^ ERROR: mismatched types + //[structural2024]~^ ERROR: mismatched types } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types @@ -42,96 +42,96 @@ pub fn main() { fn structural_errors_0() { let &[&mut x] = &&mut [0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let &[&mut x] = &mut &mut [0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let &[&mut ref x] = &&mut [0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let &[&mut ref x] = &mut &mut [0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let &[&mut mut x] = &&mut [0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let &[&mut mut x] = &mut &mut [0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; } fn structural_errors_1() { let [&(mut x)] = &[&0]; - //[structural]~^ ERROR: binding cannot be both mutable and by-reference + //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference let _: &u32 = x; let [&(mut x)] = &mut [&0]; - //[structural]~^ ERROR: binding cannot be both mutable and by-reference + //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference let _: &u32 = x; } fn structural_errors_2() { let [&&mut x] = &[&mut 0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&&mut x] = &mut [&mut 0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&&mut ref x] = &[&mut 0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&&mut ref x] = &mut [&mut 0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&&mut mut x] = &[&mut 0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&&mut mut x] = &mut [&mut 0]; - //[structural]~^ ERROR: mismatched types - //[structural]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; } fn classic_errors_0() { let [&mut x] = &[&mut 0]; - //[classic]~^ ERROR: mismatched types - //[classic]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&mut &x] = &[&mut 0]; - //[classic]~^ ERROR: mismatched types - //[classic]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&mut &ref x] = &[&mut 0]; - //[classic]~^ ERROR: mismatched types - //[classic]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&mut &(mut x)] = &[&mut 0]; - //[classic]~^ ERROR: mismatched types - //[classic]~| cannot match inherited `&` with `&mut` pattern + //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr 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 3b27aa0f6ac..de06489b9f8 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,40 +1,40 @@ //@ edition: 2024 -//@ revisions: classic structural -//@[classic] run-pass +//@ revisions: classic2024 structural2024 +//@[classic2024] run-pass //! Tests for errors from binding with `ref x` under a by-ref default binding mode. These can't be //! in the same body as tests for other errors, since they're emitted during THIR construction. #![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { let [&ref x] = &[&0]; - //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic)] let _: &&u32 = x; + //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &&u32 = x; let [&ref x] = &[&mut 0]; - //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic)] let _: &&mut u32 = x; + //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &&mut u32 = x; let [&ref x] = &mut [&0]; - //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic)] let _: &&u32 = x; + //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &&u32 = x; let [&ref x] = &mut [&mut 0]; - //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic)] let _: &&mut u32 = x; + //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &&mut u32 = x; let [&mut ref x] = &mut [&mut 0]; - //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic)] let _: &&mut u32 = x; + //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &&mut u32 = x; let [&mut ref mut x] = &mut [&mut 0]; - //[structural]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic)] let _: &mut &mut u32 = x; + //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &mut &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed similarity index 79% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed index c7216d06bb7..82c40878f49 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed @@ -1,11 +1,11 @@ //@ edition: 2024 //@ run-rustfix -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { @@ -32,6 +32,6 @@ pub fn main() { let _: &mut bool = b; let &mut [x] = &mut &mut [0]; - //[classic]~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[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.classic.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr 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 138de4f8eac..62b9037fac4 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,11 +1,11 @@ //@ edition: 2024 //@ run-rustfix -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { @@ -32,6 +32,6 @@ pub fn main() { let _: &mut bool = b; let &[x] = &mut &mut [0]; - //[classic]~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[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.structural.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed similarity index 79% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed index 24fb99ae029..32e955db12c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed @@ -1,11 +1,11 @@ //@ edition: 2024 //@ run-rustfix -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { @@ -32,6 +32,6 @@ pub fn main() { let _: &mut bool = b; let &[x] = &mut &mut [0]; - //[classic]~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[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.structural.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr similarity index 100% rename from tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr 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 1db7abc473e..8a2593d0e3a 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,11 +1,11 @@ //@ edition: 2024 -//@ revisions: classic structural +//@ revisions: classic2024 structural2024 //@ run-pass //! 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(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(Some(&x)) = &Some(&Some(0)) { From fdcbd7111b227193d4355b8072ff075d1e1df6d0 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 21 Jan 2025 01:09:55 -0800 Subject: [PATCH 11/71] minor test cleanup - Removes some excess parens - Removes 3 duplicated tests --- .../pattern-errors.classic2024.stderr | 22 ++------ .../experimental/pattern-errors.rs | 5 +- .../pattern-errors.structural2024.stderr | 52 +++++++------------ .../experimental/well-typed-edition-2024.rs | 6 --- 4 files changed, 26 insertions(+), 59 deletions(-) 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 45ee489c520..cc39e9b8ab7 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 @@ -71,19 +71,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:38:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:118:10 + --> $DIR/pattern-errors.rs:115:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -95,7 +83,7 @@ LL | let [&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:123:10 + --> $DIR/pattern-errors.rs:120:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -107,7 +95,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:128:10 + --> $DIR/pattern-errors.rs:125:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -119,7 +107,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:133:10 + --> $DIR/pattern-errors.rs:130:10 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^ @@ -130,6 +118,6 @@ help: replace this `&mut` pattern with `&` LL | let [&&(mut x)] = &[&mut 0]; | ~ -error: aborting due to 11 previous errors +error: aborting due to 10 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.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index 22ff0708d93..d1f404a634b 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 @@ -29,15 +29,12 @@ pub fn main() { if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types } - if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { //[structural2024]~^ ERROR: mismatched types } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types } - if let Some(&mut Some(x)) = &Some(Some(0)) { - //~^ ERROR: mismatched types - } } fn structural_errors_0() { 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 3396d414819..b996af4c134 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 @@ -35,16 +35,16 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:32:29 + --> $DIR/pattern-errors.rs:32:28 | -LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - | ^^^^^ +LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { + | ^^^^^ | = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | -LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { - | ~ +LL | if let Some(&Some(Some(&_))) = &Some(Some(&mut Some(0))) { + | ~ error[E0308]: mismatched types --> $DIR/pattern-errors.rs:35:17 @@ -59,19 +59,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:38:17 - | -LL | if let Some(&mut Some(x)) = &Some(Some(0)) { - | ^^^^^ - | - = note: cannot match inherited `&` with `&mut` pattern -help: replace this `&mut` pattern with `&` - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:44:11 + --> $DIR/pattern-errors.rs:41:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -83,7 +71,7 @@ LL | let &[&x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:49:11 + --> $DIR/pattern-errors.rs:46:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -95,7 +83,7 @@ LL | let &[&x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:54:11 + --> $DIR/pattern-errors.rs:51:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -107,7 +95,7 @@ LL | let &[&ref x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:56:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -119,7 +107,7 @@ LL | let &[&ref x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:64:11 + --> $DIR/pattern-errors.rs:61:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -131,7 +119,7 @@ LL | let &[&mut x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:69:11 + --> $DIR/pattern-errors.rs:66:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -143,7 +131,7 @@ LL | let &[&mut x] = &mut &mut [0]; | ~ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:76:12 + --> $DIR/pattern-errors.rs:73:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -153,7 +141,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:80:12 + --> $DIR/pattern-errors.rs:77:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -163,7 +151,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:86:11 + --> $DIR/pattern-errors.rs:83:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -175,7 +163,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:91:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -187,7 +175,7 @@ LL | let [&&x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:96:11 + --> $DIR/pattern-errors.rs:93:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -199,7 +187,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:11 + --> $DIR/pattern-errors.rs:98:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -211,7 +199,7 @@ LL | let [&&ref x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:106:11 + --> $DIR/pattern-errors.rs:103:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -223,7 +211,7 @@ LL | let [&&mut x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:111:11 + --> $DIR/pattern-errors.rs:108:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^ @@ -234,7 +222,7 @@ help: replace this `&mut` pattern with `&` LL | let [&&mut x] = &mut [&mut 0]; | ~ -error: aborting due to 20 previous errors +error: aborting due to 19 previous errors Some errors have detailed explanations: E0308, E0658. 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 8a2593d0e3a..906110d1dce 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 @@ -23,9 +23,6 @@ pub fn main() { if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { let _: u32 = x; } - if let Some(Some(&x)) = &Some(&Some(0)) { - let _: u32 = x; - } if let Some(&Some(&x)) = &mut Some(&Some(0)) { let _: u32 = x; } @@ -41,9 +38,6 @@ pub fn main() { if let Some(&Some(&x)) = &Some(&Some(0)) { let _: u32 = x; } - if let Some(&Some(&x)) = &Some(&mut Some(0)) { - let _: u32 = x; - } if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { let _: u32 = x; } From afd976b2b0382a91fba18f946a6272512895456a Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 21 Jan 2025 00:50:44 -0800 Subject: [PATCH 12/71] add more information to old tests --- .../pattern-errors.classic2024.stderr | 18 ++++----- .../experimental/pattern-errors.rs | 8 ++++ .../pattern-errors.structural2024.stderr | 38 +++++++++---------- 3 files changed, 36 insertions(+), 28 deletions(-) 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 cc39e9b8ab7..7b1abb6eaac 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 @@ -11,7 +11,7 @@ LL | if let Some(&x) = &Some(&mut 0) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:14:17 + --> $DIR/pattern-errors.rs:15:17 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^^^^ @@ -23,7 +23,7 @@ LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:18:22 + --> $DIR/pattern-errors.rs:20:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ @@ -35,7 +35,7 @@ LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:23:17 + --> $DIR/pattern-errors.rs:26:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -47,7 +47,7 @@ LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:29:23 + --> $DIR/pattern-errors.rs:34:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -59,7 +59,7 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:35:17 + --> $DIR/pattern-errors.rs:42:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -71,7 +71,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:115:10 + --> $DIR/pattern-errors.rs:123:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -83,7 +83,7 @@ LL | let [&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:120:10 + --> $DIR/pattern-errors.rs:128:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -95,7 +95,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:125:10 + --> $DIR/pattern-errors.rs:133:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -107,7 +107,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:130:10 + --> $DIR/pattern-errors.rs:138: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 d1f404a634b..14c32a053e3 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 @@ -9,31 +9,39 @@ pub fn main() { if let Some(&mut x) = &Some(&mut 0) { //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; } if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; } if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; } if let Some(&mut Some(&_)) = &Some(&Some(0)) { //~^ ERROR: mismatched types + //~| cannot match inherited `&` with `&mut` pattern } if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types + //~| cannot match inherited `&` with `&mut` pattern } if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { //[structural2024]~^ ERROR: mismatched types + //[structural2024]~| cannot match inherited `&` with `&mut` pattern } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types + //~| cannot match inherited `&` with `&mut` pattern } } 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 b996af4c134..05ff254ab98 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:23:17 + --> $DIR/pattern-errors.rs:26:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -11,7 +11,7 @@ LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:26:23 + --> $DIR/pattern-errors.rs:30:23 | LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { | ^^^^^ @@ -23,7 +23,7 @@ LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:29:23 + --> $DIR/pattern-errors.rs:34:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -35,7 +35,7 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:32:28 + --> $DIR/pattern-errors.rs:38:28 | LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { | ^^^^^ @@ -47,7 +47,7 @@ LL | if let Some(&Some(Some(&_))) = &Some(Some(&mut Some(0))) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:35:17 + --> $DIR/pattern-errors.rs:42:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -59,7 +59,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:41:11 + --> $DIR/pattern-errors.rs:49:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -71,7 +71,7 @@ LL | let &[&x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:46:11 + --> $DIR/pattern-errors.rs:54:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -83,7 +83,7 @@ LL | let &[&x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:51:11 + --> $DIR/pattern-errors.rs:59:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -95,7 +95,7 @@ LL | let &[&ref x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:56:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -107,7 +107,7 @@ LL | let &[&ref x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:61:11 + --> $DIR/pattern-errors.rs:69:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -119,7 +119,7 @@ LL | let &[&mut x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:66:11 + --> $DIR/pattern-errors.rs:74:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -131,7 +131,7 @@ LL | let &[&mut x] = &mut &mut [0]; | ~ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:73:12 + --> $DIR/pattern-errors.rs:81:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -141,7 +141,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:77:12 + --> $DIR/pattern-errors.rs:85:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -151,7 +151,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:83:11 + --> $DIR/pattern-errors.rs:91:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -163,7 +163,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:88:11 + --> $DIR/pattern-errors.rs:96:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -175,7 +175,7 @@ LL | let [&&x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:93:11 + --> $DIR/pattern-errors.rs:101:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -187,7 +187,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:98:11 + --> $DIR/pattern-errors.rs:106:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -199,7 +199,7 @@ LL | let [&&ref x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:103:11 + --> $DIR/pattern-errors.rs:111:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -211,7 +211,7 @@ LL | let [&&mut x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:108:11 + --> $DIR/pattern-errors.rs:116:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^ From 4ed44c9bd6608bb945bedf69b91dbaa6bdf0c6b7 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 21 Jan 2025 02:07:32 -0800 Subject: [PATCH 13/71] add a stable edition 2021 revision to pattern typing tests This serves two purposes. First, they're additional tests that stable Rust behavior hasn't been messed with. There's plenty of other pattern tests, so this is less important, but these at least are targeted at what's being changed. Second, this helps document exactly where the new rulesets agree and disagree with stable pattern typing. This will be especially important after the new rules for old editions are updated, since they need to be strictly more permissive; any patterns well-typed on stable should also be well-typed with the same resultant bindings on the (upcoming) new new old-edition rules. The unusual test ordering on `borrowck-errors.rs` and `ref-binding-on-inh-ref-errors.rs` are to hopefully reduce how much adding new tests will mess with line numbers in their stderr. --- .../borrowck-errors.classic2024.stderr | 70 ++--- .../experimental/borrowck-errors.rs | 37 ++- .../borrowck-errors.stable2021.stderr | 69 +++++ .../borrowck-errors.structural2024.stderr | 4 +- .../mut-ref-mut.classic2024.stderr | 4 +- .../experimental/mut-ref-mut.rs | 19 +- .../mut-ref-mut.structural2024.stderr | 4 +- .../pattern-errors.classic2024.stderr | 20 +- .../experimental/pattern-errors.rs | 84 ++++-- .../pattern-errors.stable2021.stderr | 283 ++++++++++++++++++ .../pattern-errors.structural2024.stderr | 38 +-- ...nding-on-inh-ref-errors.classic2024.stderr | 70 +++++ .../ref-binding-on-inh-ref-errors.rs | 53 +++- ...inding-on-inh-ref-errors.stable2021.stderr | 35 +++ ...ng-on-inh-ref-errors.structural2024.stderr | 56 ++-- ...ut-inside-shared-ref-pat.classic2024.fixed | 26 +- ...t-inside-shared-ref-pat.classic2024.stderr | 12 +- .../ref-mut-inside-shared-ref-pat.rs | 26 +- ...ut-inside-shared-ref-pat.stable2021.stderr | 58 ++++ ...inside-shared-ref-pat.structural2024.fixed | 26 +- ...nside-shared-ref-pat.structural2024.stderr | 10 +- .../experimental/well-typed-edition-2024.rs | 49 ++- .../well-typed-edition-2024.stable2021.stderr | 260 ++++++++++++++++ 23 files changed, 1109 insertions(+), 204 deletions(-) create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr 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 d72539eeeb2..331b86736a0 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,5 +1,33 @@ +error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:13: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 + | +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 + | +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 + | +help: consider borrowing the pattern binding + | +LL | let [&ref x] = &mut [&mut 0]; + | +++ + error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:9:29 + --> $DIR/borrowck-errors.rs:27:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -14,59 +42,31 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:14:10 + --> $DIR/borrowck-errors.rs:32: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:17:23 + --> $DIR/borrowck-errors.rs:35: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:22:11 + --> $DIR/borrowck-errors.rs:40:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable -error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:26: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 - | -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:30: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 - | -help: consider borrowing the pattern binding - | -LL | let [&ref x] = &mut [&mut 0]; - | +++ - -error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:34:20 +error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:44:20 | LL | let [&mut 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 | 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 9107d3ebf6a..3f5d9c8db5d 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,10 +1,28 @@ -//@ edition: 2024 -//@ revisions: classic2024 structural2024 +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] 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))] +/// 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. +fn errors_caught_in_hir_typeck_on_stable() { + let [&x] = &[&mut 0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability + //[classic2024]~^^^ ERROR: cannot move out of type + 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; +} + pub fn main() { if let Some(&Some(x)) = Some(&Some(&mut 0)) { //~^ ERROR: cannot move out of a shared reference [E0507] @@ -15,23 +33,16 @@ pub fn main() { //~^ cannot borrow data in a `&` reference as mutable [E0596] if let &Some(Some(x)) = &Some(&mut Some(0)) { - //[classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + //[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable let _: &u32 = x; } let &[x] = &&mut [0]; - //[classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable - let _: &u32 = x; - - let [&x] = &[&mut 0]; - //[classic2024]~^ ERROR: cannot move out of type - let _: &u32 = x; - - let [&x] = &mut [&mut 0]; - //[classic2024]~^ ERROR: cannot move out of type + //[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable let _: &u32 = x; let [&mut x] = &mut [&mut 0]; //[classic2024]~^ ERROR: cannot move out of type - let _: &mut u32 = x; + #[cfg(stable2021)] 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 new file mode 100644 index 00000000000..65c98e2da9c --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr @@ -0,0 +1,69 @@ +error[E0308]: mismatched types + --> $DIR/borrowck-errors.rs:13:10 + | +LL | let [&x] = &[&mut 0]; + | ^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&x] = &[&mut 0]; +LL + let [x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/borrowck-errors.rs:19:10 + | +LL | let [&x] = &mut [&mut 0]; + | ^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&x] = &mut [&mut 0]; +LL + let [x] = &mut [&mut 0]; + | + +error[E0507]: cannot move out of a shared reference + --> $DIR/borrowck-errors.rs:27: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:32: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:35: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:40:11 + | +LL | let &[x] = &&mut [0]; + | ^ cannot borrow as mutable + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0507, E0596. +For more information about an error, try `rustc --explain E0308`. 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 c6246114075..30d2f9f3d70 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:9:29 + --> $DIR/borrowck-errors.rs:27: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:14:10 + --> $DIR/borrowck-errors.rs:32: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 43560a18030..3849b4ed989 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:11:13 + --> $DIR/mut-ref-mut.rs:14: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:15:13 + --> $DIR/mut-ref-mut.rs:19:13 | LL | let Foo(mut a) = &mut Foo(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 c2fb3f28709..68d6871eabf 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,7 +1,10 @@ -//@ edition: 2024 -//@ revisions: classic2024 structural2024 +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 +//@[stable2021] run-pass //! Test diagnostics for binding with `mut` when the default binding mode is by-ref. -#![allow(incomplete_features)] +#![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))] @@ -9,10 +12,12 @@ pub fn main() { struct Foo(u8); let Foo(mut a) = &Foo(0); - //~^ ERROR: binding cannot be both mutable and by-reference - a = &42; + //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference + #[cfg(stable2021)] { a = 42 } + #[cfg(any(classic2024, structural2024))] { a = &42 } let Foo(mut a) = &mut Foo(0); - //~^ ERROR: binding cannot be both mutable and by-reference - a = &mut 42; + //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference + #[cfg(stable2021)] { a = 42 } + #[cfg(any(classic2024, structural2024))] { a = &mut 42 } } 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 43560a18030..3849b4ed989 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:11:13 + --> $DIR/mut-ref-mut.rs:14: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:15:13 + --> $DIR/mut-ref-mut.rs:19:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ 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 7b1abb6eaac..3a124dcead5 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:10:17 + --> $DIR/pattern-errors.rs:12:17 | LL | if let Some(&mut x) = &Some(&mut 0) { | ^^^^^ @@ -11,7 +11,7 @@ LL | if let Some(&x) = &Some(&mut 0) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:15:17 + --> $DIR/pattern-errors.rs:18:17 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^^^^ @@ -23,7 +23,7 @@ LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:20:22 + --> $DIR/pattern-errors.rs:24:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ @@ -35,7 +35,7 @@ LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:26:17 + --> $DIR/pattern-errors.rs:31:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -47,7 +47,7 @@ LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:34:23 + --> $DIR/pattern-errors.rs:41:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -59,7 +59,7 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:42:17 + --> $DIR/pattern-errors.rs:51:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -71,7 +71,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:123:10 + --> $DIR/pattern-errors.rs:147:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -83,7 +83,7 @@ LL | let [&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:128:10 + --> $DIR/pattern-errors.rs:153:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -95,7 +95,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:133:10 + --> $DIR/pattern-errors.rs:159:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -107,7 +107,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:138:10 + --> $DIR/pattern-errors.rs:165: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 14c32a053e3..c07c2972cd0 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,5 +1,7 @@ -//@ edition: 2024 -//@ revisions: classic2024 structural2024 +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] 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)] @@ -10,69 +12,83 @@ pub fn main() { if let Some(&mut x) = &Some(&mut 0) { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(stable2021)] let _: u32 = x; + #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - //[classic2024]~^ ERROR: mismatched types + //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; } if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(stable2021)] let _: u32 = x; + #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&_)) = &Some(&Some(0)) { //~^ ERROR: mismatched types - //~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| types differ in mutability + //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types - //~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| expected integer, found `&mut _` + //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` //[structural2024]~| cannot match inherited `&` with `&mut` pattern } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types - //~| cannot match inherited `&` with `&mut` pattern + //[stable2021]~| expected `Option<{integer}>`, found `&mut _` + //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } } fn structural_errors_0() { let &[&mut x] = &&mut [0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let &[&mut x] = &mut &mut [0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let &[&mut ref x] = &&mut [0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let &[&mut ref x] = &mut &mut [0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let &[&mut mut x] = &&mut [0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let &[&mut mut x] = &mut &mut [0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; } @@ -80,41 +96,49 @@ fn structural_errors_0() { fn structural_errors_1() { let [&(mut x)] = &[&0]; //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference - let _: &u32 = x; + #[cfg(stable2021)] let _: u32 = x; + #[cfg(classic2024)] let _: &u32 = x; let [&(mut x)] = &mut [&0]; //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference - let _: &u32 = x; + #[cfg(stable2021)] let _: u32 = x; + #[cfg(classic2024)] let _: &u32 = x; } fn structural_errors_2() { let [&&mut x] = &[&mut 0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&&mut x] = &mut [&mut 0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&&mut ref x] = &[&mut 0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&&mut ref x] = &mut [&mut 0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&&mut mut x] = &[&mut 0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&&mut mut x] = &mut [&mut 0]; - //[structural2024]~^ ERROR: mismatched types + //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability //[structural2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; } @@ -123,20 +147,24 @@ fn classic_errors_0() { let [&mut x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(stable2021)] let _: u32 = x; + #[cfg(structural2024)] let _: &u32 = x; let [&mut &x] = &[&mut 0]; - //[classic2024]~^ ERROR: mismatched types + //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: u32 = x; let [&mut &ref x] = &[&mut 0]; - //[classic2024]~^ ERROR: mismatched types + //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern let _: &u32 = x; let [&mut &(mut x)] = &[&mut 0]; - //[classic2024]~^ ERROR: mismatched types + //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern 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 new file mode 100644 index 00000000000..e7eb1813846 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr @@ -0,0 +1,283 @@ +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:18: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)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:31: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:36:17 + | +LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + | ^^^^^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:41: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:46:17 + | +LL | if let Some(&Some(Some(&mut _))) = &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:51: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:59: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:59: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:65:9 + | +LL | let &[&mut x] = &mut &mut [0]; + | ^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut &mut [{integer}; 1]` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:71: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:71: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:77:9 + | +LL | let &[&mut ref x] = &mut &mut [0]; + | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut &mut [{integer}; 1]` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:83: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:83: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:89:9 + | +LL | let &[&mut mut x] = &mut &mut [0]; + | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut &mut [{integer}; 1]` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:109:10 + | +LL | let [&&mut x] = &[&mut 0]; + | ^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:115:10 + | +LL | let [&&mut x] = &mut [&mut 0]; + | ^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:121:10 + | +LL | let [&&mut ref x] = &[&mut 0]; + | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:127:10 + | +LL | let [&&mut ref x] = &mut [&mut 0]; + | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:133:10 + | +LL | let [&&mut mut x] = &[&mut 0]; + | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:139:10 + | +LL | let [&&mut mut x] = &mut [&mut 0]; + | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:153: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:159: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:165: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 05ff254ab98..861ed2216cd 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:26:17 + --> $DIR/pattern-errors.rs:31:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -11,7 +11,7 @@ LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:30:23 + --> $DIR/pattern-errors.rs:36:23 | LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { | ^^^^^ @@ -23,7 +23,7 @@ LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:34:23 + --> $DIR/pattern-errors.rs:41:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -35,7 +35,7 @@ LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:38:28 + --> $DIR/pattern-errors.rs:46:28 | LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { | ^^^^^ @@ -47,7 +47,7 @@ LL | if let Some(&Some(Some(&_))) = &Some(Some(&mut Some(0))) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:42:17 + --> $DIR/pattern-errors.rs:51:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -59,7 +59,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:49:11 + --> $DIR/pattern-errors.rs:59:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -71,7 +71,7 @@ LL | let &[&x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:54:11 + --> $DIR/pattern-errors.rs:65:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -83,7 +83,7 @@ LL | let &[&x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:71:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -95,7 +95,7 @@ LL | let &[&ref x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:64:11 + --> $DIR/pattern-errors.rs:77:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -107,7 +107,7 @@ LL | let &[&ref x] = &mut &mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:69:11 + --> $DIR/pattern-errors.rs:83:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -119,7 +119,7 @@ LL | let &[&mut x] = &&mut [0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:74:11 + --> $DIR/pattern-errors.rs:89:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -131,7 +131,7 @@ LL | let &[&mut x] = &mut &mut [0]; | ~ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:81:12 + --> $DIR/pattern-errors.rs:97:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -141,7 +141,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:85:12 + --> $DIR/pattern-errors.rs:102:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -151,7 +151,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:91:11 + --> $DIR/pattern-errors.rs:109:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -163,7 +163,7 @@ LL | let [&&x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:96:11 + --> $DIR/pattern-errors.rs:115:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -175,7 +175,7 @@ LL | let [&&x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:101:11 + --> $DIR/pattern-errors.rs:121:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -187,7 +187,7 @@ LL | let [&&ref x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:106:11 + --> $DIR/pattern-errors.rs:127:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -199,7 +199,7 @@ LL | let [&&ref x] = &mut [&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:111:11 + --> $DIR/pattern-errors.rs:133:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -211,7 +211,7 @@ LL | let [&&mut x] = &[&mut 0]; | ~ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:116:11 + --> $DIR/pattern-errors.rs:139: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.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr new file mode 100644 index 00000000000..70cdcbd62eb --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -0,0 +1,70 @@ +error[E0308]: mismatched types + --> $DIR/ref-binding-on-inh-ref-errors.rs:60:10 + | +LL | let [&mut ref x] = &[&mut 0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | let [&ref x] = &[&mut 0]; + | ~ + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:74:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[ref mut x] = &[0]; + | + + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref-binding-on-inh-ref-errors.rs:74:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + | +LL | let [ref x] = &[0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[ref x] = &[0]; + | + + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:88:10 + | +LL | let [ref x] = &mut [0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [ref x] = &mut [0]; + | ++++ + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:93:10 + | +LL | let [ref mut x] = &mut [0]; + | ^^^^^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [ref mut x] = &mut [0]; + | ++++ + +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-binding-on-inh-ref-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs index de06489b9f8..a151c84739c 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,40 +1,63 @@ -//@ edition: 2024 -//@ revisions: classic2024 structural2024 +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 //@[classic2024] run-pass -//! Tests for errors from binding with `ref x` under a by-ref default binding mode. These can't be -//! in the same body as tests for other errors, since they're emitted during THIR construction. +//! 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))] -pub fn main() { +/// 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: this pattern relies on behavior which may change in edition 2024 //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; - let [&ref x] = &[&mut 0]; - //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural2024]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic2024)] let _: &&mut u32 = x; - let [&ref x] = &mut [&0]; //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; - let [&ref x] = &mut [&mut 0]; - //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 - //[structural2024]~| cannot override to bind by-reference when that is the implicit default - #[cfg(classic2024)] let _: &&mut u32 = x; - let [&mut ref x] = &mut [&mut 0]; //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&mut ref mut x] = &mut [&mut 0]; //[structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] let _: &mut u32 = x; #[cfg(classic2024)] let _: &mut &mut u32 = x; + + errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable(); +} + +/// To make absolutely sure binding with `ref` ignores inherited references on stable, let's +/// quarantine these typeck errors (from using a `&` pattern to match a `&mut` reference type). +fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() { + let [&ref x] = &[&mut 0]; + //[stable2021]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability + //[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &&mut u32 = x; + + let [&ref x] = &mut [&mut 0]; + //[stable2021]~^ ERROR: mismatched types + //[stable2021]~| types differ in mutability + //[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(classic2024)] let _: &&mut u32 = x; +} + +pub fn main() { + errors_from_eating_the_real_reference(); } 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 new file mode 100644 index 00000000000..c0518130368 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/ref-binding-on-inh-ref-errors.rs:46:10 + | +LL | let [&ref x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&ref x] = &[&mut 0]; +LL + let [ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/ref-binding-on-inh-ref-errors.rs:53:10 + | +LL | let [&ref x] = &mut [&mut 0]; + | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&ref x] = &mut [&mut 0]; +LL + let [ref x] = &mut [&mut 0]; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. 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 a952f72f08e..92aa8f1ea68 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,5 +1,5 @@ error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:11:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:16:11 | LL | let [&ref x] = &[&0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -11,19 +11,7 @@ LL | let &[&ref x] = &[&0]; | + error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:16:11 - | -LL | let [&ref x] = &[&mut 0]; - | ^^^ cannot override to bind by-reference when that is the implicit default - | - = note: for more information, see -help: make the implied reference pattern explicit - | -LL | let &[&ref x] = &[&mut 0]; - | + - -error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:21:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:22:11 | LL | let [&ref x] = &mut [&0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -35,19 +23,7 @@ LL | let &mut [&ref x] = &mut [&0]; | ++++ error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:26:11 - | -LL | let [&ref x] = &mut [&mut 0]; - | ^^^ cannot override to bind by-reference when that is the implicit default - | - = note: for more information, see -help: make the implied reference pattern explicit - | -LL | let &mut [&ref x] = &mut [&mut 0]; - | ++++ - -error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:31:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:28:15 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -59,7 +35,7 @@ LL | let &mut [&mut ref x] = &mut [&mut 0]; | ++++ error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:36:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:34:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^ cannot override to bind by-reference when that is the implicit default @@ -70,5 +46,29 @@ help: make the implied reference pattern explicit LL | let &mut [&mut ref mut x] = &mut [&mut 0]; | ++++ +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:46:11 + | +LL | let [&ref x] = &[&mut 0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[&ref x] = &[&mut 0]; + | + + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:53:11 + | +LL | let [&ref x] = &mut [&mut 0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [&ref x] = &mut [&mut 0]; + | ++++ + error: aborting due to 6 previous errors 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 82c40878f49..c01784d5076 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,6 +1,9 @@ -//@ edition: 2024 -//@ run-rustfix -//@ revisions: classic2024 structural2024 +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 +//@[classic2024] run-rustfix +//@[structural2024] run-rustfix //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] @@ -9,12 +12,14 @@ pub fn main() { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -22,16 +27,19 @@ pub fn main() { ($var:ident) => { ref mut $var }; } let &mut pat!(x) = &mut 0; - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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); - //~^ ERROR: cannot borrow as mutable inside an `&` pattern - //~| ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &mut [x] = &mut &mut [0]; - //[classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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 42a4a8597f7..5e98b77be40 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,5 +1,5 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:31 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -7,7 +7,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:16:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:20: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:24:15 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:29: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:28:19 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:34: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:28:30 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:34: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:34:11 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:41: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 62b9037fac4..fe40dabb553 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,6 +1,9 @@ -//@ edition: 2024 -//@ run-rustfix -//@ revisions: classic2024 structural2024 +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 +//@[classic2024] run-rustfix +//@[structural2024] run-rustfix //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] @@ -9,12 +12,14 @@ pub fn main() { if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -22,16 +27,19 @@ pub fn main() { ($var:ident) => { ref mut $var }; } let &pat!(x) = &mut 0; - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; let &(ref mut a, ref mut b) = &mut (true, false); - //~^ ERROR: cannot borrow as mutable inside an `&` pattern - //~| ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &[x] = &mut &mut [0]; - //[classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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 new file mode 100644 index 00000000000..72c6c05e184 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr @@ -0,0 +1,58 @@ +error[E0308]: mismatched types + --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:17 + | +LL | if let Some(&Some(ref mut 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/ref-mut-inside-shared-ref-pat.rs:20:12 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | ^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut Option>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/ref-mut-inside-shared-ref-pat.rs:29:9 + | +LL | let &pat!(x) = &mut 0; + | ^^^^^^^^ ------ this expression has type `&mut {integer}` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:9 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | ^^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut (bool, bool)` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut (bool, bool)` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/ref-mut-inside-shared-ref-pat.rs:41:9 + | +LL | let &[x] = &mut &mut [0]; + | ^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut &mut [{integer}; 1]` + found reference `&_` + +error: aborting due to 5 previous errors + +For more information about this 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 32e955db12c..4ee849b38c5 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,6 +1,9 @@ -//@ edition: 2024 -//@ run-rustfix -//@ revisions: classic2024 structural2024 +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 +//@[classic2024] run-rustfix +//@[structural2024] run-rustfix //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] @@ -9,12 +12,14 @@ pub fn main() { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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)) { - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -22,16 +27,19 @@ pub fn main() { ($var:ident) => { ref mut $var }; } let &mut pat!(x) = &mut 0; - //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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); - //~^ ERROR: cannot borrow as mutable inside an `&` pattern - //~| ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &[x] = &mut &mut [0]; - //[classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + //[stable2021]~^ ERROR: mismatched types + //[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 6c384a51fac..69cb6c438b6 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,5 +1,5 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:11:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:31 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -7,7 +7,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:16:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:20: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:24:15 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:29: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:28:19 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:34: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:28:30 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:34: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.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 906110d1dce..a8ad014fc5d 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,6 +1,9 @@ -//@ edition: 2024 -//@ revisions: classic2024 structural2024 -//@ run-pass +//@ revisions: stable2021 classic2024 structural2024 +//@[stable2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 +//@[classic2024] run-pass +//@[structural2024] run-pass //! 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)] @@ -9,65 +12,101 @@ pub fn main() { if let Some(Some(&x)) = &Some(&Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&_` let _: u32 = x; } if let Some(Some(&x)) = &Some(Some(&0)) { - let _: &u32 = x; + #[cfg(stable2021)] 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; } if let Some(&Some(x)) = &Some(Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected `Option<{integer}>`, found `&_` let _: u32 = x; } if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&mut _` let _: u32 = x; } if let Some(&Some(&x)) = &mut Some(&Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&_` let _: u32 = x; } if let Some(&Some(x)) = &mut Some(&Some(0)) { - let _: &u32 = x; + #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(classic2024, structural2024))] let _: &u32 = x; } if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) { let _: &u32 = x; } if let Some(&Some(&x)) = &Some(&mut Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability let _: u32 = x; } if let Some(&Some(&x)) = &Some(&Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&_` let _: u32 = x; } if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` let _: u32 = x; } if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability let _: u32 = x; } if let Some(&Some(x)) = &mut Some(Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected `Option<{integer}>`, found `&_` 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; let [&mut ref x] = &mut [&0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability let _: &&u32 = x; let [&mut ref mut x] = &mut [&0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability let _: &mut &u32 = x; let [&mut mut x] = &mut [&0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability let _: &u32 = x; let [&mut &x] = &mut [&0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability let _: u32 = x; let [&mut &ref x] = &mut [&0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability let _: &u32 = x; let [&mut &(mut x)] = &mut [&0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability 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 new file mode 100644 index 00000000000..c78459bb21c --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr @@ -0,0 +1,260 @@ +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:14: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)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:23: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:28: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:33: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:33: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(x)) = &mut Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:38: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)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:50:17 + | +LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { + | ^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:55: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)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:60: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:65:23 + | +LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:70: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:78: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:78: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:83: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:83: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:88: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:88: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:93: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:93: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:98: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:103: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:108: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 17 previous errors + +For more information about this error, try `rustc --explain E0308`. From f5567e1132c1dce184f34313715e3f22dc6a8e04 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 21 Jan 2025 02:19:27 -0800 Subject: [PATCH 14/71] organize old well-typed-edition-2024 tests This doesn't (or at least shouldn't!) add, remove, or change any test cases. I've grouped them by which rule variants they test. --- .../experimental/well-typed-edition-2024.rs | 77 ++++---- .../well-typed-edition-2024.stable2021.stderr | 168 +++++++++--------- 2 files changed, 130 insertions(+), 115 deletions(-) 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 a8ad014fc5d..3114b9d3bf8 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 @@ -11,20 +11,34 @@ #![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { - if let Some(Some(&x)) = &Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + // Tests not using match ergonomics. These should always succeed with the same bindings. + if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) { + let _: &u32 = x; } + + // 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(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(classic2024, structural2024))] let _: &u32 = x; + } if let Some(Some(&&x)) = &Some(Some(&0)) { //[stable2021]~^ mismatched types //[stable2021]~| expected integer, found `&_` 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; + } if let Some(&Some(x)) = &Some(Some(0)) { //[stable2021]~^ mismatched types //[stable2021]~| expected `Option<{integer}>`, found `&_` @@ -35,44 +49,45 @@ pub fn main() { //[stable2021]~| expected integer, found `&mut _` let _: u32 = x; } - if let Some(&Some(&x)) = &mut Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; - } - if let Some(&Some(x)) = &mut Some(&Some(0)) { - #[cfg(stable2021)] let _: u32 = x; - #[cfg(any(classic2024, structural2024))] let _: &u32 = x; - } - if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) { - let _: &u32 = x; - } - if let Some(&Some(&x)) = &Some(&mut Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: u32 = x; - } - if let Some(&Some(&x)) = &Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; - } - if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` - let _: u32 = x; - } + + // 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; } + + // 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; + } + + // Tests for `&` matching a lone inherited possibly-`&mut` reference + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` + let _: u32 = x; + } if let Some(&Some(x)) = &mut Some(Some(0)) { //[stable2021]~^ mismatched types //[stable2021]~| expected `Option<{integer}>`, found `&_` let _: u32 = x; } + // 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]~| types differ in mutability + let _: u32 = x; + } + if let Some(&Some(&x)) = &mut Some(&Some(0)) { + //[stable2021]~^ mismatched types + //[stable2021]~| expected integer, found `&_` + 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]; 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 c78459bb21c..e9c338de243 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,20 +1,5 @@ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:14: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)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:23:23 + --> $DIR/well-typed-edition-2024.rs:30:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -30,7 +15,22 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:28:17 + --> $DIR/well-typed-edition-2024.rs:37: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)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:42:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -41,7 +41,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:33:22 + --> $DIR/well-typed-edition-2024.rs:47:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -51,7 +51,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:33:22 + --> $DIR/well-typed-edition-2024.rs:47:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -61,59 +61,7 @@ LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:38: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)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:50:17 - | -LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { - | ^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` - | | - | types differ in mutability - | - = note: expected mutable reference `&mut Option<{integer}>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:55: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)) { - | ~ - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:60: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:65:23 + --> $DIR/well-typed-edition-2024.rs:54:23 | LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) { | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` @@ -128,7 +76,33 @@ LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | ~ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:70:17 + --> $DIR/well-typed-edition-2024.rs:61: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)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:68: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:73:17 | LL | if let Some(&Some(x)) = &mut Some(Some(0)) { | ^^^^^^^^ ------------------ this expression has type `&mut Option>` @@ -139,7 +113,33 @@ LL | if let Some(&Some(x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:78:10 + --> $DIR/well-typed-edition-2024.rs:80:17 + | +LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { + | ^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:85: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)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:93:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -149,7 +149,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:78:10 + --> $DIR/well-typed-edition-2024.rs:93:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ @@ -160,7 +160,7 @@ LL + let [x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:83:10 + --> $DIR/well-typed-edition-2024.rs:98:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -170,7 +170,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:83:10 + --> $DIR/well-typed-edition-2024.rs:98:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + let [ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:88:10 + --> $DIR/well-typed-edition-2024.rs:103:10 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -191,7 +191,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:88:10 + --> $DIR/well-typed-edition-2024.rs:103:10 | LL | let [&mut ref mut x] = &mut [&0]; | ^^^^^^^^^^^^^^ @@ -202,7 +202,7 @@ LL + let [ref mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:93:10 + --> $DIR/well-typed-edition-2024.rs:108:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -212,7 +212,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:93:10 + --> $DIR/well-typed-edition-2024.rs:108:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ @@ -223,7 +223,7 @@ LL + let [mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:98:10 + --> $DIR/well-typed-edition-2024.rs:113:10 | LL | let [&mut &x] = &mut [&0]; | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -234,7 +234,7 @@ LL | let [&mut &x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:103:10 + --> $DIR/well-typed-edition-2024.rs:118:10 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -245,7 +245,7 @@ LL | let [&mut &ref x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:108:10 + --> $DIR/well-typed-edition-2024.rs:123:10 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` From e288cff5cf38c66a5fad52d010e97f9dd3c5b991 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 21 Jan 2025 06:27:11 -0800 Subject: [PATCH 15/71] add tests differing between stable and new rules (with errors on new rules) Since there are so many ways to write these, I've opted to only include two sorts of test: simple tests that directly target the rules differing between rulesets and nuanced tests that produce different errors under different rulesets. I've also tried not to add any duplicate tests. `well-typed-edition-2024.rs` already has tests disagreeing with stable, so I've opted not to include any in this commit that are well-typed under the new rules. --- .../mut-ref-mut.classic2024.stderr | 17 +++- .../experimental/mut-ref-mut.rs | 6 ++ .../mut-ref-mut.structural2024.stderr | 12 ++- .../ref-binding-on-inh-ref-errors.rs | 44 ++++++++-- ...inding-on-inh-ref-errors.stable2021.stderr | 15 +++- ...ng-on-inh-ref-errors.structural2024.stderr | 81 +++++++++++++++++-- 6 files changed, 156 insertions(+), 19 deletions(-) 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 3849b4ed989..afaa925a757 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 @@ -18,6 +18,19 @@ LL | let Foo(mut a) = &mut Foo(0); = 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: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/mut-ref-mut.rs:24:10 + | +LL | let [&mut mut x] = &[&mut 0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL | let [&mut x] = &[&mut 0]; + | ~ -For more information about this error, try `rustc --explain E0658`. +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. 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 68d6871eabf..fbd6514df73 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 @@ -20,4 +20,10 @@ pub fn main() { //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference #[cfg(stable2021)] { 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 } } 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 3849b4ed989..fd82da70a18 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 @@ -18,6 +18,16 @@ LL | let Foo(mut a) = &mut Foo(0); = 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: aborting due to 2 previous errors +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mut-ref-mut.rs:24:15 + | +LL | let [&mut mut x] = &[&mut 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: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. 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 a151c84739c..4c88c0c63ae 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 @@ -2,7 +2,6 @@ //@[stable2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 -//@[classic2024] run-pass //! 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. @@ -36,8 +35,6 @@ fn errors_from_eating_the_real_reference() { //[structural2024]~| cannot override to bind by-reference when that is the implicit default #[cfg(stable2021)] let _: &mut u32 = x; #[cfg(classic2024)] let _: &mut &mut u32 = x; - - errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable(); } /// To make absolutely sure binding with `ref` ignores inherited references on stable, let's @@ -58,6 +55,43 @@ fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() { #[cfg(classic2024)] let _: &&mut u32 = x; } -pub fn main() { - errors_from_eating_the_real_reference(); +/// This one also needs to be quarantined for a typeck error on `classic2024` (eat-outer). +fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() { + let [&mut ref x] = &[&mut 0]; + //[classic2024]~^ ERROR: mismatched types + //[classic2024]~| cannot match inherited `&` with `&mut` pattern + //[structural2024]~^^^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] let _: &u32 = x; +} + +/// These should be errors in all editions. In edition 2024, they should be caught by the pattern +/// typing rules disallowing `ref` when there's an inherited reference. In old editions where that +/// resets the binding mode, they're borrowck errors due to binding with `ref mut`. +/// As a quirk of how the edition 2024 error is emitted during THIR construction, it ends up going +/// through borrowck as well, using the old `ref` behavior as a fallback, so we get that error too. +fn borrowck_errors_in_old_editions() { + let [ref mut x] = &[0]; + //~^ ERROR: cannot borrow data in a `&` reference as mutable + //[classic2024,structural2024]~| ERROR: this pattern relies on behavior which may change in edition 2024 + //[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default +} + +/// The remaining tests are purely for testing `ref` bindings in the presence of an inherited +/// reference. These should always fail on edition 2024 and succeed on edition 2021. +pub fn main() { + let [ref x] = &[0]; + //[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] let _: &u32 = x; + + let [ref x] = &mut [0]; + //[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] let _: &u32 = x; + + let [ref mut x] = &mut [0]; + //[classic2024,structural2024]~^ ERROR: this pattern relies on behavior which may change in edition 2024 + //[classic2024,structural2024]~| cannot override to bind by-reference when that is the implicit default + #[cfg(stable2021)] 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 c0518130368..a21e4bb5b8f 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:46:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:43: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:53:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:50:10 | LL | let [&ref x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -30,6 +30,13 @@ LL - let [&ref x] = &mut [&mut 0]; LL + let [ref x] = &mut [&mut 0]; | -error: aborting due to 2 previous errors +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref-binding-on-inh-ref-errors.rs:74:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^ cannot borrow as mutable -For more information about this error, try `rustc --explain E0308`. +error: aborting due to 3 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-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 92aa8f1ea68..ee2c831bfcc 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,5 +1,5 @@ error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:16:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:15:11 | LL | let [&ref x] = &[&0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -11,7 +11,7 @@ LL | let &[&ref x] = &[&0]; | + error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:22:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:21:11 | LL | let [&ref x] = &mut [&0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -23,7 +23,7 @@ LL | let &mut [&ref x] = &mut [&0]; | ++++ error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:28:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:27:15 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -35,7 +35,7 @@ LL | let &mut [&mut ref x] = &mut [&mut 0]; | ++++ error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:34:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:33:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^ cannot override to bind by-reference when that is the implicit default @@ -47,7 +47,7 @@ LL | let &mut [&mut ref mut x] = &mut [&mut 0]; | ++++ error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:46:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:43:11 | LL | let [&ref x] = &[&mut 0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -59,7 +59,7 @@ LL | let &[&ref x] = &[&mut 0]; | + error: this pattern relies on behavior which may change in edition 2024 - --> $DIR/ref-binding-on-inh-ref-errors.rs:53:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:50:11 | LL | let [&ref x] = &mut [&mut 0]; | ^^^ cannot override to bind by-reference when that is the implicit default @@ -70,5 +70,72 @@ help: make the implied reference pattern explicit LL | let &mut [&ref x] = &mut [&mut 0]; | ++++ -error: aborting due to 6 previous errors +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:60:15 + | +LL | let [&mut ref x] = &[&mut 0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[&mut ref x] = &[&mut 0]; + | + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:74:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[ref mut x] = &[0]; + | + + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref-binding-on-inh-ref-errors.rs:74:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + | +LL | let [ref x] = &[0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &[ref x] = &[0]; + | + + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:88:10 + | +LL | let [ref x] = &mut [0]; + | ^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [ref x] = &mut [0]; + | ++++ + +error: this pattern relies on behavior which may change in edition 2024 + --> $DIR/ref-binding-on-inh-ref-errors.rs:93:10 + | +LL | let [ref mut x] = &mut [0]; + | ^^^^^^^ cannot override to bind by-reference when that is the implicit default + | + = note: for more information, see +help: make the implied reference pattern explicit + | +LL | let &mut [ref mut x] = &mut [0]; + | ++++ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0596`. From 5be02d6f051d78a3140bf14b4f20537515f85a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 21 Jan 2025 17:00:28 +0100 Subject: [PATCH 16/71] Add `@bors rollup=never` to rustc-push PR body --- src/doc/rustc-dev-guide/josh-sync/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs index eff80b1091d..7ff5e018d2e 100644 --- a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs +++ b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs @@ -180,7 +180,7 @@ impl GitSync { ); println!( // Open PR with `subtree update` title to silence the `no-merges` triagebot check - " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=r?+@ghost" + " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=@bors+rollup=never%0Ar?+@ghost" ); drop(josh); From 6b48b67dfcc1f75bbf19ec690d498129e19360ab Mon Sep 17 00:00:00 2001 From: edwloef Date: Tue, 21 Jan 2025 22:28:04 +0100 Subject: [PATCH 17/71] optimize slice::ptr_rotate for compile-time-constant small rotates --- library/core/src/slice/rotate.rs | 331 ++++++++++++++++--------------- 1 file changed, 168 insertions(+), 163 deletions(-) diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index d8e0acb565c..20833dc31aa 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -11,11 +11,18 @@ use crate::{cmp, ptr}; /// /// # Algorithm /// -/// Algorithm 1 is used for small values of `left + right` or for large `T`. The elements are moved -/// into their final positions one at a time starting at `mid - left` and advancing by `right` steps -/// modulo `left + right`, such that only one temporary is needed. Eventually, we arrive back at -/// `mid - left`. However, if `gcd(left + right, right)` is not 1, the above steps skipped over -/// elements. For example: +/// Algorithm 1 is used if `min(left, right)` is small enough to fit onto a stack buffer. The +/// `min(left, right)` elements are copied onto the buffer, `memmove` is applied to the others, and +/// the ones on the buffer are moved back into the hole on the opposite side of where they +/// originated. +/// +/// Algorithms that can be vectorized outperform the above once `left + right` becomes large enough. +/// +/// Algorithm 2 is otherwise used for small values of `left + right` or for large `T`. The elements +/// are moved into their final positions one at a time starting at `mid - left` and advancing by +/// `right` steps modulo `left + right`, such that only one temporary is needed. Eventually, we +/// arrive back at `mid - left`. However, if `gcd(left + right, right)` is not 1, the above steps +/// skipped over elements. For example: /// ```text /// left = 10, right = 6 /// the `^` indicates an element in its final place @@ -39,13 +46,7 @@ use crate::{cmp, ptr}; /// `gcd(left + right, right)` value). The end result is that all elements are finalized once and /// only once. /// -/// Algorithm 2 is used if `left + right` is large but `min(left, right)` is small enough to -/// fit onto a stack buffer. The `min(left, right)` elements are copied onto the buffer, `memmove` -/// is applied to the others, and the ones on the buffer are moved back into the hole on the -/// opposite side of where they originated. -/// -/// Algorithms that can be vectorized outperform the above once `left + right` becomes large enough. -/// Algorithm 1 can be vectorized by chunking and performing many rounds at once, but there are too +/// Algorithm 2 can be vectorized by chunking and performing many rounds at once, but there are too /// few rounds on average until `left + right` is enormous, and the worst case of a single /// round is always there. Instead, algorithm 3 utilizes repeated swapping of /// `min(left, right)` elements until a smaller rotate problem is left. @@ -65,172 +66,176 @@ pub(super) unsafe fn ptr_rotate(mut left: usize, mut mid: *mut T, mut right: if T::IS_ZST { return; } - loop { - // N.B. the below algorithms can fail if these cases are not checked - if (right == 0) || (left == 0) { - return; + // N.B. the below algorithms can fail if these cases are not checked + if (right == 0) || (left == 0) { + return; + } + // `T` is not a zero-sized type, so it's okay to divide by its size. + if !cfg!(feature = "optimize_for_size") + && cmp::min(left, right) <= mem::size_of::() / mem::size_of::() + { + // Algorithm 1 + // The `[T; 0]` here is to ensure this is appropriately aligned for T + let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); + let buf = rawarray.as_mut_ptr() as *mut T; + // SAFETY: `mid-left <= mid-left+right < mid+right` + let dim = unsafe { mid.sub(left).add(right) }; + if left <= right { + // SAFETY: + // + // 1) The `if` condition about the sizes ensures `[mid-left; left]` will fit in + // `buf` without overflow and `buf` was created just above and so cannot be + // overlapped with any value of `[mid-left; left]` + // 2) [mid-left, mid+right) are all valid for reading and writing and we don't care + // about overlaps here. + // 3) The `if` condition about `left <= right` ensures writing `left` elements to + // `dim = mid-left+right` is valid because: + // - `buf` is valid and `left` elements were written in it in 1) + // - `dim+left = mid-left+right+left = mid+right` and we write `[dim, dim+left)` + unsafe { + // 1) + ptr::copy_nonoverlapping(mid.sub(left), buf, left); + // 2) + ptr::copy(mid, mid.sub(left), right); + // 3) + ptr::copy_nonoverlapping(buf, dim, left); + } + } else { + // SAFETY: same reasoning as above but with `left` and `right` reversed + unsafe { + ptr::copy_nonoverlapping(mid, buf, right); + ptr::copy(mid.sub(left), dim, left); + ptr::copy_nonoverlapping(buf, mid.sub(left), right); + } } - if !cfg!(feature = "optimize_for_size") - && ((left + right < 24) || (mem::size_of::() > mem::size_of::<[usize; 4]>())) - { - // Algorithm 1 - // Microbenchmarks indicate that the average performance for random shifts is better all - // the way until about `left + right == 32`, but the worst case performance breaks even - // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4 - // `usize`s, this algorithm also outperforms other algorithms. - // SAFETY: callers must ensure `mid - left` is valid for reading and writing. - let x = unsafe { mid.sub(left) }; - // beginning of first round - // SAFETY: see previous comment. - let mut tmp: T = unsafe { x.read() }; - let mut i = right; - // `gcd` can be found before hand by calculating `gcd(left + right, right)`, - // but it is faster to do one loop which calculates the gcd as a side effect, then - // doing the rest of the chunk - let mut gcd = right; - // benchmarks reveal that it is faster to swap temporaries all the way through instead - // of reading one temporary once, copying backwards, and then writing that temporary at - // the very end. This is possibly due to the fact that swapping or replacing temporaries - // uses only one memory address in the loop instead of needing to manage two. + } else if !cfg!(feature = "optimize_for_size") + && ((left + right < 24) || (mem::size_of::() > mem::size_of::<[usize; 4]>())) + { + // Algorithm 2 + // Microbenchmarks indicate that the average performance for random shifts is better all + // the way until about `left + right == 32`, but the worst case performance breaks even + // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4 + // `usize`s, this algorithm also outperforms other algorithms. + // SAFETY: callers must ensure `mid - left` is valid for reading and writing. + let x = unsafe { mid.sub(left) }; + // beginning of first round + // SAFETY: see previous comment. + let mut tmp: T = unsafe { x.read() }; + let mut i = right; + // `gcd` can be found before hand by calculating `gcd(left + right, right)`, + // but it is faster to do one loop which calculates the gcd as a side effect, then + // doing the rest of the chunk + let mut gcd = right; + // benchmarks reveal that it is faster to swap temporaries all the way through instead + // of reading one temporary once, copying backwards, and then writing that temporary at + // the very end. This is possibly due to the fact that swapping or replacing temporaries + // uses only one memory address in the loop instead of needing to manage two. + loop { + // [long-safety-expl] + // SAFETY: callers must ensure `[left, left+mid+right)` are all valid for reading and + // writing. + // + // - `i` start with `right` so `mid-left <= x+i = x+right = mid-left+right < mid+right` + // - `i <= left+right-1` is always true + // - if `i < left`, `right` is added so `i < left+right` and on the next + // iteration `left` is removed from `i` so it doesn't go further + // - if `i >= left`, `left` is removed immediately and so it doesn't go further. + // - overflows cannot happen for `i` since the function's safety contract ask for + // `mid+right-1 = x+left+right` to be valid for writing + // - underflows cannot happen because `i` must be bigger or equal to `left` for + // a subtraction of `left` to happen. + // + // So `x+i` is valid for reading and writing if the caller respected the contract + tmp = unsafe { x.add(i).replace(tmp) }; + // instead of incrementing `i` and then checking if it is outside the bounds, we + // check if `i` will go outside the bounds on the next increment. This prevents + // any wrapping of pointers or `usize`. + if i >= left { + i -= left; + if i == 0 { + // end of first round + // SAFETY: tmp has been read from a valid source and x is valid for writing + // according to the caller. + unsafe { x.write(tmp) }; + break; + } + // this conditional must be here if `left + right >= 15` + if i < gcd { + gcd = i; + } + } else { + i += right; + } + } + // finish the chunk with more rounds + for start in 1..gcd { + // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for + // reading and writing as per the function's safety contract, see [long-safety-expl] + // above + tmp = unsafe { x.add(start).read() }; + // [safety-expl-addition] + // + // Here `start < gcd` so `start < right` so `i < right+right`: `right` being the + // greatest common divisor of `(left+right, right)` means that `left = right` so + // `i < left+right` so `x+i = mid-left+i` is always valid for reading and writing + // according to the function's safety contract. + i = start + right; loop { - // [long-safety-expl] - // SAFETY: callers must ensure `[left, left+mid+right)` are all valid for reading and - // writing. - // - // - `i` start with `right` so `mid-left <= x+i = x+right = mid-left+right < mid+right` - // - `i <= left+right-1` is always true - // - if `i < left`, `right` is added so `i < left+right` and on the next - // iteration `left` is removed from `i` so it doesn't go further - // - if `i >= left`, `left` is removed immediately and so it doesn't go further. - // - overflows cannot happen for `i` since the function's safety contract ask for - // `mid+right-1 = x+left+right` to be valid for writing - // - underflows cannot happen because `i` must be bigger or equal to `left` for - // a subtraction of `left` to happen. - // - // So `x+i` is valid for reading and writing if the caller respected the contract + // SAFETY: see [long-safety-expl] and [safety-expl-addition] tmp = unsafe { x.add(i).replace(tmp) }; - // instead of incrementing `i` and then checking if it is outside the bounds, we - // check if `i` will go outside the bounds on the next increment. This prevents - // any wrapping of pointers or `usize`. if i >= left { i -= left; - if i == 0 { - // end of first round - // SAFETY: tmp has been read from a valid source and x is valid for writing - // according to the caller. - unsafe { x.write(tmp) }; + if i == start { + // SAFETY: see [long-safety-expl] and [safety-expl-addition] + unsafe { x.add(start).write(tmp) }; break; } - // this conditional must be here if `left + right >= 15` - if i < gcd { - gcd = i; - } } else { i += right; } } - // finish the chunk with more rounds - for start in 1..gcd { - // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for - // reading and writing as per the function's safety contract, see [long-safety-expl] - // above - tmp = unsafe { x.add(start).read() }; - // [safety-expl-addition] - // - // Here `start < gcd` so `start < right` so `i < right+right`: `right` being the - // greatest common divisor of `(left+right, right)` means that `left = right` so - // `i < left+right` so `x+i = mid-left+i` is always valid for reading and writing - // according to the function's safety contract. - i = start + right; + } + } else { + loop { + if left >= right { + // Algorithm 3 + // There is an alternate way of swapping that involves finding where the last swap + // of this algorithm would be, and swapping using that last chunk instead of swapping + // adjacent chunks like this algorithm is doing, but this way is still faster. loop { - // SAFETY: see [long-safety-expl] and [safety-expl-addition] - tmp = unsafe { x.add(i).replace(tmp) }; - if i >= left { - i -= left; - if i == start { - // SAFETY: see [long-safety-expl] and [safety-expl-addition] - unsafe { x.add(start).write(tmp) }; - break; - } - } else { - i += right; + // SAFETY: + // `left >= right` so `[mid-right, mid+right)` is valid for reading and writing + // Subtracting `right` from `mid` each turn is counterbalanced by the addition and + // check after it. + unsafe { + ptr::swap_nonoverlapping(mid.sub(right), mid, right); + mid = mid.sub(right); + } + left -= right; + if left < right { + break; + } + } + } else { + // Algorithm 3, `left < right` + loop { + // SAFETY: `[mid-left, mid+left)` is valid for reading and writing because + // `left < right` so `mid+left < mid+right`. + // Adding `left` to `mid` each turn is counterbalanced by the subtraction and check + // after it. + unsafe { + ptr::swap_nonoverlapping(mid.sub(left), mid, left); + mid = mid.add(left); + } + right -= left; + if right < left { + break; } } } - return; - // `T` is not a zero-sized type, so it's okay to divide by its size. - } else if !cfg!(feature = "optimize_for_size") - && cmp::min(left, right) <= mem::size_of::() / mem::size_of::() - { - // Algorithm 2 - // The `[T; 0]` here is to ensure this is appropriately aligned for T - let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); - let buf = rawarray.as_mut_ptr() as *mut T; - // SAFETY: `mid-left <= mid-left+right < mid+right` - let dim = unsafe { mid.sub(left).add(right) }; - if left <= right { - // SAFETY: - // - // 1) The `else if` condition about the sizes ensures `[mid-left; left]` will fit in - // `buf` without overflow and `buf` was created just above and so cannot be - // overlapped with any value of `[mid-left; left]` - // 2) [mid-left, mid+right) are all valid for reading and writing and we don't care - // about overlaps here. - // 3) The `if` condition about `left <= right` ensures writing `left` elements to - // `dim = mid-left+right` is valid because: - // - `buf` is valid and `left` elements were written in it in 1) - // - `dim+left = mid-left+right+left = mid+right` and we write `[dim, dim+left)` - unsafe { - // 1) - ptr::copy_nonoverlapping(mid.sub(left), buf, left); - // 2) - ptr::copy(mid, mid.sub(left), right); - // 3) - ptr::copy_nonoverlapping(buf, dim, left); - } - } else { - // SAFETY: same reasoning as above but with `left` and `right` reversed - unsafe { - ptr::copy_nonoverlapping(mid, buf, right); - ptr::copy(mid.sub(left), dim, left); - ptr::copy_nonoverlapping(buf, mid.sub(left), right); - } - } - return; - } else if left >= right { - // Algorithm 3 - // There is an alternate way of swapping that involves finding where the last swap - // of this algorithm would be, and swapping using that last chunk instead of swapping - // adjacent chunks like this algorithm is doing, but this way is still faster. - loop { - // SAFETY: - // `left >= right` so `[mid-right, mid+right)` is valid for reading and writing - // Subtracting `right` from `mid` each turn is counterbalanced by the addition and - // check after it. - unsafe { - ptr::swap_nonoverlapping(mid.sub(right), mid, right); - mid = mid.sub(right); - } - left -= right; - if left < right { - break; - } - } - } else { - // Algorithm 3, `left < right` - loop { - // SAFETY: `[mid-left, mid+left)` is valid for reading and writing because - // `left < right` so `mid+left < mid+right`. - // Adding `left` to `mid` each turn is counterbalanced by the subtraction and check - // after it. - unsafe { - ptr::swap_nonoverlapping(mid.sub(left), mid, left); - mid = mid.add(left); - } - right -= left; - if right < left { - break; - } + + if (right == 0) || (left == 0) { + return; } } } From cc19dfa125e280545e6e599f1aaf27ffb0c55ffd Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Wed, 22 Jan 2025 00:20:54 +0100 Subject: [PATCH 18/71] Add `AsyncFn*` to core prelude --- library/core/src/prelude/common.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs index e38ef1e147c..8b116cecb52 100644 --- a/library/core/src/prelude/common.rs +++ b/library/core/src/prelude/common.rs @@ -12,6 +12,9 @@ pub use crate::marker::{Copy, Send, Sized, Sync, Unpin}; #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; +#[stable(feature = "async_closure", since = "1.85.0")] +#[doc(no_inline)] +pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; // Re-exported functions #[stable(feature = "core_prelude", since = "1.4.0")] From ccb967438de778b7f4ee3cf94f3e8163f6f5c53f Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 22 Jan 2025 16:01:10 +0100 Subject: [PATCH 19/71] simplify similar_tokens from Option> to Vec<_> --- compiler/rustc_ast/src/token.rs | 14 +++++++------- compiler/rustc_builtin_macros/src/format.rs | 15 +++++++-------- compiler/rustc_parse/src/parser/expr.rs | 3 +-- compiler/rustc_parse/src/parser/mod.rs | 6 ++---- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 3b7367d1ee2..5b6e65c804f 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -527,13 +527,13 @@ impl TokenKind { /// Returns tokens that are likely to be typed accidentally instead of the current token. /// Enables better error recovery when the wrong token is found. - pub fn similar_tokens(&self) -> Option> { - match *self { - Comma => Some(vec![Dot, Lt, Semi]), - Semi => Some(vec![Colon, Comma]), - Colon => Some(vec![Semi]), - FatArrow => Some(vec![Eq, RArrow, Ge, Gt]), - _ => None, + pub fn similar_tokens(&self) -> Vec { + match self { + Comma => vec![Dot, Lt, Semi], + Semi => vec![Colon, Comma], + Colon => vec![Semi], + FatArrow => vec![Eq, RArrow, Ge, Gt], + _ => vec![], } } diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 5202fe26c40..d9cfbaf63e6 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -101,15 +101,14 @@ fn parse_args<'a>(ecx: &ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, match p.expect(exp!(Comma)) { Err(err) => { - match token::TokenKind::Comma.similar_tokens() { - Some(tks) if tks.contains(&p.token.kind) => { - // If a similar token is found, then it may be a typo. We - // consider it as a comma, and continue parsing. - err.emit(); - p.bump(); - } + if token::TokenKind::Comma.similar_tokens().contains(&p.token.kind) { + // If a similar token is found, then it may be a typo. We + // consider it as a comma, and continue parsing. + err.emit(); + p.bump(); + } else { // Otherwise stop the parsing and return the error. - _ => return Err(err), + return Err(err); } } Ok(Recovered::Yes(_)) => (), diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5cd02128287..cf87c8c9495 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3115,8 +3115,7 @@ impl<'a> Parser<'a> { let arm_body; let is_fat_arrow = this.check(exp!(FatArrow)); let is_almost_fat_arrow = TokenKind::FatArrow - .similar_tokens() - .is_some_and(|similar_tokens| similar_tokens.contains(&this.token.kind)); + .similar_tokens().contains(&this.token.kind); // this avoids the compiler saying that a `,` or `}` was expected even though // the pattern isn't a never pattern (and thus an arm body is required) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 10756be6afb..aba84d44a44 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -923,10 +923,8 @@ impl<'a> Parser<'a> { _ => { // Attempt to keep parsing if it was a similar separator. - if let Some(tokens) = exp.tok.similar_tokens() { - if tokens.contains(&self.token.kind) { - self.bump(); - } + if exp.tok.similar_tokens().contains(&self.token.kind) { + self.bump(); } } } From 5f01e12ea8035fdfc23eefaf6b580dbb9a8863ec Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 22 Jan 2025 16:50:22 +0100 Subject: [PATCH 20/71] simplify similar_tokens from Vec<_> to &[_] --- compiler/rustc_ast/src/token.rs | 12 ++++++------ compiler/rustc_parse/src/parser/expr.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 5b6e65c804f..100f664a89f 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -527,13 +527,13 @@ impl TokenKind { /// Returns tokens that are likely to be typed accidentally instead of the current token. /// Enables better error recovery when the wrong token is found. - pub fn similar_tokens(&self) -> Vec { + pub fn similar_tokens(&self) -> &[TokenKind] { match self { - Comma => vec![Dot, Lt, Semi], - Semi => vec![Colon, Comma], - Colon => vec![Semi], - FatArrow => vec![Eq, RArrow, Ge, Gt], - _ => vec![], + Comma => &[Dot, Lt, Semi], + Semi => &[Colon, Comma], + Colon => &[Semi], + FatArrow => &[Eq, RArrow, Ge, Gt], + _ => &[], } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index cf87c8c9495..0affca1f825 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3114,8 +3114,8 @@ impl<'a> Parser<'a> { let span_before_body = this.prev_token.span; let arm_body; let is_fat_arrow = this.check(exp!(FatArrow)); - let is_almost_fat_arrow = TokenKind::FatArrow - .similar_tokens().contains(&this.token.kind); + let is_almost_fat_arrow = + TokenKind::FatArrow.similar_tokens().contains(&this.token.kind); // this avoids the compiler saying that a `,` or `}` was expected even though // the pattern isn't a never pattern (and thus an arm body is required) From b06e840d9e8e27ac1f79be5e6d2778455146f665 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Fri, 24 Jan 2025 00:37:05 +0100 Subject: [PATCH 21/71] Add comments about address spaces --- compiler/rustc_codegen_llvm/src/builder.rs | 2 +- compiler/rustc_codegen_llvm/src/common.rs | 2 ++ compiler/rustc_codegen_llvm/src/consts.rs | 13 +++++++++++++ .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 10 ++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 1b99fea8d51..4d572dc56fb 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1226,7 +1226,7 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> { fn get_static(&mut self, def_id: DefId) -> &'ll Value { // Forward to the `get_static` method of `CodegenCx` let s = self.cx().get_static(def_id); - // Cast to default address space if statics are in a different addrspace + // Cast to default address space if globals are in a different addrspace self.cx().const_pointercast(s, self.type_ptr()) } } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index bd792c02810..5031df06b05 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -221,6 +221,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global); } llvm::set_linkage(g, llvm::Linkage::InternalLinkage); + // Cast to default address space if globals are in a different addrspace let g = self.const_pointercast(g, self.type_ptr()); (s.to_owned(), g) }) @@ -324,6 +325,7 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let llval = unsafe { llvm::LLVMConstInBoundsGEP2( self.type_i8(), + // Cast to the required address space if necessary self.const_pointercast(base_addr, self.type_ptr_ext(base_addr_space)), &self.const_usize(offset.bytes()), 1, diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index b88fd133e8e..771ebf2057f 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -214,6 +214,10 @@ impl<'ll> CodegenCx<'ll, '_> { unsafe { llvm::LLVMConstPointerCast(val, ty) } } + /// Create a global variable. + /// + /// The returned global variable is a pointer in the default address space for globals. + /// Fails if a symbol with the given name already exists. pub(crate) fn static_addr_of_mut( &self, cv: &'ll Value, @@ -237,6 +241,9 @@ impl<'ll> CodegenCx<'ll, '_> { gv } + /// Create a global constant. + /// + /// The returned global variable is a pointer in the default address space for globals. pub(crate) fn static_addr_of_impl( &self, cv: &'ll Value, @@ -534,8 +541,14 @@ impl<'ll> CodegenCx<'ll, '_> { } impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> { + /// Get a pointer to a global variable. + /// + /// The pointer will always be in the default address space. If global variables default to a + /// different address space, an addrspacecast is inserted. fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value { let gv = self.static_addr_of_impl(cv, align, kind); + // static_addr_of_impl returns the bare global variable, which might not be in the default + // address space. Cast to the default address space if necessary. self.const_pointercast(gv, self.type_ptr()) } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index e4da540da5c..b9e3a6975d6 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1500,6 +1500,14 @@ fn build_vtable_type_di_node<'ll, 'tcx>( .di_node } +/// Get the global variable for the vtable. +/// +/// When using global variables, we may have created an addrspacecast to get a pointer to the +/// default address space if global variables are created in a different address space. +/// For modifying the vtable, we need the real global variable. This function accepts either a +/// global variable (which is simply returned), or an addrspacecast constant expression. +/// If the given value is an addrspacecast, the cast is removed and the global variable behind +/// the cast is returned. fn find_vtable_behind_cast<'ll>(vtable: &'ll Value) -> &'ll Value { // The vtable is a global variable, which may be behind an addrspacecast. unsafe { @@ -1532,6 +1540,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( let Some(trait_ref) = trait_ref else { return }; + // Unwrap potential addrspacecast let vtable = find_vtable_behind_cast(vtable); let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); let trait_ref_self = cx.tcx.erase_regions(trait_ref_self); @@ -1606,6 +1615,7 @@ pub(crate) fn create_vtable_di_node<'ll, 'tcx>( return; } + // Unwrap potential addrspacecast let vtable = find_vtable_behind_cast(vtable); // When full debuginfo is enabled, we want to try and prevent vtables from being From 353d916a0a0246b1bce331737e21806d77c7b857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 24 Jan 2025 13:59:05 +0100 Subject: [PATCH 22/71] Revert "Add `@bors rollup=never` to rustc-push PR body" --- src/doc/rustc-dev-guide/josh-sync/src/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs index 7ff5e018d2e..eff80b1091d 100644 --- a/src/doc/rustc-dev-guide/josh-sync/src/sync.rs +++ b/src/doc/rustc-dev-guide/josh-sync/src/sync.rs @@ -180,7 +180,7 @@ impl GitSync { ); println!( // Open PR with `subtree update` title to silence the `no-merges` triagebot check - " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=@bors+rollup=never%0Ar?+@ghost" + " https://github.com/{UPSTREAM_REPO}/compare/{github_user}:{branch}?quick_pull=1&title=Rustc+dev+guide+subtree+update&body=r?+@ghost" ); drop(josh); From 17a14b627eedef258b4e8144615fc2460c13648e Mon Sep 17 00:00:00 2001 From: Ada Alakbarova <58857108+ada4a@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:12:17 +0100 Subject: [PATCH 23/71] fix(solve/significant-changes): typo --- src/doc/rustc-dev-guide/src/solve/significant-changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/solve/significant-changes.md b/src/doc/rustc-dev-guide/src/solve/significant-changes.md index c5bb8a01b12..c82b5d46896 100644 --- a/src/doc/rustc-dev-guide/src/solve/significant-changes.md +++ b/src/doc/rustc-dev-guide/src/solve/significant-changes.md @@ -42,7 +42,7 @@ old implementation structurally relates the aliases instead. This enables the new solver to stall equality until it is able to normalize the related aliases. The behavior of the old solver is incomplete and relies on eager normalization -which replaces ambiguous aliases with inference variables. As this is not +which replaces ambiguous aliases with inference variables. As this is not possible for aliases containing bound variables, the old implementation does not handle aliases inside of binders correctly, e.g. [#102048]. See the chapter on [normalization] for more details. From 1392e074b7941af2f0b4bb400e1d0c75943cfe47 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Sat, 25 Jan 2025 18:21:58 +0100 Subject: [PATCH 24/71] CI: use key-restore for cache GH action It seems one can't overwrite a cache entry: ``` Failed to save: Unable to reserve cache with key linkcheck--0.8.1, another job may be creating this cache. More details: Cache already exists. Scope: refs/heads/master, Key: linkcheck--0.8.1, Version: 33f8fd511bed9c91c40778bc5c27cb58425caa894ab50f9c5705d83cb78660e0 Warning: Cache save failed. ``` A proper solution is to use `restore-keys`: https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 006bcce44b3..3f810e2fbcc 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -41,7 +41,9 @@ jobs: uses: actions/cache/restore@v4 with: path: book/linkcheck/cache.json - key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }} + key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ github.run_id }} + restore-keys: | + linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}-- - name: Install latest nightly Rust toolchain if: steps.mdbook-cache.outputs.cache-hit != 'true' @@ -66,7 +68,7 @@ jobs: uses: actions/cache/save@v4 with: path: book/linkcheck/cache.json - key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }} + key: linkcheck--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ github.run_id }} - name: Deploy to gh-pages if: github.event_name == 'push' From 40e051f1bfc41f3230e1a264425cd064ea66f500 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 25 Jan 2025 13:47:50 -0800 Subject: [PATCH 25/71] Update boring lines to sync with rustdoc --- .../src/early_late_parameters.md | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/early_late_parameters.md b/src/doc/rustc-dev-guide/src/early_late_parameters.md index 6d13655294d..28026b0af27 100644 --- a/src/doc/rustc-dev-guide/src/early_late_parameters.md +++ b/src/doc/rustc-dev-guide/src/early_late_parameters.md @@ -126,8 +126,8 @@ In this example we call `foo`'s function item type twice, each time with a borro If the lifetime parameter on `foo` was late bound this would be able to compile as each caller could provide a different lifetime argument for its borrow. See the following example which demonstrates this using the `bar` function defined above: ```rust -#fn foo<'a: 'a>(b: &'a String) -> &'a String { b } -#fn bar<'a>(b: &'a String) -> &'a String { b } +# fn foo<'a: 'a>(b: &'a String) -> &'a String { b } +# fn bar<'a>(b: &'a String) -> &'a String { b } // Early bound parameters are instantiated here, however as `'a` is // late bound it is not provided here. @@ -220,24 +220,24 @@ Then, for the first case, we can call each function with a single lifetime argum ```rust #![deny(late_bound_lifetime_arguments)] -#fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} # -#struct Foo; +# struct Foo; # -#trait Trait: Sized { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); -#} +# trait Trait: Sized { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); +# } # -#impl Trait for Foo { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Trait for Foo { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # -#impl Foo { -# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Foo { +# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # // Specifying as many arguments as there are early // bound parameters is always a future compat warning @@ -251,24 +251,24 @@ free_function::<'static>(&(), &()); For the second case we call each function with more lifetime arguments than there are lifetime parameters (be it early or late bound) and note that method calls result in a FCW as opposed to the free/associated functions which result in a hard error: ```rust -#fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# fn free_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} # -#struct Foo; +# struct Foo; # -#trait Trait: Sized { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); -#} +# trait Trait: Sized { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()); +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()); +# } # -#impl Trait for Foo { -# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Trait for Foo { +# fn trait_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn trait_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # -#impl Foo { -# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} -# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} -#} +# impl Foo { +# fn inherent_method<'a: 'a, 'b>(self, _: &'a (), _: &'b ()) {} +# fn inherent_function<'a: 'a, 'b>(_: &'a (), _: &'b ()) {} +# } # // Specifying more arguments than there are early // bound parameters is a future compat warning when @@ -421,4 +421,4 @@ impl<'a> Fn<()> for FooFnItem<'a> { type Output = &'a String; /* fn call(...) -> ... { ... } */ } -``` \ No newline at end of file +``` From 20818c47a59cb5fe617c5653a953d71c30def1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 26 Jan 2025 02:42:09 +0100 Subject: [PATCH 26/71] Remove accidental leading empty line in code block --- src/doc/rustc-dev-guide/src/early_late_parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/early_late_parameters.md b/src/doc/rustc-dev-guide/src/early_late_parameters.md index 28026b0af27..3b2a5e8a155 100644 --- a/src/doc/rustc-dev-guide/src/early_late_parameters.md +++ b/src/doc/rustc-dev-guide/src/early_late_parameters.md @@ -128,7 +128,7 @@ If the lifetime parameter on `foo` was late bound this would be able to compile ```rust # fn foo<'a: 'a>(b: &'a String) -> &'a String { b } # fn bar<'a>(b: &'a String) -> &'a String { b } - +# // Early bound parameters are instantiated here, however as `'a` is // late bound it is not provided here. let b = bar; From 5210a8d1e9789ad961b8464958fee3e804552a7e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 26 Jan 2025 12:08:48 -0800 Subject: [PATCH 27/71] Correct information on dylib compression Compression of dylibs was removed in https://github.com/rust-lang/rust/pull/113695 (and decompression removed in https://github.com/rust-lang/rust/pull/132402). --- src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md index b0823b9a5ee..556b3fdf8f8 100644 --- a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md +++ b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md @@ -42,7 +42,7 @@ format is specific to `rustc`, and may change over time. This file contains: ### dylib A `dylib` is a platform-specific shared library. It includes the `rustc` -[metadata] in a special link section called `.rustc` in a compressed format. +[metadata] in a special link section called `.rustc`. ### rmeta From 2412289fc9ae0e8903d1c3cca8ef0aaf84eae307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 27 Jan 2025 23:34:36 +0100 Subject: [PATCH 28/71] Fix rustc-pull CI's bash commands --- src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml index 87a3ee2e78f..615927d55e5 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml @@ -50,10 +50,10 @@ jobs: RESULT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | length' --json title` if [[ "$RESULT" -eq 0 ]]; then echo "Creating new pull request" - PR_URL=gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.' + PR_URL=`gh pr create -B master --title 'Rustc pull update' --body 'Latest update from rustc.'` echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT else - PR_URL=gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title + PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT fi env: From be7d6e3d5e34641f99f4a77d143beefbf243a934 Mon Sep 17 00:00:00 2001 From: dianne Date: Tue, 21 Jan 2025 08:17:59 -0800 Subject: [PATCH 29/71] add work-in-progress unstable book chapters These are very bare-bones, only intended to provide some documentation of what these feature gates are and aren't yet implementing. --- .../ref-pat-eat-one-layer-2024-structural.md | 19 +++++++++++++++++++ .../ref-pat-eat-one-layer-2024.md | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md create mode 100644 src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md 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 new file mode 100644 index 00000000000..bc587686111 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md @@ -0,0 +1,19 @@ +# `ref_pat_eat_one_layer_2024_structural` + +The tracking issue for this feature is: [#123076] + +[#123076]: https://github.com/rust-lang/rust/issues/123076 + +--- + +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 alternative experimental match ergonomics, see the feature +[`ref_pat_eat_one_layer_2024`](./ref-pat-eat-one-layer-2024.md). + +[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 new file mode 100644 index 00000000000..43de1849a5e --- /dev/null +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md @@ -0,0 +1,19 @@ +# `ref_pat_eat_one_layer_2024` + +The tracking issue for this feature is: [#123076] + +[#123076]: https://github.com/rust-lang/rust/issues/123076 + +--- + +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 alternative experimental match ergonomics, see the feature +[`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md). + +[Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false From d63796f69a977f1ab914004c70169a80ef0d8520 Mon Sep 17 00:00:00 2001 From: Joren-vanGoethem <55790052+Joren-vanGoethem@users.noreply.github.com> Date: Tue, 28 Jan 2025 07:43:16 +0100 Subject: [PATCH 30/71] Update about-this-guide.md --- src/doc/rustc-dev-guide/src/about-this-guide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index 793bfa9e66e..781a5c51bf7 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -72,7 +72,6 @@ You might also find the following sites useful: - The [Rust reference][rr], even though it doesn't specifically talk about Rust's internals, is a great resource nonetheless - Although out of date, [Tom Lee's great blog article][tlgba] is very helpful -- [rustaceans.org][ro] is helpful, but mostly dedicated to IRC - The [Rust Compiler Testing Docs][rctd] - For [@bors], [this cheat sheet][cheatsheet] is helpful - Google is always helpful when programming. From 62102ee041d0681e507e16c6d17ff5798b3a9d9f Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 28 Jan 2025 11:57:04 +0000 Subject: [PATCH 31/71] Preparing for merge from rustc --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 9693bfd63e8..183d26b2938 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -ecda83b30f0f68cf5692855dddc0bc38ee8863fc +66d6064f9eb888018775e08f84747ee6f39ba28e From 5df51930f926735f2ec48433e95502c3b214cdf8 Mon Sep 17 00:00:00 2001 From: Alisa Sireneva Date: Tue, 28 Jan 2025 19:02:15 +0300 Subject: [PATCH 32/71] Fix tests/codegen/float/f128 --- src/tools/compiletest/src/directive-list.rs | 1 + tests/codegen/float/f128.rs | 31 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index acdb3cbdd45..71496444660 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -177,6 +177,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-bpf", "only-cdb", "only-dist", + "only-emscripten", "only-gnu", "only-i686-pc-windows-gnu", "only-i686-pc-windows-msvc", diff --git a/tests/codegen/float/f128.rs b/tests/codegen/float/f128.rs index 514d35433e1..562a8e6c9e9 100644 --- a/tests/codegen/float/f128.rs +++ b/tests/codegen/float/f128.rs @@ -1,11 +1,15 @@ // 32-bit x86 returns float types differently to avoid the x87 stack. // 32-bit systems will return 128bit values using a return area pointer. -//@ revisions: x86 bit32 bit64 +// Emscripten aligns f128 to 8 bytes, not 16. +//@ revisions: x86 bit32 bit64 emscripten //@[x86] only-x86 //@[bit32] ignore-x86 +//@[bit32] ignore-emscripten //@[bit32] only-32bit //@[bit64] ignore-x86 +//@[bit64] ignore-emscripten //@[bit64] only-64bit +//@[emscripten] only-emscripten // Verify that our intrinsics generate the correct LLVM calls for f128 @@ -59,6 +63,7 @@ pub fn f128_le(a: f128, b: f128) -> bool { // x86-LABEL: void @f128_neg({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_neg({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_neg( +// emscripten-LABEL: void @f128_neg({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_neg(a: f128) -> f128 { // CHECK: fneg fp128 @@ -68,6 +73,7 @@ pub fn f128_neg(a: f128) -> f128 { // x86-LABEL: void @f128_add({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_add({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_add( +// emscripten-LABEL: void @f128_add({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_add(a: f128, b: f128) -> f128 { // CHECK: fadd fp128 %{{.+}}, %{{.+}} @@ -77,6 +83,7 @@ pub fn f128_add(a: f128, b: f128) -> f128 { // x86-LABEL: void @f128_sub({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_sub({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_sub( +// emscripten-LABEL: void @f128_sub({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_sub(a: f128, b: f128) -> f128 { // CHECK: fsub fp128 %{{.+}}, %{{.+}} @@ -86,6 +93,7 @@ pub fn f128_sub(a: f128, b: f128) -> f128 { // x86-LABEL: void @f128_mul({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_mul({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_mul( +// emscripten-LABEL: void @f128_mul({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_mul(a: f128, b: f128) -> f128 { // CHECK: fmul fp128 %{{.+}}, %{{.+}} @@ -95,6 +103,7 @@ pub fn f128_mul(a: f128, b: f128) -> f128 { // x86-LABEL: void @f128_div({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_div({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_div( +// emscripten-LABEL: void @f128_div({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_div(a: f128, b: f128) -> f128 { // CHECK: fdiv fp128 %{{.+}}, %{{.+}} @@ -104,6 +113,7 @@ pub fn f128_div(a: f128, b: f128) -> f128 { // x86-LABEL: void @f128_rem({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_rem({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_rem( +// emscripten-LABEL: void @f128_rem({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_rem(a: f128, b: f128) -> f128 { // CHECK: frem fp128 %{{.+}}, %{{.+}} @@ -164,6 +174,7 @@ pub fn f128_as_f16(a: f128) -> f16 { // x86-LABEL: i32 @f128_as_f32( // bit32-LABEL: float @f128_as_f32( // bit64-LABEL: float @f128_as_f32( +// emscripten-LABEL: float @f128_as_f32( #[no_mangle] pub fn f128_as_f32(a: f128) -> f32 { // CHECK: fptrunc fp128 %{{.+}} to float @@ -173,6 +184,7 @@ pub fn f128_as_f32(a: f128) -> f32 { // x86-LABEL: void @f128_as_f64( // bit32-LABEL: double @f128_as_f64( // bit64-LABEL: double @f128_as_f64( +// emscripten-LABEL: double @f128_as_f64( #[no_mangle] pub fn f128_as_f64(a: f128) -> f64 { // CHECK: fptrunc fp128 %{{.+}} to double @@ -182,17 +194,20 @@ pub fn f128_as_f64(a: f128) -> f64 { // x86-LABEL: void @f128_as_self({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_as_self({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_as_self( +// emscripten-LABEL: void @f128_as_self({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_as_self(a: f128) -> f128 { // x86: store fp128 %a, ptr %_0, align 16 // bit32: store fp128 %a, ptr %_0, align 16 // bit64: ret fp128 %{{.+}} + // emscripten: store fp128 %a, ptr %_0, align 8 a as f128 } // x86-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f16_as_f128( +// emscripten-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn f16_as_f128(a: f16) -> f128 { // CHECK: fpext half %{{.+}} to fp128 @@ -202,6 +217,7 @@ pub fn f16_as_f128(a: f16) -> f128 { // x86-LABEL: void @f32_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f32_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f32_as_f128( +// emscripten-LABEL: void @f32_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn f32_as_f128(a: f32) -> f128 { // CHECK: fpext float %{{.+}} to fp128 @@ -211,6 +227,7 @@ pub fn f32_as_f128(a: f32) -> f128 { // x86-LABEL: void @f64_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f64_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f64_as_f128( +// emscripten-LABEL: void @f64_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn f64_as_f128(a: f64) -> f128 { // CHECK: fpext double %{{.+}} to fp128 @@ -249,6 +266,7 @@ pub fn f128_as_u64(a: f128) -> u64 { // x86-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) // bit64-LABEL: i128 @f128_as_u128( +// emscripten-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_as_u128(a: f128) -> u128 { // CHECK: call i128 @llvm.fptoui.sat.i128.f128(fp128 %{{.+}}) @@ -285,6 +303,7 @@ pub fn f128_as_i64(a: f128) -> i64 { // x86-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) // bit64-LABEL: i128 @f128_as_i128( +// emscripten-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) #[no_mangle] pub fn f128_as_i128(a: f128) -> i128 { // CHECK: call i128 @llvm.fptosi.sat.i128.f128(fp128 %{{.+}}) @@ -296,6 +315,7 @@ pub fn f128_as_i128(a: f128) -> i128 { // x86-LABEL: void @u8_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u8_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u8_as_f128( +// emscripten-LABEL: void @u8_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn u8_as_f128(a: u8) -> f128 { // CHECK: uitofp i8 %{{.+}} to fp128 @@ -305,6 +325,7 @@ pub fn u8_as_f128(a: u8) -> f128 { // x86-LABEL: void @u16_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u16_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u16_as_f128( +// emscripten-LABEL: void @u16_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn u16_as_f128(a: u16) -> f128 { // CHECK: uitofp i16 %{{.+}} to fp128 @@ -314,6 +335,7 @@ pub fn u16_as_f128(a: u16) -> f128 { // x86-LABEL: void @u32_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u32_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u32_as_f128( +// emscripten-LABEL: void @u32_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn u32_as_f128(a: u32) -> f128 { // CHECK: uitofp i32 %{{.+}} to fp128 @@ -323,6 +345,7 @@ pub fn u32_as_f128(a: u32) -> f128 { // x86-LABEL: void @u64_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u64_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u64_as_f128( +// emscripten-LABEL: void @u64_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn u64_as_f128(a: u64) -> f128 { // CHECK: uitofp i64 %{{.+}} to fp128 @@ -332,6 +355,7 @@ pub fn u64_as_f128(a: u64) -> f128 { // x86-LABEL: void @u128_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u128_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u128_as_f128( +// emscripten-LABEL: void @u128_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn u128_as_f128(a: u128) -> f128 { // CHECK: uitofp i128 %{{.+}} to fp128 @@ -341,6 +365,7 @@ pub fn u128_as_f128(a: u128) -> f128 { // x86-LABEL: void @i8_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i8_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i8_as_f128( +// emscripten-LABEL: void @i8_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn i8_as_f128(a: i8) -> f128 { // CHECK: sitofp i8 %{{.+}} to fp128 @@ -350,6 +375,7 @@ pub fn i8_as_f128(a: i8) -> f128 { // x86-LABEL: void @i16_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i16_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i16_as_f128( +// emscripten-LABEL: void @i16_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn i16_as_f128(a: i16) -> f128 { // CHECK: sitofp i16 %{{.+}} to fp128 @@ -359,6 +385,7 @@ pub fn i16_as_f128(a: i16) -> f128 { // x86-LABEL: void @i32_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i32_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i32_as_f128( +// emscripten-LABEL: void @i32_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn i32_as_f128(a: i32) -> f128 { // CHECK: sitofp i32 %{{.+}} to fp128 @@ -368,6 +395,7 @@ pub fn i32_as_f128(a: i32) -> f128 { // x86-LABEL: void @i64_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i64_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i64_as_f128( +// emscripten-LABEL: void @i64_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn i64_as_f128(a: i64) -> f128 { // CHECK: sitofp i64 %{{.+}} to fp128 @@ -377,6 +405,7 @@ pub fn i64_as_f128(a: i64) -> f128 { // x86-LABEL: void @i128_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i128_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i128_as_f128( +// emscripten-LABEL: void @i128_as_f128({{.*}}sret([16 x i8]) #[no_mangle] pub fn i128_as_f128(a: i128) -> f128 { // CHECK: sitofp i128 %{{.+}} to fp128 From efaeedef59e4f213806898cdedb2220016d193c0 Mon Sep 17 00:00:00 2001 From: Alisa Sireneva Date: Tue, 28 Jan 2025 19:03:26 +0300 Subject: [PATCH 33/71] Fix tests/codegen/wasm_exceptions --- tests/codegen/wasm_exceptions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs index 719499dd8ea..07b8ae6e9d7 100644 --- a/tests/codegen/wasm_exceptions.rs +++ b/tests/codegen/wasm_exceptions.rs @@ -1,5 +1,5 @@ //@ only-wasm32 -//@ compile-flags: -C panic=unwind +//@ compile-flags: -C panic=unwind -Z emscripten-wasm-eh #![crate_type = "lib"] #![feature(core_intrinsics)] From 644e527c17a1b53e60a346cce7b6b32d97b9d10d Mon Sep 17 00:00:00 2001 From: Alisa Sireneva Date: Tue, 28 Jan 2025 19:07:12 +0300 Subject: [PATCH 34/71] Fix tests/ui/privacy/sysroot-private --- tests/ui/privacy/sysroot-private.default.stderr | 8 ++++---- tests/ui/privacy/sysroot-private.rs | 1 + .../privacy/sysroot-private.rustc_private_enabled.stderr | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/ui/privacy/sysroot-private.default.stderr b/tests/ui/privacy/sysroot-private.default.stderr index 845d4558d13..fef88d107e6 100644 --- a/tests/ui/privacy/sysroot-private.default.stderr +++ b/tests/ui/privacy/sysroot-private.default.stderr @@ -1,11 +1,11 @@ error[E0405]: cannot find trait `Equivalent` in this scope - --> $DIR/sysroot-private.rs:26:18 + --> $DIR/sysroot-private.rs:27:18 | LL | trait Trait2: Equivalent {} | ^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `K` in this scope - --> $DIR/sysroot-private.rs:31:35 + --> $DIR/sysroot-private.rs:32:35 | LL | fn trait_member(val: &T, key: &K) -> bool { | - ^ @@ -22,13 +22,13 @@ LL | fn trait_member(val: &T, key: &K) -> bool { | +++ error[E0220]: associated type `ExpressionStack` not found for `Trait` - --> $DIR/sysroot-private.rs:21:31 + --> $DIR/sysroot-private.rs:22:31 | LL | type AssociatedTy = dyn Trait; | ^^^^^^^^^^^^^^^ help: `Trait` has the following associated type: `Bar` error[E0425]: cannot find function `memchr2` in this scope - --> $DIR/sysroot-private.rs:39:5 + --> $DIR/sysroot-private.rs:40:5 | LL | memchr2(b'a', b'b', buf) | ^^^^^^^ not found in this scope diff --git a/tests/ui/privacy/sysroot-private.rs b/tests/ui/privacy/sysroot-private.rs index 67ab67c7f5c..86818574592 100644 --- a/tests/ui/privacy/sysroot-private.rs +++ b/tests/ui/privacy/sysroot-private.rs @@ -7,6 +7,7 @@ //! of `std`'s dependencies, but may not be robust against dependency upgrades/changes. //@ only-unix Windows sysroots seem to not expose this dependency +//@ ignore-emscripten neither does Emscripten //@ revisions: default rustc_private_enabled // Enabling `rustc_private` should `std`'s dependencies accessible, so they should show up diff --git a/tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr b/tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr index 98e6922428a..4b54b59714a 100644 --- a/tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr +++ b/tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr @@ -1,11 +1,11 @@ error[E0405]: cannot find trait `Equivalent` in this scope - --> $DIR/sysroot-private.rs:26:18 + --> $DIR/sysroot-private.rs:27:18 | LL | trait Trait2: Equivalent {} | ^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `K` in this scope - --> $DIR/sysroot-private.rs:31:35 + --> $DIR/sysroot-private.rs:32:35 | LL | fn trait_member(val: &T, key: &K) -> bool { | - ^ @@ -22,13 +22,13 @@ LL | fn trait_member(val: &T, key: &K) -> bool { | +++ error[E0220]: associated type `ExpressionStack` not found for `Trait` - --> $DIR/sysroot-private.rs:21:31 + --> $DIR/sysroot-private.rs:22:31 | LL | type AssociatedTy = dyn Trait; | ^^^^^^^^^^^^^^^ there is an associated type `ExpressionStack` in the trait `gimli::read::op::EvaluationStorage` error[E0425]: cannot find function `memchr2` in this scope - --> $DIR/sysroot-private.rs:39:5 + --> $DIR/sysroot-private.rs:40:5 | LL | memchr2(b'a', b'b', buf) | ^^^^^^^ not found in this scope From 5861aa21d9acfae6e83acb79081b81c7a7c4994f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Jan 2025 11:04:26 -0700 Subject: [PATCH 35/71] Add some extra pointers for rustdoc frontend devs --- src/doc/rustc-dev-guide/src/rustdoc.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md index 3867d248988..2a0e212f98e 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc.md +++ b/src/doc/rustc-dev-guide/src/rustdoc.md @@ -58,10 +58,13 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * If you want to copy those docs to a webserver, copy all of `build/host/doc`, since that's where the CSS, JS, fonts, and landing page are. + * For frontend debugging, disable the `rust.docs-minification` option in [`config.toml`]. * Use `./x test tests/rustdoc*` to run the tests using a stage1 rustdoc. * See [Rustdoc internals] for more information about tests. +[`config.toml`]: ./building/how-to-build-and-run.md + ## Code structure * All paths in this section are relative to `src/librustdoc` in the rust-lang/rust repository. @@ -77,6 +80,7 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where they're handled by the test runner of bootstrap and the supplementary script `src/etc/htmldocck.py`. +* Frontend CSS and JavaScript are stored in `html/static/`. ## Tests @@ -91,6 +95,11 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses puppeteer to run tests in a headless browser and check rendering and interactivity. +* Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc] + comments and an external d.ts file. The code itself is plain, valid JavaScript; we only + use tsc as a linter. + +[TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html ## Constraints From 2b8930c71c8040d338f99e1b1be6f1056edd6638 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Jan 2025 03:03:39 +0000 Subject: [PATCH 36/71] Consolidate OutlivesEnv construction with resolve_regions --- .../src/region_infer/opaque_types.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 5 +-- .../src/check/compare_impl_item.rs | 24 +++------- .../src/check/compare_impl_item/refine.rs | 8 +--- .../rustc_hir_analysis/src/check/dropck.rs | 3 +- compiler/rustc_hir_analysis/src/check/mod.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 21 +++++---- .../src/coherence/builtin.rs | 7 +-- .../src/impl_wf_check/min_specialization.rs | 8 +--- .../rustc_lint/src/impl_trait_overcaptures.rs | 2 +- compiler/rustc_trait_selection/src/regions.rs | 18 +++++++- .../src/traits/coherence.rs | 6 +-- .../src/traits/engine.rs | 16 ++++--- .../rustc_trait_selection/src/traits/misc.rs | 23 +--------- .../rustc_trait_selection/src/traits/mod.rs | 4 +- .../src/traits/outlives_bounds.rs | 45 ++++++++----------- 16 files changed, 75 insertions(+), 121 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 7c484327e31..1e7451a16af 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -439,7 +439,7 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds"); Default::default() }); - let implied_bounds = infcx.implied_bounds_tys(param_env, parent, &wf_tys); + let implied_bounds = infcx.implied_bounds_tys(parent, param_env, wf_tys); let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let mut seen = vec![tcx.lifetimes.re_static]; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b0a6922ff72..40049f96de4 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -27,7 +27,6 @@ use rustc_session::lint::builtin::UNINHABITED_STATIC; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits; -use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_type_ir::fold::TypeFoldable; use tracing::{debug, instrument}; use ty::TypingMode; @@ -417,9 +416,7 @@ fn check_opaque_meets_bounds<'tcx>( } let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, defining_use_anchor)?; - let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, &wf_tys); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?; + ocx.resolve_regions_and_report_errors(defining_use_anchor, param_env, wf_tys)?; if infcx.next_trait_solver() { Ok(()) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index d2ab98bae89..7332888c5f9 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -9,7 +9,6 @@ use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_e use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit}; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -24,7 +23,6 @@ use rustc_span::Span; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; -use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{ self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, }; @@ -416,11 +414,7 @@ fn compare_method_predicate_entailment<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. - let outlives_env = OutlivesEnvironment::with_bounds( - param_env, - infcx.implied_bounds_tys(param_env, impl_m_def_id, &wf_tys), - ); - let errors = infcx.resolve_regions(&outlives_env); + let errors = infcx.resolve_regions(impl_m_def_id, param_env, wf_tys); if !errors.is_empty() { return Err(infcx .tainted_by_errors() @@ -725,11 +719,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. - let outlives_env = OutlivesEnvironment::with_bounds( - param_env, - infcx.implied_bounds_tys(param_env, impl_m_def_id, &wf_tys), - ); - ocx.resolve_regions_and_report_errors(impl_m_def_id, &outlives_env)?; + ocx.resolve_regions_and_report_errors(impl_m_def_id, param_env, wf_tys)?; let mut remapped_types = DefIdMap::default(); for (def_id, (ty, args)) in collected_types { @@ -1883,8 +1873,7 @@ fn compare_const_predicate_entailment<'tcx>( return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); } - let outlives_env = OutlivesEnvironment::new(param_env); - ocx.resolve_regions_and_report_errors(impl_ct_def_id, &outlives_env) + ocx.resolve_regions_and_report_errors(impl_ct_def_id, param_env, []) } #[instrument(level = "debug", skip(tcx))] @@ -2017,8 +2006,7 @@ fn compare_type_predicate_entailment<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. - let outlives_env = OutlivesEnvironment::new(param_env); - ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env) + ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, []) } /// Validate that `ProjectionCandidate`s created for this associated type will @@ -2147,9 +2135,7 @@ pub(super) fn check_type_bounds<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. - let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, &assumed_wf_types); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - ocx.resolve_regions_and_report_errors(impl_ty_def_id, &outlives_env) + ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, assumed_wf_types) } struct ReplaceTy<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 2b14594ea1b..494e9560c81 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE}; use rustc_middle::span_bug; use rustc_middle::traits::ObligationCause; @@ -13,7 +12,6 @@ use rustc_middle::ty::{ }; use rustc_span::Span; use rustc_trait_selection::regions::InferCtxtRegionExt; -use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt; use rustc_trait_selection::traits::{ObligationCtxt, elaborate, normalize_param_env_or_error}; /// Check that an implementation does not refine an RPITIT from a trait method signature. @@ -170,11 +168,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); return; } - let outlives_env = OutlivesEnvironment::with_bounds( - param_env, - infcx.implied_bounds_tys(param_env, impl_m.def_id.expect_local(), &implied_wf_types), - ); - let errors = infcx.resolve_regions(&outlives_env); + let errors = infcx.resolve_regions(impl_m.def_id.expect_local(), param_env, implied_wf_types); if !errors.is_empty() { tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (regions)"); return; diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 1c9bbe627fb..0876bb82848 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::util::CheckRegions; @@ -192,7 +191,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( return Err(guar.unwrap()); } - let errors = ocx.infcx.resolve_regions(&OutlivesEnvironment::new(adt_env)); + let errors = ocx.infcx.resolve_regions(adt_def_id, adt_env, []); if !errors.is_empty() { let mut guar = None; for error in errors { diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 69b4aa47eba..c6ec2720960 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -80,7 +80,6 @@ use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::DenseBitSet; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, TyCtxtInferExt as _}; use rustc_infer::traits::ObligationCause; use rustc_middle::query::Providers; @@ -655,8 +654,7 @@ pub fn check_function_signature<'tcx>( } } - let outlives_env = OutlivesEnvironment::new(param_env); - if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, &outlives_env) { + if let Err(e) = ocx.resolve_regions_and_report_errors(local_id, param_env, []) { return Err(e); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index cd19993f937..5023a09e2f3 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -128,13 +128,17 @@ where let infcx_compat = infcx.fork(); // We specifically want to call the non-compat version of `implied_bounds_tys`; we do this always. - let implied_bounds = - infcx.implied_bounds_tys_compat(param_env, body_def_id, &assumed_wf_types, false); + let implied_bounds = infcx.implied_bounds_tys_compat( + body_def_id, + param_env, + assumed_wf_types.iter().copied(), + false, + ); let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); lint_redundant_lifetimes(tcx, body_def_id, &outlives_env); - let errors = infcx.resolve_regions(&outlives_env); + let errors = infcx.resolve_regions_with_outlives_env(&outlives_env); if errors.is_empty() { return Ok(()); } @@ -173,9 +177,9 @@ where // just obscures what we mean here anyways. Let's just be explicit. if is_bevy && !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat { let implied_bounds = - infcx_compat.implied_bounds_tys_compat(param_env, body_def_id, &assumed_wf_types, true); + infcx_compat.implied_bounds_tys_compat(body_def_id, param_env, assumed_wf_types, true); let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - let errors_compat = infcx_compat.resolve_regions(&outlives_env); + let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env); if errors_compat.is_empty() { Ok(()) } else { @@ -769,12 +773,7 @@ fn test_region_obligations<'tcx>( add_constraints(&infcx); - let outlives_environment = OutlivesEnvironment::with_bounds( - param_env, - infcx.implied_bounds_tys(param_env, id, wf_tys), - ); - - let errors = infcx.resolve_regions(&outlives_environment); + let errors = infcx.resolve_regions(id, param_env, wf_tys.iter().copied()); debug!(?errors, "errors"); // If we were able to prove that the type outlives the region without diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 27a7c2ea530..6bbd76633da 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -10,7 +10,6 @@ use rustc_hir as hir; use rustc_hir::ItemKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; @@ -346,8 +345,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() } // Finally, resolve all regions. - let outlives_env = OutlivesEnvironment::new(param_env); - res = res.and(ocx.resolve_regions_and_report_errors(impl_did, &outlives_env)); + res = res.and(ocx.resolve_regions_and_report_errors(impl_did, param_env, [])); } res } @@ -564,8 +562,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( } // Finally, resolve all regions. - let outlives_env = OutlivesEnvironment::new(param_env); - let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env); + let _ = ocx.resolve_regions_and_report_errors(impl_did, param_env, []); Ok(CoerceUnsizedInfo { custom_kind: kind }) } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index ee55e1bc21a..32694d5f4bc 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -68,7 +68,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::specialization_graph::Node; use rustc_middle::ty::trait_def::TraitSpecializationKind; @@ -77,7 +76,6 @@ use rustc_middle::ty::{ }; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; -use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCtxt, translate_args_with_cause, wf}; use tracing::{debug, instrument}; @@ -176,7 +174,6 @@ fn get_impl_args( let ocx = ObligationCtxt::new_with_diagnostics(infcx); let param_env = tcx.param_env(impl1_def_id); let impl1_span = tcx.def_span(impl1_def_id); - let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?; let impl1_args = GenericArgs::identity_for_item(tcx, impl1_def_id); let impl2_args = translate_args_with_cause( @@ -194,9 +191,8 @@ fn get_impl_args( return Err(guar); } - let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, &assumed_wf_types); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env); + let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl1_def_id)?; + let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, param_env, assumed_wf_types); let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else { let span = tcx.def_span(impl1_def_id); let guar = tcx.dcx().emit_err(GenericArgsOnOverriddenImpl { span }); diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 44f86535527..d6546066d86 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -191,7 +191,7 @@ fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) { let ocx = ObligationCtxt::new(&infcx); let assumed_wf_tys = ocx.assumed_wf_types(param_env, parent_def_id).unwrap_or_default(); let implied_bounds = - infcx.implied_bounds_tys_compat(param_env, parent_def_id, &assumed_wf_tys, false); + infcx.implied_bounds_tys_compat(parent_def_id, param_env, assumed_wf_tys, false); OutlivesEnvironment::with_bounds(param_env, implied_bounds) }), }); diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 863b6e293ff..1bae6c80cfa 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -1,10 +1,13 @@ +use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferCtxt, RegionResolutionError}; use rustc_macros::extension; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; +use rustc_middle::ty::{self, Ty}; use crate::traits::ScrubbedTraitError; +use crate::traits::outlives_bounds::InferCtxtExt; #[extension(pub trait InferCtxtRegionExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { @@ -15,10 +18,23 @@ impl<'tcx> InferCtxt<'tcx> { /// Prefer this method over `resolve_regions_with_normalize`, unless you are /// doing something specific for normalization. fn resolve_regions( + &self, + body_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + assumed_wf_tys: impl IntoIterator>, + ) -> Vec> { + self.resolve_regions_with_outlives_env(&OutlivesEnvironment::with_bounds( + param_env, + self.implied_bounds_tys(body_id, param_env, assumed_wf_tys), + )) + } + + /// Don't call this directly unless you know what you're doing. + fn resolve_regions_with_outlives_env( &self, outlives_env: &OutlivesEnvironment<'tcx>, ) -> Vec> { - self.resolve_regions_with_normalize(outlives_env, |ty, origin| { + self.resolve_regions_with_normalize(&outlives_env, |ty, origin| { let ty = self.resolve_vars_if_possible(ty); if self.next_trait_solver() { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 50d47d20e1a..7ee9eb45309 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -9,7 +9,7 @@ use std::fmt::Debug; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::PredicateObligations; use rustc_middle::bug; @@ -27,7 +27,6 @@ use tracing::{debug, instrument, warn}; use super::ObligationCtxt; use crate::error_reporting::traits::suggest_new_overflow_limit; use crate::infer::InferOk; -use crate::infer::outlives::env::OutlivesEnvironment; use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor}; use crate::solve::{SolverDelegate, deeply_normalize_for_diagnostics, inspect}; use crate::traits::query::evaluate_obligation::InferCtxtExt; @@ -596,8 +595,7 @@ fn try_prove_negated_where_clause<'tcx>( // FIXME: We could use the assumed_wf_types from both impls, I think, // if that wasn't implemented just for LocalDefId, and we'd need to do // the normalization ourselves since this is totally fallible... - let outlives_env = OutlivesEnvironment::new(param_env); - let errors = ocx.resolve_regions(&outlives_env); + let errors = ocx.resolve_regions(CRATE_DEF_ID, param_env, []); if !errors.is_empty() { return false; } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 4a3983fca31..9f3178f8879 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -8,7 +8,6 @@ use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::{ Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse, }; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace}; use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; @@ -217,14 +216,15 @@ where /// will result in region constraints getting ignored. pub fn resolve_regions_and_report_errors( self, - generic_param_scope: LocalDefId, - outlives_env: &OutlivesEnvironment<'tcx>, + body_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + assumed_wf_tys: impl IntoIterator>, ) -> Result<(), ErrorGuaranteed> { - let errors = self.infcx.resolve_regions(outlives_env); + let errors = self.infcx.resolve_regions(body_id, param_env, assumed_wf_tys); if errors.is_empty() { Ok(()) } else { - Err(self.infcx.err_ctxt().report_region_errors(generic_param_scope, &errors)) + Err(self.infcx.err_ctxt().report_region_errors(body_id, &errors)) } } @@ -235,9 +235,11 @@ where #[must_use] pub fn resolve_regions( self, - outlives_env: &OutlivesEnvironment<'tcx>, + body_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + assumed_wf_tys: impl IntoIterator>, ) -> Vec> { - self.infcx.resolve_regions(outlives_env) + self.infcx.resolve_regions(body_id, param_env, assumed_wf_tys) } } diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 7a67b943e94..79e178150de 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -4,13 +4,10 @@ use std::assert_matches::assert_matches; use hir::LangItem; use rustc_ast::Mutability; -use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; -use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; -use super::outlives_bounds::InferCtxtExt; use crate::regions::InferCtxtRegionExt; use crate::traits::{self, FulfillmentError, ObligationCause}; @@ -170,15 +167,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( } // Check regions assuming the self type of the impl is WF - let outlives_env = OutlivesEnvironment::with_bounds( - param_env, - infcx.implied_bounds_tys( - param_env, - parent_cause.body_id, - &FxIndexSet::from_iter([self_type]), - ), - ); - let errors = infcx.resolve_regions(&outlives_env); + let errors = infcx.resolve_regions(parent_cause.body_id, param_env, [self_type]); if !errors.is_empty() { infringing_inner_tys.push((inner_ty, InfringingFieldsReason::Regions(errors))); continue; @@ -261,15 +250,7 @@ pub fn all_fields_implement_trait<'tcx>( } // Check regions assuming the self type of the impl is WF - let outlives_env = OutlivesEnvironment::with_bounds( - param_env, - infcx.implied_bounds_tys( - param_env, - parent_cause.body_id, - &FxIndexSet::from_iter([self_type]), - ), - ); - let errors = infcx.resolve_regions(&outlives_env); + let errors = infcx.resolve_regions(parent_cause.body_id, param_env, [self_type]); if !errors.is_empty() { infringing.push((field, ty, InfringingFieldsReason::Regions(errors))); } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index fe5ad003a7e..6b5ebade6ae 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -290,12 +290,10 @@ fn do_normalize_predicates<'tcx>( // We can use the `elaborated_env` here; the region code only // cares about declarations like `'a: 'b`. - let outlives_env = OutlivesEnvironment::new(elaborated_env); - // FIXME: It's very weird that we ignore region obligations but apparently // still need to use `resolve_regions` as we need the resolved regions in // the normalized predicates. - let errors = infcx.resolve_regions(&outlives_env); + let errors = infcx.resolve_regions(cause.body_id, elaborated_env, []); if !errors.is_empty() { tcx.dcx().span_delayed_bug( span, diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 23dabe32ff2..eecc499f384 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -1,4 +1,3 @@ -use rustc_data_structures::fx::FxIndexSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; @@ -12,9 +11,6 @@ use tracing::instrument; use crate::infer::InferCtxt; use crate::traits::{ObligationCause, ObligationCtxt}; -pub type BoundsCompat<'a, 'tcx: 'a> = impl Iterator> + 'a; -pub type Bounds<'a, 'tcx: 'a> = impl Iterator> + 'a; - /// Implied bounds are region relationships that we deduce /// automatically. The idea is that (e.g.) a caller must check that a /// function's argument types are well-formed immediately before @@ -110,36 +106,33 @@ fn implied_outlives_bounds<'a, 'tcx>( bounds } -#[extension(pub trait InferCtxtExt<'a, 'tcx>)] -impl<'a, 'tcx: 'a> InferCtxt<'tcx> { +#[extension(pub trait InferCtxtExt<'tcx>)] +impl<'tcx> InferCtxt<'tcx> { /// Do *NOT* call this directly. - fn implied_bounds_tys_compat( - &'a self, - param_env: ParamEnv<'tcx>, + fn implied_bounds_tys_compat>>( + &self, body_id: LocalDefId, - tys: &'a FxIndexSet>, + param_env: ParamEnv<'tcx>, + tys: Tys, compat: bool, - ) -> BoundsCompat<'a, 'tcx> { - tys.iter() - .flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, *ty, compat)) + ) -> impl Iterator> { + tys.into_iter() + .flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, ty, compat)) } /// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat` /// with `compat` set to `true`, otherwise `false`. fn implied_bounds_tys( - &'a self, - param_env: ParamEnv<'tcx>, + &self, body_id: LocalDefId, - tys: &'a FxIndexSet>, - ) -> Bounds<'a, 'tcx> { - tys.iter().flat_map(move |ty| { - implied_outlives_bounds( - self, - param_env, - body_id, - *ty, - !self.tcx.sess.opts.unstable_opts.no_implied_bounds_compat, - ) - }) + param_env: ParamEnv<'tcx>, + tys: impl IntoIterator>, + ) -> impl Iterator> { + self.implied_bounds_tys_compat( + body_id, + param_env, + tys, + !self.tcx.sess.opts.unstable_opts.no_implied_bounds_compat, + ) } } From 48b7e38c0607e856dbbb932e60ecc85e45a1427d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Jan 2025 04:26:32 +0000 Subject: [PATCH 37/71] Move outlives env computation into methods --- .../src/region_infer/opaque_types.rs | 16 +++---- .../rustc_hir_analysis/src/check/wfcheck.rs | 17 ++++--- .../rustc_infer/src/infer/outlives/env.rs | 6 --- .../rustc_lint/src/impl_trait_overcaptures.rs | 6 +-- compiler/rustc_trait_selection/src/regions.rs | 46 ++++++++++++++++++- .../src/traits/auto_trait.rs | 4 +- .../src/traits/outlives_bounds.rs | 21 ++------- .../src/traits/implied-bounds.md | 4 +- 8 files changed, 71 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 1e7451a16af..5440d451ec8 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,6 +1,8 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; +use rustc_hir::OpaqueTyOrigin; use rustc_hir::def_id::LocalDefId; +use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _}; use rustc_macros::extension; use rustc_middle::ty::fold::fold_regions; @@ -10,6 +12,7 @@ use rustc_middle::ty::{ TypingMode, }; use rustc_span::Span; +use rustc_trait_selection::regions::OutlivesEnvironmentBuildExt; use rustc_trait_selection::traits::ObligationCtxt; use tracing::{debug, instrument}; @@ -406,10 +409,6 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { } fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> { - use rustc_hir as hir; - use rustc_infer::infer::outlives::env::OutlivesEnvironment; - use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; - if let Some(&canonical_args) = self.canonical_args.get() { return canonical_args; } @@ -417,9 +416,9 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { let &Self { tcx, def_id, .. } = self; let origin = tcx.local_opaque_ty_origin(def_id); let parent = match origin { - hir::OpaqueTyOrigin::FnReturn { parent, .. } - | hir::OpaqueTyOrigin::AsyncFn { parent, .. } - | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent, + OpaqueTyOrigin::FnReturn { parent, .. } + | OpaqueTyOrigin::AsyncFn { parent, .. } + | OpaqueTyOrigin::TyAlias { parent, .. } => parent, }; let param_env = tcx.param_env(parent); let args = GenericArgs::identity_for_item(tcx, parent).extend_to( @@ -439,8 +438,7 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds"); Default::default() }); - let implied_bounds = infcx.implied_bounds_tys(parent, param_env, wf_tys); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + let outlives_env = OutlivesEnvironment::new(&infcx, parent, param_env, wf_tys); let mut seen = vec![tcx.lifetimes.re_static]; let canonical_args = fold_regions(tcx, args, |r1, _| { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5023a09e2f3..83bb8c0dfaf 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -25,11 +25,10 @@ use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::{DUMMY_SP, Ident, Span, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; -use rustc_trait_selection::regions::InferCtxtRegionExt; +use rustc_trait_selection::regions::{InferCtxtRegionExt, OutlivesEnvironmentBuildExt}; use rustc_trait_selection::traits::misc::{ ConstParamTyImplementationError, type_allowed_to_implement_const_param_ty, }; -use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt, @@ -128,13 +127,13 @@ where let infcx_compat = infcx.fork(); // We specifically want to call the non-compat version of `implied_bounds_tys`; we do this always. - let implied_bounds = infcx.implied_bounds_tys_compat( + let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat( + &infcx, body_def_id, param_env, assumed_wf_types.iter().copied(), false, ); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); lint_redundant_lifetimes(tcx, body_def_id, &outlives_env); @@ -176,9 +175,13 @@ where // but that does result in slightly more work when this option is set and // just obscures what we mean here anyways. Let's just be explicit. if is_bevy && !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat { - let implied_bounds = - infcx_compat.implied_bounds_tys_compat(body_def_id, param_env, assumed_wf_types, true); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat( + &infcx, + body_def_id, + param_env, + assumed_wf_types, + true, + ); let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env); if errors_compat.is_empty() { Ok(()) diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 9300fc574dc..f8ab0b53a00 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -59,12 +59,6 @@ pub struct OutlivesEnvironment<'tcx> { pub type RegionBoundPairs<'tcx> = FxIndexSet>>; impl<'tcx> OutlivesEnvironment<'tcx> { - /// Create a new `OutlivesEnvironment` without extra outlives bounds. - #[inline] - pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self { - Self::with_bounds(param_env, vec![]) - } - /// Create a new `OutlivesEnvironment` with extra outlives bounds. pub fn with_bounds( param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index d6546066d86..d251b4b7459 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -25,8 +25,8 @@ use rustc_span::{Span, Symbol}; use rustc_trait_selection::errors::{ AddPreciseCapturingForOvercapture, impl_trait_overcapture_suggestion, }; +use rustc_trait_selection::regions::OutlivesEnvironmentBuildExt; use rustc_trait_selection::traits::ObligationCtxt; -use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt; use crate::{LateContext, LateLintPass, fluent_generated as fluent}; @@ -190,9 +190,7 @@ fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) { let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); let ocx = ObligationCtxt::new(&infcx); let assumed_wf_tys = ocx.assumed_wf_types(param_env, parent_def_id).unwrap_or_default(); - let implied_bounds = - infcx.implied_bounds_tys_compat(parent_def_id, param_env, assumed_wf_tys, false); - OutlivesEnvironment::with_bounds(param_env, implied_bounds) + OutlivesEnvironment::new(&infcx, parent_def_id, param_env, assumed_wf_tys) }), }); } diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 1bae6c80cfa..fc9fa44b4c6 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -9,6 +9,46 @@ use rustc_middle::ty::{self, Ty}; use crate::traits::ScrubbedTraitError; use crate::traits::outlives_bounds::InferCtxtExt; +#[extension(pub trait OutlivesEnvironmentBuildExt<'tcx>)] +impl<'tcx> OutlivesEnvironment<'tcx> { + fn new( + infcx: &InferCtxt<'tcx>, + body_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + assumed_wf_tys: impl IntoIterator>, + ) -> Self { + Self::new_with_implied_bounds_compat( + infcx, + body_id, + param_env, + assumed_wf_tys, + !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat, + ) + } + + fn new_with_implied_bounds_compat( + infcx: &InferCtxt<'tcx>, + body_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + assumed_wf_tys: impl IntoIterator>, + implied_bounds_compat: bool, + ) -> Self { + // FIXME: This needs to be modified so that we normalize the known type + // outlives obligations then elaborate them into their region/type components. + // Otherwise, ` as Mirror>::Assoc: 'b` will not imply `'a: 'b` even + // if we can normalize `'a`. + OutlivesEnvironment::with_bounds( + param_env, + infcx.implied_bounds_tys_with_compat( + body_id, + param_env, + assumed_wf_tys, + implied_bounds_compat, + ), + ) + } +} + #[extension(pub trait InferCtxtRegionExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { /// Resolve regions, using the deep normalizer to normalize any type-outlives @@ -23,9 +63,11 @@ impl<'tcx> InferCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, ) -> Vec> { - self.resolve_regions_with_outlives_env(&OutlivesEnvironment::with_bounds( + self.resolve_regions_with_outlives_env(&OutlivesEnvironment::new( + self, + body_id, param_env, - self.implied_bounds_tys(body_id, param_env, assumed_wf_tys), + assumed_wf_tys, )) } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 9a53e8a5d51..1fca2f4da7e 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -6,6 +6,7 @@ use std::iter; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet, IndexEntry}; use rustc_data_structures::unord::UnordSet; +use rustc_hir::def_id::CRATE_DEF_ID; use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::ty::{Region, RegionVid}; use tracing::debug; @@ -13,6 +14,7 @@ use tracing::debug; use super::*; use crate::errors::UnableToConstructConstantValue; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; +use crate::regions::OutlivesEnvironmentBuildExt; use crate::traits::project::ProjectAndUnifyResult; // FIXME(twk): this is obviously not nice to duplicate like that @@ -158,7 +160,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { panic!("Unable to fulfill trait {trait_did:?} for '{ty:?}': {errors:?}"); } - let outlives_env = OutlivesEnvironment::new(full_env); + let outlives_env = OutlivesEnvironment::new(&infcx, CRATE_DEF_ID, full_env, []); let _ = infcx.process_registered_region_obligations(&outlives_env, |ty, _| Ok(ty)); let region_data = infcx.inner.borrow_mut().unwrap_region_constraints().data().clone(); diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index eecc499f384..18932695807 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -108,8 +108,9 @@ fn implied_outlives_bounds<'a, 'tcx>( #[extension(pub trait InferCtxtExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { - /// Do *NOT* call this directly. - fn implied_bounds_tys_compat>>( + /// Do *NOT* call this directly. You probably want to construct a `OutlivesEnvironment` + /// instead if you're interested in the implied bounds for a given signature. + fn implied_bounds_tys_with_compat>>( &self, body_id: LocalDefId, param_env: ParamEnv<'tcx>, @@ -119,20 +120,4 @@ impl<'tcx> InferCtxt<'tcx> { tys.into_iter() .flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, ty, compat)) } - - /// If `-Z no-implied-bounds-compat` is set, calls `implied_bounds_tys_compat` - /// with `compat` set to `true`, otherwise `false`. - fn implied_bounds_tys( - &self, - body_id: LocalDefId, - param_env: ParamEnv<'tcx>, - tys: impl IntoIterator>, - ) -> impl Iterator> { - self.implied_bounds_tys_compat( - body_id, - param_env, - tys, - !self.tcx.sess.opts.unstable_opts.no_implied_bounds_compat, - ) - } } diff --git a/src/doc/rustc-dev-guide/src/traits/implied-bounds.md b/src/doc/rustc-dev-guide/src/traits/implied-bounds.md index 63b09a43f47..05693dcd5a1 100644 --- a/src/doc/rustc-dev-guide/src/traits/implied-bounds.md +++ b/src/doc/rustc-dev-guide/src/traits/implied-bounds.md @@ -40,7 +40,7 @@ requirements of impls and functions as explicit predicates. ### using implicit implied bounds as assumptions These bounds are not added to the `ParamEnv` of the affected item itself. For lexical -region resolution they are added using [`fn OutlivesEnvironment::with_bounds`]. +region resolution they are added using [`fn OutlivesEnvironment::new`]. Similarly, during MIR borrowck we add them using [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]. @@ -55,7 +55,7 @@ The assumed outlives constraints for implicit bounds are computed using the MIR borrowck adds the outlives constraints for both the normalized and unnormalized types, lexical region resolution [only uses the unnormalized types][notnorm]. -[`fn OutlivesEnvironment::with_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_infer/src/infer/outlives/env.rs#L90-L97 +[`fn OutlivesEnvironment::new`]: TODO [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L316 [mir]: https://github.com/rust-lang/rust/blob/91cae1dcdcf1a31bd8a92e4a63793d65cfe289bb/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L258-L332 [`fn assumed_wf_types`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_ty_utils/src/implied_bounds.rs#L21 From 8e0909d98a8e467f79d80000fe57eee6417ac02e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Jan 2025 16:20:23 +0000 Subject: [PATCH 38/71] Move param env bound deep normalization to OutlivesEnvironment building --- .../rustc_infer/src/infer/outlives/env.rs | 38 ++++++++----------- .../src/infer/outlives/obligations.rs | 22 +---------- compiler/rustc_trait_selection/src/regions.rs | 22 ++++++++++- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index f8ab0b53a00..e924c974a02 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -31,26 +31,14 @@ use crate::traits::query::OutlivesBound; pub struct OutlivesEnvironment<'tcx> { pub param_env: ty::ParamEnv<'tcx>, free_region_map: FreeRegionMap<'tcx>, - - // Contains the implied region bounds in scope for our current body. - // - // Example: - // - // ``` - // fn foo<'a, 'b, T>(x: &'a T, y: &'b ()) { - // bar(x, y, |y: &'b T| { .. } // body B1) - // } // body B0 - // ``` - // - // Here, when checking the body B0, the list would be `[T: 'a]`, because we - // infer that `T` must outlive `'a` from the implied bounds on the - // fn declaration. - // - // For the body B1 however, the list would be `[T: 'a, T: 'b]`, because we - // also can see that -- within the closure body! -- `T` must - // outlive `'b`. This is not necessarily true outside the closure - // body, since the closure may never be called. + /// FIXME: Your first reaction may be that this is a bit strange. `RegionBoundPairs` + /// does not contain lifetimes, which are instead in the `FreeRegionMap`, and other + /// known type outlives are stored in the `known_type_outlives` set. So why do we + /// have these at all? It turns out that removing these and using `known_type_outlives` + /// everywhere is just enough of a perf regression to matter. This can/should be + /// optimized in the future, though. region_bound_pairs: RegionBoundPairs<'tcx>, + known_type_outlives: Vec>, } /// "Region-bound pairs" tracks outlives relations that are known to @@ -59,9 +47,10 @@ pub struct OutlivesEnvironment<'tcx> { pub type RegionBoundPairs<'tcx> = FxIndexSet>>; impl<'tcx> OutlivesEnvironment<'tcx> { - /// Create a new `OutlivesEnvironment` with extra outlives bounds. - pub fn with_bounds( + /// Create a new `OutlivesEnvironment` from normalized outlives bounds. + pub fn from_normalized_bounds( param_env: ty::ParamEnv<'tcx>, + known_type_outlives: Vec>, extra_bounds: impl IntoIterator>, ) -> Self { let mut region_relation = TransitiveRelationBuilder::default(); @@ -96,18 +85,21 @@ impl<'tcx> OutlivesEnvironment<'tcx> { OutlivesEnvironment { param_env, + known_type_outlives, free_region_map: FreeRegionMap { relation: region_relation.freeze() }, region_bound_pairs, } } - /// Borrows current value of the `free_region_map`. pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> { &self.free_region_map } - /// Borrows current `region_bound_pairs`. pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> { &self.region_bound_pairs } + + pub fn known_type_outlives(&self) -> &[ty::PolyTypeOutlivesPredicate<'tcx>] { + &self.known_type_outlives + } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 0383c81f2af..84e51b18dc5 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -67,7 +67,6 @@ use rustc_middle::ty::{ self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesPredicate, Region, Ty, TyCtxt, TypeFoldable as _, TypeVisitableExt, }; -use rustc_span::DUMMY_SP; use rustc_type_ir::outlives::{Component, push_outlives_components}; use smallvec::smallvec; use tracing::{debug, instrument}; @@ -142,25 +141,6 @@ impl<'tcx> InferCtxt<'tcx> { ) -> Result<(), (PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>)> { assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot"); - let normalized_caller_bounds: Vec<_> = outlives_env - .param_env - .caller_bounds() - .iter() - .filter_map(|clause| { - let outlives = clause.as_type_outlives_clause()?; - Some( - deeply_normalize_ty( - outlives, - SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP), - ) - // FIXME(-Znext-solver): How do we accurately report an error span here :( - .map_err(|NoSolution| { - (outlives, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)) - }), - ) - }) - .try_collect()?; - // Must loop since the process of normalizing may itself register region obligations. for iteration in 0.. { let my_region_obligations = self.take_registered_region_obligations(); @@ -194,7 +174,7 @@ impl<'tcx> InferCtxt<'tcx> { self.tcx, outlives_env.region_bound_pairs(), None, - &normalized_caller_bounds, + outlives_env.known_type_outlives(), ); let category = origin.to_constraint_category(); outlives.type_must_outlive(origin, sup_type, sub_region, category); diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index fc9fa44b4c6..55171754618 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -33,12 +33,32 @@ impl<'tcx> OutlivesEnvironment<'tcx> { assumed_wf_tys: impl IntoIterator>, implied_bounds_compat: bool, ) -> Self { + let mut bounds = vec![]; + + for bound in param_env.caller_bounds() { + if let Some(mut type_outlives) = bound.as_type_outlives_clause() { + if infcx.next_trait_solver() { + match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>( + infcx.at(&ObligationCause::dummy(), param_env), + type_outlives, + ) { + Ok(new) => type_outlives = new, + Err(_) => { + infcx.dcx().delayed_bug(format!("could not normalize `{bound}`")); + } + } + } + bounds.push(type_outlives); + } + } + // FIXME: This needs to be modified so that we normalize the known type // outlives obligations then elaborate them into their region/type components. // Otherwise, ` as Mirror>::Assoc: 'b` will not imply `'a: 'b` even // if we can normalize `'a`. - OutlivesEnvironment::with_bounds( + OutlivesEnvironment::from_normalized_bounds( param_env, + bounds, infcx.implied_bounds_tys_with_compat( body_id, param_env, From 6763561161dff2419ffe9795ec8bc40671c16e9e Mon Sep 17 00:00:00 2001 From: Bart Jacobs Date: Tue, 28 Jan 2025 21:42:51 +0100 Subject: [PATCH 39/71] btree/node.rs: remove incorrect comment from pop_internal_level docs --- library/alloc/src/collections/btree/node.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 6815ac1c193..2525f5856cd 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -600,9 +600,6 @@ impl NodeRef { /// no cleanup is done on any of the keys, values and other children. /// This decreases the height by 1 and is the opposite of `push_internal_level`. /// - /// Requires exclusive access to the `NodeRef` object but not to the root node; - /// it will not invalidate other handles or references to the root node. - /// /// Panics if there is no internal level, i.e., if the root node is a leaf. pub(super) fn pop_internal_level(&mut self, alloc: A) { assert!(self.height > 0); From 941ab8cd187f987242d2872e0b6dabbcca569fd1 Mon Sep 17 00:00:00 2001 From: yegeunyang Date: Tue, 28 Jan 2025 20:42:26 -0600 Subject: [PATCH 40/71] Add "Writing tests" section --- src/doc/rustc-dev-guide/src/getting-started.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 03d2811e8b1..d7797d2e4bc 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -137,6 +137,10 @@ pull request, continuing the work on the feature. [abandoned-prs]: https://github.com/rust-lang/rust/pulls?q=is%3Apr+label%3AS-inactive+is%3Aclosed +### Writing tests + +Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the codebase. + ### Contributing to std (standard library) See [std-dev-guide](https://std-dev-guide.rust-lang.org/). From 0127e6479fa86a371e53412c4c46237877c81682 Mon Sep 17 00:00:00 2001 From: yegeunyang Date: Tue, 28 Jan 2025 21:05:12 -0600 Subject: [PATCH 41/71] Add link to declare_lint! macro --- src/doc/rustc-dev-guide/src/diagnostics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md index 709e9d4f889..8f389640d27 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics.md +++ b/src/doc/rustc-dev-guide/src/diagnostics.md @@ -602,7 +602,7 @@ as the linter walks the AST. You can then choose to emit lints in a very similar way to compile errors. You also declare the metadata of a particular lint via the `declare_lint!` -macro. This includes the name, the default level, a short description, and some +macro. [This macro](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html) includes the name, the default level, a short description, and some more details. Note that the lint and the lint pass must be registered with the compiler. From 4260e3a5b89de914567ee0689e87ffd7da400538 Mon Sep 17 00:00:00 2001 From: yegeunyang Date: Tue, 28 Jan 2025 22:56:52 -0600 Subject: [PATCH 42/71] Touch up a sentence --- src/doc/rustc-dev-guide/src/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index d7797d2e4bc..4cb1d0b31eb 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -139,7 +139,7 @@ pull request, continuing the work on the feature. ### Writing tests -Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the codebase. +Issues that have been resolved but do not have a regression test are marked with the `E-needs-test` label. Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the testing infrastructure and contribution workflow. ### Contributing to std (standard library) From 810e4c1bc62a4801a4c29fe6c975630acbd78370 Mon Sep 17 00:00:00 2001 From: Bart Jacobs Date: Wed, 29 Jan 2025 08:35:29 +0100 Subject: [PATCH 43/71] btree/node.rs: pop_internal_level: does not invalidate other handles --- library/alloc/src/collections/btree/node.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 2525f5856cd..37f784a322c 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -600,6 +600,9 @@ impl NodeRef { /// no cleanup is done on any of the keys, values and other children. /// This decreases the height by 1 and is the opposite of `push_internal_level`. /// + /// Does not invalidate any handles or references pointing into the subtree + /// rooted at the first child of `self`. + /// /// Panics if there is no internal level, i.e., if the root node is a leaf. pub(super) fn pop_internal_level(&mut self, alloc: A) { assert!(self.height > 0); From 57cfcd228dd6b5873c96799c64c6186fa8edec66 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Thu, 23 Jan 2025 10:16:08 +0100 Subject: [PATCH 44/71] use impl Into --- compiler/rustc_parse_format/src/lib.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 09c88e7f83b..d021ea107ed 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -363,12 +363,7 @@ impl<'a> Parser<'a> { /// Notifies of an error. The message doesn't actually need to be of type /// String, but I think it does when this eventually uses conditions so it /// might as well start using it now. - fn err, S2: Into>( - &mut self, - description: S1, - label: S2, - span: InnerSpan, - ) { + fn err(&mut self, description: impl Into, label: impl Into, span: InnerSpan) { self.errors.push(ParseError { description: description.into(), note: None, @@ -382,11 +377,11 @@ impl<'a> Parser<'a> { /// Notifies of an error. The message doesn't actually need to be of type /// String, but I think it does when this eventually uses conditions so it /// might as well start using it now. - fn err_with_note, S2: Into, S3: Into>( + fn err_with_note( &mut self, - description: S1, - label: S2, - note: S3, + description: impl Into, + label: impl Into, + note: impl Into, span: InnerSpan, ) { self.errors.push(ParseError { From b7916fb4b762d406a560c5e5f6e632033edd9c14 Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Thu, 23 Jan 2025 21:25:26 -0500 Subject: [PATCH 45/71] tests: Skip const OOM tests on aarch64-unknown-linux-gnu Skip const OOM tests on AArch64 Linux through explicit annotations instead of inside opt-dist. Intended to avoid confusion in cases like #135952. Prerequisite for https://github.com/rust-lang/rust/pull/135960. --- src/tools/opt-dist/src/main.rs | 12 +----------- tests/ui/consts/large_const_alloc.rs | 2 ++ tests/ui/consts/large_const_alloc.stderr | 4 ++-- .../promoted_running_out_of_memory_issue-130687.rs | 2 ++ ...romoted_running_out_of_memory_issue-130687.stderr | 2 +- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 04de3493ea2..565721a9093 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -148,16 +148,6 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> let is_aarch64 = target_triple.starts_with("aarch64"); - let skip_tests = if is_aarch64 { - vec![ - // Those tests fail only inside of Docker on aarch64, as of December 2024 - "tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs".to_string(), - "tests/ui/consts/large_const_alloc.rs".to_string(), - ] - } else { - vec![] - }; - let checkout_dir = Utf8PathBuf::from("/checkout"); let env = EnvironmentBuilder::default() .host_tuple(target_triple) @@ -169,7 +159,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec)> .shared_llvm(true) // FIXME: Enable bolt for aarch64 once it's fixed upstream. Broken as of December 2024. .use_bolt(!is_aarch64) - .skipped_tests(skip_tests) + .skipped_tests(vec![]) .build()?; (env, shared.build_args) diff --git a/tests/ui/consts/large_const_alloc.rs b/tests/ui/consts/large_const_alloc.rs index 61a22216ae5..14edc1bb696 100644 --- a/tests/ui/consts/large_const_alloc.rs +++ b/tests/ui/consts/large_const_alloc.rs @@ -1,5 +1,7 @@ //@ only-64bit // on 32bit and 16bit platforms it is plausible that the maximum allocation size will succeed +// FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger +//@ ignore-aarch64-unknown-linux-gnu const FOO: () = { // 128 TiB, unlikely anyone has that much RAM diff --git a/tests/ui/consts/large_const_alloc.stderr b/tests/ui/consts/large_const_alloc.stderr index 25d660f1217..fa7d5977a95 100644 --- a/tests/ui/consts/large_const_alloc.stderr +++ b/tests/ui/consts/large_const_alloc.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/large_const_alloc.rs:6:13 + --> $DIR/large_const_alloc.rs:8:13 | LL | let x = [0_u8; (1 << 47) - 1]; | ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler error[E0080]: could not evaluate static initializer - --> $DIR/large_const_alloc.rs:11:13 + --> $DIR/large_const_alloc.rs:13:13 | LL | let x = [0_u8; (1 << 47) - 1]; | ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs index b923a768cbf..53618e2e86a 100644 --- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs +++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs @@ -3,6 +3,8 @@ // Needs the max type size to be much bigger than the RAM people typically have. //@ only-64bit +// FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger +//@ ignore-aarch64-unknown-linux-gnu pub struct Data([u8; (1 << 47) - 1]); const _: &'static Data = &Data([0; (1 << 47) - 1]); diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr index f5d767efceb..aac805dbd8c 100644 --- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr +++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:32 + --> $DIR/promoted_running_out_of_memory_issue-130687.rs:10:32 | LL | const _: &'static Data = &Data([0; (1 << 47) - 1]); | ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler From d93cbe5d693b8f486b82d2b11a7cbb7e2c09c1e8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Dec 2024 15:29:19 +0100 Subject: [PATCH 46/71] Add new setting allowing to switch to sans serif fonts --- src/librustdoc/build.rs | 2 ++ src/librustdoc/html/static/css/rustdoc.css | 27 ++++++++++++++++-- .../html/static/fonts/FiraMono-Medium.woff2 | Bin 0 -> 64572 bytes .../html/static/fonts/FiraMono-Regular.woff2 | Bin 0 -> 64868 bytes src/librustdoc/html/static/js/settings.js | 11 +++++++ src/librustdoc/html/static/js/storage.js | 3 ++ src/librustdoc/html/static_files.rs | 2 ++ 7 files changed, 43 insertions(+), 2 deletions(-) create mode 100755 src/librustdoc/html/static/fonts/FiraMono-Medium.woff2 create mode 100755 src/librustdoc/html/static/fonts/FiraMono-Regular.woff2 diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs index 69337fb1d25..810225ca927 100644 --- a/src/librustdoc/build.rs +++ b/src/librustdoc/build.rs @@ -19,6 +19,8 @@ fn main() { "static/images/favicon-32x32.png", "static/fonts/FiraSans-Regular.woff2", "static/fonts/FiraSans-Medium.woff2", + "static/fonts/FiraMono-Regular.woff2", + "static/fonts/FiraMono-Medium.woff2", "static/fonts/FiraSans-LICENSE.txt", "static/fonts/SourceSerif4-Regular.ttf.woff2", "static/fonts/SourceSerif4-Bold.ttf.woff2", diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index f487d66edac..bf665bc61d6 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -38,6 +38,13 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ --code-block-border-radius: 6px; --impl-items-indent: 0.3em; --docblock-indent: 24px; + --font-family: "Source Serif 4", NanumBarunGothic, serif; + --font-family-code: "Source Code Pro", monospace; +} + +:root.sans-serif { + --font-family: "Fira Sans", sans-serif; + --font-family-code: "Fira Mono", monospace; } /* See FiraSans-LICENSE.txt for the Fira Sans license. */ @@ -57,6 +64,22 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ url("FiraSans-Medium-e1aa3f0a.woff2") format("woff2"); font-display: swap; } +@font-face { + font-family: 'Fira Mono'; + font-style: normal; + font-weight: 400; + src: local('Fira Mono'), + url("FiraMono-Regular-87c26294.woff2") format("woff2"); + font-display: swap; +} +@font-face { + font-family: 'Fira Mono'; + font-style: normal; + font-weight: 500; + src: local('Fira Mono Medium'), + url("FiraMono-Medium-86f75c8c.woff2") format("woff2"); + font-display: swap; +} /* See SourceSerif4-LICENSE.md for the Source Serif 4 license. */ @font-face { @@ -126,7 +149,7 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ body { /* Line spacing at least 1.5 per Web Content Accessibility Guidelines https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html */ - font: 1rem/1.5 "Source Serif 4", NanumBarunGothic, serif; + font: 1rem/1.5 var(--font-family); margin: 0; position: relative; /* We use overflow-wrap: break-word for Safari, which doesn't recognize @@ -380,7 +403,7 @@ details:not(.toggle) summary { } code, pre, .code-header, .type-signature { - font-family: "Source Code Pro", monospace; + font-family: var(--font-family-code) } .docblock code, .item-table dd code { border-radius: 3px; diff --git a/src/librustdoc/html/static/fonts/FiraMono-Medium.woff2 b/src/librustdoc/html/static/fonts/FiraMono-Medium.woff2 new file mode 100755 index 0000000000000000000000000000000000000000..610e9b2071ec1d6c47a7815010acb20f0abbdd98 GIT binary patch literal 64572 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ℜ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 literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static/fonts/FiraMono-Regular.woff2 b/src/librustdoc/html/static/fonts/FiraMono-Regular.woff2 new file mode 100755 index 0000000000000000000000000000000000000000..9fa44b7cc2d38680bc14df07ddf3f6b320740da5 GIT binary patch literal 64868 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 literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 183663b94fc..245159d8e05 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -50,6 +50,12 @@ removeClass(document.documentElement, "hide-modnav"); } break; + case "sans-serif-fonts": + if (value === true) { + addClass(document.documentElement, "sans-serif"); + } else { + removeClass(document.documentElement, "sans-serif"); + } } } @@ -232,6 +238,11 @@ "js_name": "disable-shortcuts", "default": false, }, + { + "name": "Use sans serif fonts", + "js_name": "sans-serif-fonts", + "default": false, + }, ]; // Then we build the DOM. diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index d77804d045e..1867e4cc0f3 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -211,6 +211,9 @@ if (getSettingValue("hide-toc") === "true") { if (getSettingValue("hide-modnav") === "true") { addClass(document.documentElement, "hide-modnav"); } +if (getSettingValue("sans-serif-fonts") === "true") { + addClass(document.documentElement, "sans-serif"); +} function updateSidebarWidth() { const desktopSidebarWidth = getSettingValue("desktop-sidebar-width"); if (desktopSidebarWidth && desktopSidebarWidth !== "null") { diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 6457ac731cb..ec59353948d 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -100,6 +100,8 @@ static_files! { rust_favicon_png_32 => "static/images/favicon-32x32.png", fira_sans_regular => "static/fonts/FiraSans-Regular.woff2", fira_sans_medium => "static/fonts/FiraSans-Medium.woff2", + fira_mono_regular => "static/fonts/FiraMono-Regular.woff2", + fira_mono_medium => "static/fonts/FiraMono-Medium.woff2", fira_sans_license => "static/fonts/FiraSans-LICENSE.txt", source_serif_4_regular => "static/fonts/SourceSerif4-Regular.ttf.woff2", source_serif_4_bold => "static/fonts/SourceSerif4-Bold.ttf.woff2", From 65fedebfc40653d88142171252f5e8b004afbfb9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Dec 2024 15:55:05 +0100 Subject: [PATCH 47/71] Add GUI test for new "sans serif fonts" setting --- tests/rustdoc-gui/font-serif-change.goml | 31 ++++++++++++++++++++++++ tests/rustdoc-gui/settings.goml | 8 +++--- 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 tests/rustdoc-gui/font-serif-change.goml diff --git a/tests/rustdoc-gui/font-serif-change.goml b/tests/rustdoc-gui/font-serif-change.goml new file mode 100644 index 00000000000..b14d5ae96f9 --- /dev/null +++ b/tests/rustdoc-gui/font-serif-change.goml @@ -0,0 +1,31 @@ +// Ensures that the font serif change is working as expected. +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" + +// By default, it should be the serif fonts. +store-value: (serif_font, '"Source Serif 4", NanumBarunGothic, serif') +store-value: (serif_code_font, '"Source Code Pro", monospace') +assert-css: ("body", {"font-family": |serif_font|}) +assert-css: ("p code", {"font-family": |serif_code_font|}) + +// We now switch to the sans serif font +click: "#settings-menu" +wait-for: "#sans-serif-fonts" +click: "#sans-serif-fonts" + +store-value: (font, '"Fira Sans", sans-serif') +store-value: (code_font, '"Fira Mono", monospace') +assert-css: ("body", {"font-family": |font|}) +assert-css: ("p code", {"font-family": |code_font|}) + +// Reloading the page to ensure it is loaded correctly. +reload: +assert-css: ("body", {"font-family": |font|}) +assert-css: ("p code", {"font-family": |code_font|}) + +// We switch back to the serif font +click: "#settings-menu" +wait-for: "#sans-serif-fonts" +click: "#sans-serif-fonts" + +assert-css: ("body", {"font-family": |serif_font|}) +assert-css: ("p code", {"font-family": |serif_code_font|}) diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index 1d93c07f9ec..4ab5b83d7c4 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -257,15 +257,15 @@ assert-text: ("#preferred-light-theme .setting-radio-name", "Preferred light the // We now check that clicking on the toggles' text is like clicking on the checkbox. // To test it, we use the "Disable keyboard shortcuts". set-local-storage: {"rustdoc-disable-shortcuts": "false"} -click: ".setting-line:last-child .setting-check span" +click: "#disable-shortcuts" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} // We now check that focusing a toggle and pressing Space is like clicking on it. assert-local-storage: {"rustdoc-disable-shortcuts": "true"} -focus: ".setting-line:last-child .setting-check input" +focus: "#disable-shortcuts" press-key: "Space" assert-local-storage: {"rustdoc-disable-shortcuts": "false"} -focus: ".setting-line:last-child .setting-check input" +focus: "#disable-shortcuts" press-key: "Space" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} @@ -276,7 +276,7 @@ assert-false: "#help-button .popover" wait-for-css: ("#settings-menu .popover", {"display": "block"}) // Now turn keyboard shortcuts back on, and see if they work. -click: ".setting-line:last-child .setting-check span" +click: "#disable-shortcuts" assert-local-storage: {"rustdoc-disable-shortcuts": "false"} press-key: "Escape" press-key: "?" From 91f6e000c29db3882039569e53d091df63ba5415 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Dec 2024 16:12:08 +0100 Subject: [PATCH 48/71] Fix tidy errors --- REUSE.toml | 2 +- license-metadata.json | 2 ++ src/tools/tidy/src/bins.rs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/REUSE.toml b/REUSE.toml index 6b16d97ed80..9e873e94eff 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -92,7 +92,7 @@ SPDX-FileCopyrightText = "2015 Anders Kaseorg " SPDX-License-Identifier = "MIT" [[annotations]] -path = "src/librustdoc/html/static/fonts/FiraSans**" +path = "src/librustdoc/html/static/fonts/Fira**" precedence = "override" SPDX-FileCopyrightText = ["2014, Mozilla Foundation", "2014, Telefonica S.A."] SPDX-License-Identifier = "OFL-1.1" diff --git a/license-metadata.json b/license-metadata.json index 09cc3693565..1814044d5a4 100644 --- a/license-metadata.json +++ b/license-metadata.json @@ -113,6 +113,8 @@ { "directories": [], "files": [ + "FiraMono-Medium.woff2", + "FiraMono-Regular.woff2", "FiraSans-LICENSE.txt", "FiraSans-Medium.woff2", "FiraSans-Regular.woff2" diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index d158a8e6324..9b78ba75a05 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -134,7 +134,7 @@ mod os_impl { &mut |entry| { let file = entry.path(); let extension = file.extension(); - let scripts = ["py", "sh", "ps1"]; + let scripts = ["py", "sh", "ps1", "woff2"]; if scripts.into_iter().any(|e| extension == Some(OsStr::new(e))) { return; } From 999a25ee891a20003b9004ff3bee5e2849efd375 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Dec 2024 16:12:08 +0100 Subject: [PATCH 49/71] Fix tidy errors --- license-metadata.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/license-metadata.json b/license-metadata.json index 1814044d5a4..35a362fafd3 100644 --- a/license-metadata.json +++ b/license-metadata.json @@ -117,7 +117,9 @@ "FiraMono-Regular.woff2", "FiraSans-LICENSE.txt", "FiraSans-Medium.woff2", - "FiraSans-Regular.woff2" + "FiraSans-Regular.woff2", + "FiraMono-Medium.woff2", + "FiraMono-Regular.woff2" ], "license": { "copyright": [ @@ -268,4 +270,4 @@ ], "type": "root" } -} \ No newline at end of file +} From 895564e0381e816705990ab5354739e8a64b158d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 18 Jan 2025 22:28:34 +0100 Subject: [PATCH 50/71] Add italic for newly added sans serif fonts --- license-metadata.json | 6 +++--- src/librustdoc/build.rs | 2 ++ src/librustdoc/html/static/css/rustdoc.css | 20 ++++++++++++++++-- .../html/static/fonts/FiraSans-Italic.woff2 | Bin 0 -> 136300 bytes .../static/fonts/FiraSans-MediumItalic.woff2 | Bin 0 -> 140588 bytes src/librustdoc/html/static_files.rs | 2 ++ src/librustdoc/html/templates/page.html | 2 +- 7 files changed, 26 insertions(+), 6 deletions(-) create mode 100755 src/librustdoc/html/static/fonts/FiraSans-Italic.woff2 create mode 100755 src/librustdoc/html/static/fonts/FiraSans-MediumItalic.woff2 diff --git a/license-metadata.json b/license-metadata.json index 35a362fafd3..4cf9bea2861 100644 --- a/license-metadata.json +++ b/license-metadata.json @@ -115,11 +115,11 @@ "files": [ "FiraMono-Medium.woff2", "FiraMono-Regular.woff2", + "FiraSans-Italic.woff2", "FiraSans-LICENSE.txt", "FiraSans-Medium.woff2", - "FiraSans-Regular.woff2", - "FiraMono-Medium.woff2", - "FiraMono-Regular.woff2" + "FiraSans-MediumItalic.woff2", + "FiraSans-Regular.woff2" ], "license": { "copyright": [ diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs index 810225ca927..5e25c588cd9 100644 --- a/src/librustdoc/build.rs +++ b/src/librustdoc/build.rs @@ -17,8 +17,10 @@ fn main() { "static/images/rust-logo.svg", "static/images/favicon.svg", "static/images/favicon-32x32.png", + "static/fonts/FiraSans-Italic.woff2", "static/fonts/FiraSans-Regular.woff2", "static/fonts/FiraSans-Medium.woff2", + "static/fonts/FiraSans-MediumItalic.woff2", "static/fonts/FiraMono-Regular.woff2", "static/fonts/FiraMono-Medium.woff2", "static/fonts/FiraSans-LICENSE.txt", diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index bf665bc61d6..71d4ca44da6 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -56,6 +56,14 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ url("FiraSans-Regular-0fe48ade.woff2") format("woff2"); font-display: swap; } +@font-face { + font-family: 'Fira Sans'; + font-style: italic; + font-weight: 400; + src: local('Fira Sans Italic'), + url("FiraSans-Italic-81dc35de.woff2") format("woff2"); + font-display: swap; +} @font-face { font-family: 'Fira Sans'; font-style: normal; @@ -64,6 +72,14 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ url("FiraSans-Medium-e1aa3f0a.woff2") format("woff2"); font-display: swap; } +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 500; + src: local('Fira Sans Medium Italic'), + url("FiraSans-MediumItalic-ccf7e434.woff2") format("woff2"); + font-display: swap; +} @font-face { font-family: 'Fira Mono'; font-style: normal; @@ -273,7 +289,7 @@ summary.hideme, .rustdoc-breadcrumbs, /* This selector is for the items listed in the "all items" page. */ ul.all-items { - font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif; + font-family: var(--font-family); } #toggle-all-docs, @@ -403,7 +419,7 @@ details:not(.toggle) summary { } code, pre, .code-header, .type-signature { - font-family: var(--font-family-code) + font-family: var(--font-family-code); } .docblock code, .item-table dd code { border-radius: 3px; diff --git a/src/librustdoc/html/static/fonts/FiraSans-Italic.woff2 b/src/librustdoc/html/static/fonts/FiraSans-Italic.woff2 new file mode 100755 index 0000000000000000000000000000000000000000..3f63664fee6ddf221f71a57461a7f4d1de281177 GIT binary patch literal 136300 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≫Z$OHx4eWbW1E?5o%p_ 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 S^KaC%*UN+?Bwk@=U;qHNWc059 literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static/fonts/FiraSans-MediumItalic.woff2 b/src/librustdoc/html/static/fonts/FiraSans-MediumItalic.woff2 new file mode 100755 index 0000000000000000000000000000000000000000..2d08f9f7d45fda39315519c4d6ffce5b84454d70 GIT binary patch literal 140588 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¨{$-yCTqVw{kyY8 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 literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index ec59353948d..31911951482 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -98,8 +98,10 @@ static_files! { rust_logo_svg => "static/images/rust-logo.svg", rust_favicon_svg => "static/images/favicon.svg", rust_favicon_png_32 => "static/images/favicon-32x32.png", + fira_sans_italic => "static/fonts/FiraSans-Italic.woff2", fira_sans_regular => "static/fonts/FiraSans-Regular.woff2", fira_sans_medium => "static/fonts/FiraSans-Medium.woff2", + fira_sans_medium_italic => "static/fonts/FiraSans-MediumItalic.woff2", fira_mono_regular => "static/fonts/FiraMono-Regular.woff2", fira_mono_medium => "static/fonts/FiraMono-Medium.woff2", fira_sans_license => "static/fonts/FiraSans-LICENSE.txt", diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index a05d6ca8313..5ef376f4acb 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -7,7 +7,7 @@ {# #} {{page.title}} {# #} {# #} {# #} From 22f074129a27e229b30c69b8e8d600dee3593537 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 28 Jan 2025 11:59:29 +0000 Subject: [PATCH 51/71] Add tests for transmuting pattern types --- tests/ui/type/pattern_types/transmute.rs | 34 +++++++++++++++++ tests/ui/type/pattern_types/transmute.stderr | 39 ++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/ui/type/pattern_types/transmute.rs create mode 100644 tests/ui/type/pattern_types/transmute.stderr diff --git a/tests/ui/type/pattern_types/transmute.rs b/tests/ui/type/pattern_types/transmute.rs new file mode 100644 index 00000000000..54aab6e3cb2 --- /dev/null +++ b/tests/ui/type/pattern_types/transmute.rs @@ -0,0 +1,34 @@ +#![feature(pattern_types)] +#![feature(pattern_type_macro)] + +use std::pat::pattern_type; + +// ok +fn create(x: u32) -> pattern_type!(u32 is S..=E) { + unsafe { std::mem::transmute(x) } + //~^ ERROR types of different sizes +} + +// ok +fn unwrap(x: pattern_type!(u32 is S..=E)) -> u32 { + unsafe { std::mem::transmute(x) } + //~^ ERROR types of different sizes +} + +// bad, only when S != u32::MIN or E != u32::MAX will this ok +fn non_base_ty_transmute( + x: Option, +) -> u32 { + unsafe { std::mem::transmute(x) } + //~^ ERROR types of different sizes +} + +// bad, only when S = u32::MIN and E = u32::MAX will this ok +fn wrapped_transmute( + x: Option, +) -> Option { + unsafe { std::mem::transmute(x) } + //~^ ERROR types of different sizes +} + +fn main() {} diff --git a/tests/ui/type/pattern_types/transmute.stderr b/tests/ui/type/pattern_types/transmute.stderr new file mode 100644 index 00000000000..f348740b105 --- /dev/null +++ b/tests/ui/type/pattern_types/transmute.stderr @@ -0,0 +1,39 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:8:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `u32` (32 bits) + = note: target type: `(u32) is S..=E` (size can vary because of u32) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:14:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `(u32) is S..=E` (size can vary because of u32) + = note: target type: `u32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:22:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) + = note: target type: `u32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:30:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) + = note: target type: `Option` (64 bits) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0512`. From a639e276f3bfb0e0538bad78f3d68ebb7877aeaa Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 28 Jan 2025 11:08:22 +0000 Subject: [PATCH 52/71] Allow transmuting generic pattern types to and from their base --- compiler/rustc_middle/src/ty/layout.rs | 3 +++ tests/ui/type/pattern_types/transmute.rs | 2 -- tests/ui/type/pattern_types/transmute.stderr | 24 +++----------------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 0d41a1d7dbf..b212992bd2d 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -504,6 +504,9 @@ impl<'tcx> SizeSkeleton<'tcx> { } } + // Pattern types are always the same size as their base. + ty::Pat(base, _) => SizeSkeleton::compute(base, tcx, typing_env), + _ => Err(err), } } diff --git a/tests/ui/type/pattern_types/transmute.rs b/tests/ui/type/pattern_types/transmute.rs index 54aab6e3cb2..cb76b2b938d 100644 --- a/tests/ui/type/pattern_types/transmute.rs +++ b/tests/ui/type/pattern_types/transmute.rs @@ -6,13 +6,11 @@ use std::pat::pattern_type; // ok fn create(x: u32) -> pattern_type!(u32 is S..=E) { unsafe { std::mem::transmute(x) } - //~^ ERROR types of different sizes } // ok fn unwrap(x: pattern_type!(u32 is S..=E)) -> u32 { unsafe { std::mem::transmute(x) } - //~^ ERROR types of different sizes } // bad, only when S != u32::MIN or E != u32::MAX will this ok diff --git a/tests/ui/type/pattern_types/transmute.stderr b/tests/ui/type/pattern_types/transmute.stderr index f348740b105..578549b515c 100644 --- a/tests/ui/type/pattern_types/transmute.stderr +++ b/tests/ui/type/pattern_types/transmute.stderr @@ -1,23 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute.rs:8:14 - | -LL | unsafe { std::mem::transmute(x) } - | ^^^^^^^^^^^^^^^^^^^ - | - = note: source type: `u32` (32 bits) - = note: target type: `(u32) is S..=E` (size can vary because of u32) - -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute.rs:14:14 - | -LL | unsafe { std::mem::transmute(x) } - | ^^^^^^^^^^^^^^^^^^^ - | - = note: source type: `(u32) is S..=E` (size can vary because of u32) - = note: target type: `u32` (32 bits) - -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute.rs:22:14 + --> $DIR/transmute.rs:20:14 | LL | unsafe { std::mem::transmute(x) } | ^^^^^^^^^^^^^^^^^^^ @@ -26,7 +8,7 @@ LL | unsafe { std::mem::transmute(x) } = note: target type: `u32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute.rs:30:14 + --> $DIR/transmute.rs:28:14 | LL | unsafe { std::mem::transmute(x) } | ^^^^^^^^^^^^^^^^^^^ @@ -34,6 +16,6 @@ LL | unsafe { std::mem::transmute(x) } = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) = note: target type: `Option` (64 bits) -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0512`. From 2511faf61d82dd32fa40f1724e6ee74d51700b54 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 29 Jan 2025 11:44:14 +0100 Subject: [PATCH 53/71] Add SemiBold for SourceSerif4 --- src/librustdoc/build.rs | 1 + src/librustdoc/html/static/COPYRIGHT.txt | 2 +- src/librustdoc/html/static/css/rustdoc.css | 12 ++++++++++-- .../fonts/SourceSerif4-Semibold.ttf.woff2 | Bin 0 -> 80732 bytes src/librustdoc/html/static_files.rs | 1 + 5 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 src/librustdoc/html/static/fonts/SourceSerif4-Semibold.ttf.woff2 diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs index 5e25c588cd9..b4b0a8d0615 100644 --- a/src/librustdoc/build.rs +++ b/src/librustdoc/build.rs @@ -25,6 +25,7 @@ fn main() { "static/fonts/FiraMono-Medium.woff2", "static/fonts/FiraSans-LICENSE.txt", "static/fonts/SourceSerif4-Regular.ttf.woff2", + "static/fonts/SourceSerif4-Semibold.ttf.woff2", "static/fonts/SourceSerif4-Bold.ttf.woff2", "static/fonts/SourceSerif4-It.ttf.woff2", "static/fonts/SourceSerif4-LICENSE.md", diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index 1447df792f6..111340298c5 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -36,7 +36,7 @@ included, and carry their own copyright notices and license terms: See SourceCodePro-LICENSE.txt. * Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, - SourceSerif4-It.ttf.woff2): + SourceSerif4-It.ttf.woff2, SourceSerif4-Semibold.ttf.woff2): Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 71d4ca44da6..d0612e997fd 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -74,7 +74,7 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ } @font-face { font-family: 'Fira Sans'; - font-style: normal; + font-style: italic; font-weight: 500; src: local('Fira Sans Medium Italic'), url("FiraSans-MediumItalic-ccf7e434.woff2") format("woff2"); @@ -114,6 +114,14 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ url("SourceSerif4-It-ca3b17ed.ttf.woff2") format("woff2"); font-display: swap; } +@font-face { + font-family: 'Source Serif 4'; + font-style: normal; + font-weight: 500; + src: local('Source Serif 4 Semibold'), + url("SourceSerif4-Semibold-457a13ac.ttf.woff2") format("woff2"); + font-display: swap; +} @font-face { font-family: 'Source Serif 4'; font-style: normal; @@ -289,7 +297,7 @@ summary.hideme, .rustdoc-breadcrumbs, /* This selector is for the items listed in the "all items" page. */ ul.all-items { - font-family: var(--font-family); + font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif; } #toggle-all-docs, diff --git a/src/librustdoc/html/static/fonts/SourceSerif4-Semibold.ttf.woff2 b/src/librustdoc/html/static/fonts/SourceSerif4-Semibold.ttf.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..dd55f4e95ec9c29fb566d8617104afca31f0eeef GIT binary patch literal 80732 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 "static/fonts/FiraMono-Medium.woff2", fira_sans_license => "static/fonts/FiraSans-LICENSE.txt", source_serif_4_regular => "static/fonts/SourceSerif4-Regular.ttf.woff2", + source_serif_4_semibold => "static/fonts/SourceSerif4-Semibold.ttf.woff2", source_serif_4_bold => "static/fonts/SourceSerif4-Bold.ttf.woff2", source_serif_4_italic => "static/fonts/SourceSerif4-It.ttf.woff2", source_serif_4_license => "static/fonts/SourceSerif4-LICENSE.md", From 869bc2fded5e8b9332001da5a1ea252ca5f4f9ad Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Tue, 28 Jan 2025 00:51:33 +0300 Subject: [PATCH 54/71] override build profile for bootstrap tests Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 3 +++ src/bootstrap/src/core/builder/cargo.rs | 28 +++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 0d3ab6ad97d..505a6ef3e34 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -86,6 +86,7 @@ impl Step for CrateBootstrap { SourceType::InTree, &[], ); + let crate_name = path.rsplit_once('/').unwrap().1; run_cargo_test(cargo, &[], &[], crate_name, crate_name, bootstrap_host, builder); } @@ -3099,6 +3100,8 @@ impl Step for Bootstrap { &[], ); + cargo.release_build(false); + cargo .rustflag("-Cdebuginfo=2") .env("CARGO_TARGET_DIR", builder.out.join("bootstrap")) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 6b792108784..4059aa6bcd2 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -88,12 +88,14 @@ impl HostFlags { #[derive(Debug)] pub struct Cargo { command: BootstrapCommand, + args: Vec, compiler: Compiler, target: TargetSelection, rustflags: Rustflags, rustdocflags: Rustflags, hostflags: HostFlags, allow_features: String, + release_build: bool, } impl Cargo { @@ -121,6 +123,10 @@ impl Cargo { cargo } + pub fn release_build(&mut self, release_build: bool) { + self.release_build = release_build; + } + pub fn compiler(&self) -> Compiler { self.compiler } @@ -153,7 +159,7 @@ impl Cargo { } pub fn arg(&mut self, arg: impl AsRef) -> &mut Cargo { - self.command.arg(arg.as_ref()); + self.args.push(arg.as_ref().into()); self } @@ -335,6 +341,12 @@ impl Cargo { impl From for BootstrapCommand { fn from(mut cargo: Cargo) -> BootstrapCommand { + if cargo.release_build { + cargo.args.insert(0, "--release".into()); + } + + cargo.command.args(cargo.args); + let rustflags = &cargo.rustflags.0; if !rustflags.is_empty() { cargo.command.env("RUSTFLAGS", rustflags); @@ -353,6 +365,7 @@ impl From for BootstrapCommand { if !cargo.allow_features.is_empty() { cargo.command.env("RUSTC_ALLOW_FEATURES", cargo.allow_features); } + cargo.command } } @@ -422,13 +435,6 @@ impl Builder<'_> { assert_eq!(target, compiler.host); } - if self.config.rust_optimize.is_release() && - // cargo bench/install do not accept `--release` and miri doesn't want it - !matches!(cmd_kind, Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest) - { - cargo.arg("--release"); - } - // Remove make-related flags to ensure Cargo can correctly set things up cargo.env_remove("MAKEFLAGS"); cargo.env_remove("MFLAGS"); @@ -1214,14 +1220,20 @@ impl Builder<'_> { rustflags.arg("-Zmir_strip_debuginfo=locals-in-tiny-functions"); } + let release_build = self.config.rust_optimize.is_release() && + // cargo bench/install do not accept `--release` and miri doesn't want it + !matches!(cmd_kind, Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest); + Cargo { command: cargo, + args: vec![], compiler, target, rustflags, rustdocflags, hostflags, allow_features, + release_build, } } } From 2f276b36e203c05b3c38b427d6e38219ae6a2cf1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 29 Jan 2025 13:27:41 -0300 Subject: [PATCH 55/71] spastorino back from vacations --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 4a09fe116a5..6beaae2b9b7 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1023,7 +1023,6 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" users_on_vacation = [ "jyn514", "nnethercote", - "spastorino", "workingjubilee", "kobzol" ] From e4db6d7825cc22991f2c73623c39c457e86a1600 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 27 Jan 2025 13:55:21 -0800 Subject: [PATCH 56/71] Add release notes for 1.84.1 --- RELEASES.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 2da6ed3f100..e0175db7ec8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,18 @@ +Version 1.84.1 (2025-01-30) +========================== + + + +- [Fix ICE 132920 in duplicate-crate diagnostics.](https://github.com/rust-lang/rust/pull/133304/) +- [Fix errors for overlapping impls in incremental rebuilds.](https://github.com/rust-lang/rust/pull/133828/) +- [Fix slow compilation related to the next-generation trait solver.](https://github.com/rust-lang/rust/pull/135618/) +- [Fix debuginfo when LLVM's location discriminator value limit is exceeded.](https://github.com/rust-lang/rust/pull/135643/) +- Fixes for building Rust from source: + - [Only try to distribute `llvm-objcopy` if llvm tools are enabled.](https://github.com/rust-lang/rust/pull/134240/) + - [Add Profile Override for Non-Git Sources.](https://github.com/rust-lang/rust/pull/135433/) + - [Resolve symlinks of LLVM tool binaries before copying them.](https://github.com/rust-lang/rust/pull/135585/) + - [Make it possible to use ci-rustc on tarball sources.](https://github.com/rust-lang/rust/pull/135722/) + Version 1.84.0 (2025-01-09) ========================== From 311c3b71f0972e144cac91679a08906875c8af3f Mon Sep 17 00:00:00 2001 From: edwloef Date: Mon, 27 Jan 2025 16:35:15 +0100 Subject: [PATCH 57/71] split slice::ptr_rotate into three separate algorithms, to hopefully help inlining --- library/core/src/slice/rotate.rs | 373 ++++++++++++++++--------------- 1 file changed, 197 insertions(+), 176 deletions(-) diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index 20833dc31aa..3e88978b781 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -1,6 +1,8 @@ use crate::mem::{self, MaybeUninit, SizedTypeProperties}; use crate::{cmp, ptr}; +type BufType = [usize; 32]; + /// Rotates the range `[mid-left, mid+right)` such that the element at `mid` becomes the first /// element. Equivalently, rotates the range `left` elements to the left or `right` elements to the /// right. @@ -8,17 +10,76 @@ use crate::{cmp, ptr}; /// # Safety /// /// The specified range must be valid for reading and writing. -/// -/// # Algorithm -/// +pub(super) unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { + if T::IS_ZST { + return; + } + // abort early if the rotate is a no-op + if (left == 0) || (right == 0) { + return; + } + // `T` is not a zero-sized type, so it's okay to divide by its size. + if !cfg!(feature = "optimize_for_size") + && cmp::min(left, right) <= mem::size_of::() / mem::size_of::() + { + // SAFETY: guaranteed by the caller + unsafe { ptr_rotate_memmove(left, mid, right) }; + } else if !cfg!(feature = "optimize_for_size") + && ((left + right < 24) || (mem::size_of::() > mem::size_of::<[usize; 4]>())) + { + // SAFETY: guaranteed by the caller + unsafe { ptr_rotate_gcd(left, mid, right) } + } else { + // SAFETY: guaranteed by the caller + unsafe { ptr_rotate_swap(left, mid, right) } + } +} + /// Algorithm 1 is used if `min(left, right)` is small enough to fit onto a stack buffer. The /// `min(left, right)` elements are copied onto the buffer, `memmove` is applied to the others, and /// the ones on the buffer are moved back into the hole on the opposite side of where they /// originated. /// -/// Algorithms that can be vectorized outperform the above once `left + right` becomes large enough. +/// # Safety /// -/// Algorithm 2 is otherwise used for small values of `left + right` or for large `T`. The elements +/// The specified range must be valid for reading and writing. +unsafe fn ptr_rotate_memmove(left: usize, mid: *mut T, right: usize) { + // The `[T; 0]` here is to ensure this is appropriately aligned for T + let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); + let buf = rawarray.as_mut_ptr() as *mut T; + // SAFETY: `mid-left <= mid-left+right < mid+right` + let dim = unsafe { mid.sub(left).add(right) }; + if left <= right { + // SAFETY: + // + // 1) The `if` condition about the sizes ensures `[mid-left; left]` will fit in + // `buf` without overflow and `buf` was created just above and so cannot be + // overlapped with any value of `[mid-left; left]` + // 2) [mid-left, mid+right) are all valid for reading and writing and we don't care + // about overlaps here. + // 3) The `if` condition about `left <= right` ensures writing `left` elements to + // `dim = mid-left+right` is valid because: + // - `buf` is valid and `left` elements were written in it in 1) + // - `dim+left = mid-left+right+left = mid+right` and we write `[dim, dim+left)` + unsafe { + // 1) + ptr::copy_nonoverlapping(mid.sub(left), buf, left); + // 2) + ptr::copy(mid, mid.sub(left), right); + // 3) + ptr::copy_nonoverlapping(buf, dim, left); + } + } else { + // SAFETY: same reasoning as above but with `left` and `right` reversed + unsafe { + ptr::copy_nonoverlapping(mid, buf, right); + ptr::copy(mid.sub(left), dim, left); + ptr::copy_nonoverlapping(buf, mid.sub(left), right); + } + } +} + +/// Algorithm 2 is used for small values of `left + right` or for large `T`. The elements /// are moved into their final positions one at a time starting at `mid - left` and advancing by /// `right` steps modulo `left + right`, such that only one temporary is needed. Eventually, we /// arrive back at `mid - left`. However, if `gcd(left + right, right)` is not 1, the above steps @@ -48,9 +109,101 @@ use crate::{cmp, ptr}; /// /// Algorithm 2 can be vectorized by chunking and performing many rounds at once, but there are too /// few rounds on average until `left + right` is enormous, and the worst case of a single -/// round is always there. Instead, algorithm 3 utilizes repeated swapping of -/// `min(left, right)` elements until a smaller rotate problem is left. +/// round is always there. /// +/// # Safety +/// +/// The specified range must be valid for reading and writing. +unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { + // Algorithm 2 + // Microbenchmarks indicate that the average performance for random shifts is better all + // the way until about `left + right == 32`, but the worst case performance breaks even + // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4 + // `usize`s, this algorithm also outperforms other algorithms. + // SAFETY: callers must ensure `mid - left` is valid for reading and writing. + let x = unsafe { mid.sub(left) }; + // beginning of first round + // SAFETY: see previous comment. + let mut tmp: T = unsafe { x.read() }; + let mut i = right; + // `gcd` can be found before hand by calculating `gcd(left + right, right)`, + // but it is faster to do one loop which calculates the gcd as a side effect, then + // doing the rest of the chunk + let mut gcd = right; + // benchmarks reveal that it is faster to swap temporaries all the way through instead + // of reading one temporary once, copying backwards, and then writing that temporary at + // the very end. This is possibly due to the fact that swapping or replacing temporaries + // uses only one memory address in the loop instead of needing to manage two. + loop { + // [long-safety-expl] + // SAFETY: callers must ensure `[left, left+mid+right)` are all valid for reading and + // writing. + // + // - `i` start with `right` so `mid-left <= x+i = x+right = mid-left+right < mid+right` + // - `i <= left+right-1` is always true + // - if `i < left`, `right` is added so `i < left+right` and on the next + // iteration `left` is removed from `i` so it doesn't go further + // - if `i >= left`, `left` is removed immediately and so it doesn't go further. + // - overflows cannot happen for `i` since the function's safety contract ask for + // `mid+right-1 = x+left+right` to be valid for writing + // - underflows cannot happen because `i` must be bigger or equal to `left` for + // a subtraction of `left` to happen. + // + // So `x+i` is valid for reading and writing if the caller respected the contract + tmp = unsafe { x.add(i).replace(tmp) }; + // instead of incrementing `i` and then checking if it is outside the bounds, we + // check if `i` will go outside the bounds on the next increment. This prevents + // any wrapping of pointers or `usize`. + if i >= left { + i -= left; + if i == 0 { + // end of first round + // SAFETY: tmp has been read from a valid source and x is valid for writing + // according to the caller. + unsafe { x.write(tmp) }; + break; + } + // this conditional must be here if `left + right >= 15` + if i < gcd { + gcd = i; + } + } else { + i += right; + } + } + // finish the chunk with more rounds + for start in 1..gcd { + // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for + // reading and writing as per the function's safety contract, see [long-safety-expl] + // above + tmp = unsafe { x.add(start).read() }; + // [safety-expl-addition] + // + // Here `start < gcd` so `start < right` so `i < right+right`: `right` being the + // greatest common divisor of `(left+right, right)` means that `left = right` so + // `i < left+right` so `x+i = mid-left+i` is always valid for reading and writing + // according to the function's safety contract. + i = start + right; + loop { + // SAFETY: see [long-safety-expl] and [safety-expl-addition] + tmp = unsafe { x.add(i).replace(tmp) }; + if i >= left { + i -= left; + if i == start { + // SAFETY: see [long-safety-expl] and [safety-expl-addition] + unsafe { x.add(start).write(tmp) }; + break; + } + } else { + i += right; + } + } + } +} + +/// Algorithm 3 utilizes repeated swapping of `min(left, right)` elements. +/// +/// /// /// ```text /// left = 11, right = 4 /// [4 5 6 7 8 9 10 11 12 13 14 . 0 1 2 3] @@ -61,182 +214,50 @@ use crate::{cmp, ptr}; /// we cannot swap any more, but a smaller rotation problem is left to solve /// ``` /// when `left < right` the swapping happens from the left instead. -pub(super) unsafe fn ptr_rotate(mut left: usize, mut mid: *mut T, mut right: usize) { - type BufType = [usize; 32]; - if T::IS_ZST { - return; - } - // N.B. the below algorithms can fail if these cases are not checked - if (right == 0) || (left == 0) { - return; - } - // `T` is not a zero-sized type, so it's okay to divide by its size. - if !cfg!(feature = "optimize_for_size") - && cmp::min(left, right) <= mem::size_of::() / mem::size_of::() - { - // Algorithm 1 - // The `[T; 0]` here is to ensure this is appropriately aligned for T - let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); - let buf = rawarray.as_mut_ptr() as *mut T; - // SAFETY: `mid-left <= mid-left+right < mid+right` - let dim = unsafe { mid.sub(left).add(right) }; - if left <= right { - // SAFETY: - // - // 1) The `if` condition about the sizes ensures `[mid-left; left]` will fit in - // `buf` without overflow and `buf` was created just above and so cannot be - // overlapped with any value of `[mid-left; left]` - // 2) [mid-left, mid+right) are all valid for reading and writing and we don't care - // about overlaps here. - // 3) The `if` condition about `left <= right` ensures writing `left` elements to - // `dim = mid-left+right` is valid because: - // - `buf` is valid and `left` elements were written in it in 1) - // - `dim+left = mid-left+right+left = mid+right` and we write `[dim, dim+left)` - unsafe { - // 1) - ptr::copy_nonoverlapping(mid.sub(left), buf, left); - // 2) - ptr::copy(mid, mid.sub(left), right); - // 3) - ptr::copy_nonoverlapping(buf, dim, left); - } - } else { - // SAFETY: same reasoning as above but with `left` and `right` reversed - unsafe { - ptr::copy_nonoverlapping(mid, buf, right); - ptr::copy(mid.sub(left), dim, left); - ptr::copy_nonoverlapping(buf, mid.sub(left), right); - } - } - } else if !cfg!(feature = "optimize_for_size") - && ((left + right < 24) || (mem::size_of::() > mem::size_of::<[usize; 4]>())) - { - // Algorithm 2 - // Microbenchmarks indicate that the average performance for random shifts is better all - // the way until about `left + right == 32`, but the worst case performance breaks even - // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4 - // `usize`s, this algorithm also outperforms other algorithms. - // SAFETY: callers must ensure `mid - left` is valid for reading and writing. - let x = unsafe { mid.sub(left) }; - // beginning of first round - // SAFETY: see previous comment. - let mut tmp: T = unsafe { x.read() }; - let mut i = right; - // `gcd` can be found before hand by calculating `gcd(left + right, right)`, - // but it is faster to do one loop which calculates the gcd as a side effect, then - // doing the rest of the chunk - let mut gcd = right; - // benchmarks reveal that it is faster to swap temporaries all the way through instead - // of reading one temporary once, copying backwards, and then writing that temporary at - // the very end. This is possibly due to the fact that swapping or replacing temporaries - // uses only one memory address in the loop instead of needing to manage two. - loop { - // [long-safety-expl] - // SAFETY: callers must ensure `[left, left+mid+right)` are all valid for reading and - // writing. - // - // - `i` start with `right` so `mid-left <= x+i = x+right = mid-left+right < mid+right` - // - `i <= left+right-1` is always true - // - if `i < left`, `right` is added so `i < left+right` and on the next - // iteration `left` is removed from `i` so it doesn't go further - // - if `i >= left`, `left` is removed immediately and so it doesn't go further. - // - overflows cannot happen for `i` since the function's safety contract ask for - // `mid+right-1 = x+left+right` to be valid for writing - // - underflows cannot happen because `i` must be bigger or equal to `left` for - // a subtraction of `left` to happen. - // - // So `x+i` is valid for reading and writing if the caller respected the contract - tmp = unsafe { x.add(i).replace(tmp) }; - // instead of incrementing `i` and then checking if it is outside the bounds, we - // check if `i` will go outside the bounds on the next increment. This prevents - // any wrapping of pointers or `usize`. - if i >= left { - i -= left; - if i == 0 { - // end of first round - // SAFETY: tmp has been read from a valid source and x is valid for writing - // according to the caller. - unsafe { x.write(tmp) }; +/// +/// # Safety +/// +/// The specified range must be valid for reading and writing. +unsafe fn ptr_rotate_swap(mut left: usize, mut mid: *mut T, mut right: usize) { + loop { + if left >= right { + // Algorithm 3 + // There is an alternate way of swapping that involves finding where the last swap + // of this algorithm would be, and swapping using that last chunk instead of swapping + // adjacent chunks like this algorithm is doing, but this way is still faster. + loop { + // SAFETY: + // `left >= right` so `[mid-right, mid+right)` is valid for reading and writing + // Subtracting `right` from `mid` each turn is counterbalanced by the addition and + // check after it. + unsafe { + ptr::swap_nonoverlapping(mid.sub(right), mid, right); + mid = mid.sub(right); + } + left -= right; + if left < right { break; } - // this conditional must be here if `left + right >= 15` - if i < gcd { - gcd = i; - } - } else { - i += right; } - } - // finish the chunk with more rounds - for start in 1..gcd { - // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for - // reading and writing as per the function's safety contract, see [long-safety-expl] - // above - tmp = unsafe { x.add(start).read() }; - // [safety-expl-addition] - // - // Here `start < gcd` so `start < right` so `i < right+right`: `right` being the - // greatest common divisor of `(left+right, right)` means that `left = right` so - // `i < left+right` so `x+i = mid-left+i` is always valid for reading and writing - // according to the function's safety contract. - i = start + right; + } else { + // Algorithm 3, `left < right` loop { - // SAFETY: see [long-safety-expl] and [safety-expl-addition] - tmp = unsafe { x.add(i).replace(tmp) }; - if i >= left { - i -= left; - if i == start { - // SAFETY: see [long-safety-expl] and [safety-expl-addition] - unsafe { x.add(start).write(tmp) }; - break; - } - } else { - i += right; + // SAFETY: `[mid-left, mid+left)` is valid for reading and writing because + // `left < right` so `mid+left < mid+right`. + // Adding `left` to `mid` each turn is counterbalanced by the subtraction and check + // after it. + unsafe { + ptr::swap_nonoverlapping(mid.sub(left), mid, left); + mid = mid.add(left); + } + right -= left; + if right < left { + break; } } } - } else { - loop { - if left >= right { - // Algorithm 3 - // There is an alternate way of swapping that involves finding where the last swap - // of this algorithm would be, and swapping using that last chunk instead of swapping - // adjacent chunks like this algorithm is doing, but this way is still faster. - loop { - // SAFETY: - // `left >= right` so `[mid-right, mid+right)` is valid for reading and writing - // Subtracting `right` from `mid` each turn is counterbalanced by the addition and - // check after it. - unsafe { - ptr::swap_nonoverlapping(mid.sub(right), mid, right); - mid = mid.sub(right); - } - left -= right; - if left < right { - break; - } - } - } else { - // Algorithm 3, `left < right` - loop { - // SAFETY: `[mid-left, mid+left)` is valid for reading and writing because - // `left < right` so `mid+left < mid+right`. - // Adding `left` to `mid` each turn is counterbalanced by the subtraction and check - // after it. - unsafe { - ptr::swap_nonoverlapping(mid.sub(left), mid, left); - mid = mid.add(left); - } - right -= left; - if right < left { - break; - } - } - } - - if (right == 0) || (left == 0) { - return; - } + if (right == 0) || (left == 0) { + return; } } } From fb3d1d0c4bcd1b744c8ef23ba977bad9fcd43849 Mon Sep 17 00:00:00 2001 From: edwloef Date: Tue, 28 Jan 2025 12:26:32 +0100 Subject: [PATCH 58/71] add inline attribute and codegen test --- library/core/src/slice/rotate.rs | 4 +++ .../codegen/lib-optimizations/slice_rotate.rs | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 tests/codegen/lib-optimizations/slice_rotate.rs diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index 3e88978b781..5d5ee4c7b62 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -10,6 +10,7 @@ type BufType = [usize; 32]; /// # Safety /// /// The specified range must be valid for reading and writing. +#[inline] pub(super) unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { if T::IS_ZST { return; @@ -43,6 +44,7 @@ pub(super) unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { /// # Safety /// /// The specified range must be valid for reading and writing. +#[inline] unsafe fn ptr_rotate_memmove(left: usize, mid: *mut T, right: usize) { // The `[T; 0]` here is to ensure this is appropriately aligned for T let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); @@ -114,6 +116,7 @@ unsafe fn ptr_rotate_memmove(left: usize, mid: *mut T, right: usize) { /// # Safety /// /// The specified range must be valid for reading and writing. +#[inline] unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { // Algorithm 2 // Microbenchmarks indicate that the average performance for random shifts is better all @@ -218,6 +221,7 @@ unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { /// # Safety /// /// The specified range must be valid for reading and writing. +#[inline] unsafe fn ptr_rotate_swap(mut left: usize, mut mid: *mut T, mut right: usize) { loop { if left >= right { diff --git a/tests/codegen/lib-optimizations/slice_rotate.rs b/tests/codegen/lib-optimizations/slice_rotate.rs new file mode 100644 index 00000000000..d0a7b328d18 --- /dev/null +++ b/tests/codegen/lib-optimizations/slice_rotate.rs @@ -0,0 +1,30 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] + +// Ensure that the simple case of rotating by a constant 1 optimizes to the obvious thing + +// CHECK-LABEL: @rotate_left_by_one +#[no_mangle] +pub fn rotate_left_by_one(slice: &mut [i32]) { + // CHECK-NOT: phi + // CHECK-NOT: call + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: getelementptr + // CHECK: %[[END:.+]] = getelementptr + // CHECK-NEXT: %[[DIM:.+]] = getelementptr + // CHECK-NEXT: %[[LAST:.+]] = load + // CHECK-NEXT: %[[FIRST:.+]] = shl + // CHECK-NEXT: call void @llvm.memmove + // CHECK-NEXT: store i32 %[[LAST]], ptr %[[DIM:.+]] + // CHECK-NOT: phi + // CHECK-NOT: call + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: getelementptr + // CHECK: ret void + if !slice.is_empty() { + slice.rotate_left(1); + } +} From 52519e145ef3496781fa049ea0edbe44a1bc206c Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 29 Jan 2025 19:47:59 +0100 Subject: [PATCH 59/71] Cleanup docs for Allocator --- library/core/src/alloc/mod.rs | 58 ++++++++++++++++------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index aa841db045c..dcab6136ae8 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -49,26 +49,26 @@ impl fmt::Display for AllocError { /// An implementation of `Allocator` can allocate, grow, shrink, and deallocate arbitrary blocks of /// data described via [`Layout`][]. /// -/// `Allocator` is designed to be implemented on ZSTs, references, or smart pointers because having -/// an allocator like `MyAlloc([u8; N])` cannot be moved, without updating the pointers to the +/// `Allocator` is designed to be implemented on ZSTs, references, or smart pointers. +/// An allocator for `MyAlloc([u8; N])` cannot be moved, without updating the pointers to the /// allocated memory. /// -/// Unlike [`GlobalAlloc`][], zero-sized allocations are allowed in `Allocator`. If an underlying -/// allocator does not support this (like jemalloc) or return a null pointer (such as -/// `libc::malloc`), this must be caught by the implementation. +/// In contrast to [`GlobalAlloc`][], `Allocator` allows zero-sized allocations. If an underlying +/// allocator does not support this (like jemalloc) or responds by returning a null pointer +/// (such as `libc::malloc`), this must be caught by the implementation. /// /// ### Currently allocated memory /// -/// Some of the methods require that a memory block be *currently allocated* via an allocator. This -/// means that: +/// Some of the methods require that a memory block is *currently allocated* by an allocator. +/// This means that: +/// * the starting address for that memory block was previously +/// returned by [`allocate`], [`grow`], or [`shrink`], and +/// * the memory block has not subsequently been deallocated. /// -/// * the starting address for that memory block was previously returned by [`allocate`], [`grow`], or -/// [`shrink`], and -/// -/// * the memory block has not been subsequently deallocated, where blocks are either deallocated -/// directly by being passed to [`deallocate`] or were changed by being passed to [`grow`] or -/// [`shrink`] that returns `Ok`. If `grow` or `shrink` have returned `Err`, the passed pointer -/// remains valid. +/// A memory block is deallocated by a call to [`deallocate`], +/// or by a call to [`grow`] or [`shrink`] that returns `Ok`. +/// A call to `grow` or `shrink` that returns `Err`, +/// does not deallocate the memory block passed to it. /// /// [`allocate`]: Allocator::allocate /// [`grow`]: Allocator::grow @@ -77,32 +77,28 @@ impl fmt::Display for AllocError { /// /// ### Memory fitting /// -/// Some of the methods require that a layout *fit* a memory block. What it means for a layout to -/// "fit" a memory block means (or equivalently, for a memory block to "fit" a layout) is that the +/// Some of the methods require that a `layout` *fit* a memory block or vice versa. This means that the /// following conditions must hold: -/// -/// * The block must be allocated with the same alignment as [`layout.align()`], and -/// -/// * The provided [`layout.size()`] must fall in the range `min ..= max`, where: -/// - `min` is the size of the layout most recently used to allocate the block, and -/// - `max` is the latest actual size returned from [`allocate`], [`grow`], or [`shrink`]. +/// * the memory block must be *currently allocated* with alignment of [`layout.align()`], and +/// * [`layout.size()`] must fall in the range `min ..= max`, where: +/// - `min` is the size of the layout used to allocate the block, and +/// - `max` is the actual size returned from [`allocate`], [`grow`], or [`shrink`]. /// /// [`layout.align()`]: Layout::align /// [`layout.size()`]: Layout::size /// /// # Safety /// -/// * Memory blocks returned from an allocator that are [*currently allocated*] must point to -/// valid memory and retain their validity while they are [*currently allocated*] and the shorter -/// of: -/// - the borrow-checker lifetime of the allocator type itself. -/// - as long as at least one of the instance and all of its clones has not been dropped. +/// Memory blocks that are [*currently allocated*] by an allocator, +/// must point to valid memory, and retain their validity while until either: +/// - the memory block is deallocated, or +/// - the allocator is dropped. /// -/// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this -/// allocator. A copied or cloned allocator must behave like the same allocator, and +/// Copying, cloning, or moving the allocator must not invalidate memory blocks returned from it +/// A copied or cloned allocator must behave like the original allocator. /// -/// * any pointer to a memory block which is [*currently allocated*] may be passed to any other -/// method of the allocator. +/// A memory block which is [*currently allocated*] may be passed to +/// any method of the allocator that accepts such an argument. /// /// [*currently allocated*]: #currently-allocated-memory #[unstable(feature = "allocator_api", issue = "32838")] From b320e1741c738363184c87657f972a739d704908 Mon Sep 17 00:00:00 2001 From: Sky Date: Wed, 29 Jan 2025 20:23:59 -0500 Subject: [PATCH 60/71] Remove minor future footgun in `impl Debug for MaybeUninit` No longer breaks if `MaybeUninit` moves modules (technically it could break if `MaybeUninit` were renamed but realistically that will never happen) --- library/core/src/mem/maybe_uninit.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index ac5307a671d..0d8c3ef906b 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -276,10 +276,9 @@ impl Clone for MaybeUninit { impl fmt::Debug for MaybeUninit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("MaybeUninit<{..}>"). - // This needs to be adjusted if `MaybeUninit` moves modules. let full_name = type_name::(); - let short_name = full_name.split_once("mem::maybe_uninit::").unwrap().1; - f.pad(short_name) + let prefix_len = full_name.find("MaybeUninit").unwrap(); + f.pad(&full_name[prefix_len..]) } } From 51eaa0d56aadeea9eb3a3c011189d20bf9333bc7 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sun, 19 Jan 2025 13:04:28 -0600 Subject: [PATCH 61/71] Clean up uses of the unstable `dwarf_version` option - Consolidate calculation of the effective value. - Check the target `DebuginfoKind` instead of using `is_like_msvc`. --- .../src/debuginfo/metadata.rs | 3 +- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 49 ++++++++++--------- compiler/rustc_session/src/options.rs | 1 + compiler/rustc_session/src/session.rs | 8 ++- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8d782a618fc..2a1a12f3ce5 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -919,8 +919,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( .unwrap_or_default(); let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo); - let dwarf_version = - tcx.sess.opts.unstable_opts.dwarf_version.unwrap_or(tcx.sess.target.default_dwarf_version); + let dwarf_version = tcx.sess.dwarf_version(); let is_dwarf_kind = matches!(tcx.sess.target.debuginfo_kind, DebuginfoKind::Dwarf | DebuginfoKind::DwarfDsym); // Don't emit `.debug_pubnames` and `.debug_pubtypes` on DWARFv4 or lower. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index e6778411365..5089560784a 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -22,6 +22,7 @@ use rustc_session::config::{self, DebugInfo}; use rustc_span::{ BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId, Symbol, }; +use rustc_target::spec::DebuginfoKind; use smallvec::SmallVec; use tracing::debug; @@ -93,29 +94,31 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { pub(crate) fn finalize(&self, sess: &Session) { unsafe { llvm::LLVMRustDIBuilderFinalize(self.builder) }; - if !sess.target.is_like_msvc { - // Debuginfo generation in LLVM by default uses a higher - // version of dwarf than macOS currently understands. We can - // instruct LLVM to emit an older version of dwarf, however, - // for macOS to understand. For more info see #11352 - // This can be overridden using --llvm-opts -dwarf-version,N. - // Android has the same issue (#22398) - let dwarf_version = - sess.opts.unstable_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version); - llvm::add_module_flag_u32( - self.llmod, - llvm::ModuleFlagMergeBehavior::Warning, - "Dwarf Version", - dwarf_version, - ); - } else { - // Indicate that we want CodeView debug information on MSVC - llvm::add_module_flag_u32( - self.llmod, - llvm::ModuleFlagMergeBehavior::Warning, - "CodeView", - 1, - ); + + match sess.target.debuginfo_kind { + DebuginfoKind::Dwarf | DebuginfoKind::DwarfDsym => { + // Debuginfo generation in LLVM by default uses a higher + // version of dwarf than macOS currently understands. We can + // instruct LLVM to emit an older version of dwarf, however, + // for macOS to understand. For more info see #11352 + // This can be overridden using --llvm-opts -dwarf-version,N. + // Android has the same issue (#22398) + llvm::add_module_flag_u32( + self.llmod, + llvm::ModuleFlagMergeBehavior::Warning, + "Dwarf Version", + sess.dwarf_version(), + ); + } + DebuginfoKind::Pdb => { + // Indicate that we want CodeView debug information + llvm::add_module_flag_u32( + self.llmod, + llvm::ModuleFlagMergeBehavior::Warning, + "CodeView", + 1, + ); + } } // Prevent bitcode readers from deleting the debug info. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 4ce63825129..c7af40a8ad4 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1803,6 +1803,7 @@ options! { "output statistics about monomorphization collection"), dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED], "the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"), + #[rustc_lint_opt_deny_field_access("use `Session::dwarf_version` instead of this field")] dwarf_version: Option = (None, parse_opt_number, [TRACKED], "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"), dylib_lto: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 1f03de3f53d..c0f5f0d4a9e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -732,6 +732,11 @@ impl Session { self.opts.cg.split_debuginfo.unwrap_or(self.target.split_debuginfo) } + /// Returns the DWARF version passed on the CLI or the default for the target. + pub fn dwarf_version(&self) -> u32 { + self.opts.unstable_opts.dwarf_version.unwrap_or(self.target.default_dwarf_version) + } + pub fn stack_protector(&self) -> StackProtector { if self.target.options.supports_stack_protector { self.opts.unstable_opts.stack_protector @@ -1263,8 +1268,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } if sess.opts.unstable_opts.embed_source { - let dwarf_version = - sess.opts.unstable_opts.dwarf_version.unwrap_or(sess.target.default_dwarf_version); + let dwarf_version = sess.dwarf_version(); if dwarf_version < 5 { sess.dcx().emit_warn(errors::EmbedSourceInsufficientDwarfVersion { dwarf_version }); From 4d5a63f8825e127040a078d3a81d7904a7cfb1ad Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sun, 19 Jan 2025 13:22:25 -0600 Subject: [PATCH 62/71] Add tracking issue to docs --- src/doc/unstable-book/src/compiler-flags/dwarf-version.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/unstable-book/src/compiler-flags/dwarf-version.md b/src/doc/unstable-book/src/compiler-flags/dwarf-version.md index c5e86f17df7..e88799d2cf0 100644 --- a/src/doc/unstable-book/src/compiler-flags/dwarf-version.md +++ b/src/doc/unstable-book/src/compiler-flags/dwarf-version.md @@ -1,5 +1,9 @@ ## `dwarf-version` +The tracking issue for this feature is: + +---------------------------- + This option controls the version of DWARF that the compiler emits, on platforms that use DWARF to encode debug information. It takes one of the following values: From fb1ad2fe02dc7d13b6a088b535bd8c293a8085be Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 30 Jan 2025 11:42:19 +0100 Subject: [PATCH 63/71] Improve documentation for file locking Add notes to each method stating that locks get dropped on close. Clarify the return values of the try methods: they're only defined if the lock is held via a *different* file handle/descriptor. That goes along with the documentation that calling them while holding a lock via the *same* file handle/descriptor may deadlock. Document the behavior of unlock if no lock is held. --- library/std/src/fs.rs | 57 ++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 1f8aac48a9a..a5b0111adfb 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -629,9 +629,9 @@ impl File { /// This acquires an exclusive advisory lock; no other file handle to this file may acquire /// another lock. /// - /// If this file handle, or a clone of it, already holds an advisory lock the exact behavior is - /// unspecified and platform dependent, including the possibility that it will deadlock. - /// However, if this method returns, then an exclusive lock is held. + /// If this file handle/descriptor, or a clone of it, already holds an advisory lock the exact + /// behavior is unspecified and platform dependent, including the possibility that it will + /// deadlock. However, if this method returns, then an exclusive lock is held. /// /// If the file not open for writing, it is unspecified whether this function returns an error. /// @@ -639,6 +639,9 @@ impl File { /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`] /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. /// + /// The lock will be released when this file (along with any other file descriptors/handles + /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. + /// /// # Platform-specific behavior /// /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` flag, @@ -671,19 +674,22 @@ impl File { self.inner.lock() } - /// Acquire a shared advisory lock on the file. Blocks until the lock can be acquired. + /// Acquire a shared (non-exclusive) advisory lock on the file. Blocks until the lock can be acquired. /// /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but - /// none may hold an exclusive lock. + /// none may hold an exclusive lock at the same time. /// - /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is - /// unspecified and platform dependent, including the possibility that it will deadlock. - /// However, if this method returns, then a shared lock is held. + /// If this file handle/descriptor, or a clone of it, already holds an advisory lock, the exact + /// behavior is unspecified and platform dependent, including the possibility that it will + /// deadlock. However, if this method returns, then a shared lock is held. /// /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`], /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`] /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. /// + /// The lock will be released when this file (along with any other file descriptors/handles + /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. + /// /// # Platform-specific behavior /// /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` flag, @@ -716,14 +722,18 @@ impl File { self.inner.lock_shared() } - /// Acquire an exclusive advisory lock on the file. Returns `Ok(false)` if the file is locked. + /// Try to acquire an exclusive advisory lock on the file. + /// + /// Returns `Ok(false)` if a different lock is already held on this file (via another + /// handle/descriptor). /// /// This acquires an exclusive advisory lock; no other file handle to this file may acquire /// another lock. /// - /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is - /// unspecified and platform dependent, including the possibility that it will deadlock. - /// However, if this method returns, then an exclusive lock is held. + /// If this file handle/descriptor, or a clone of it, already holds an advisory lock, the exact + /// behavior is unspecified and platform dependent, including the possibility that it will + /// deadlock. However, if this method returns `Ok(true)`, then it has acquired an exclusive + /// lock. /// /// If the file not open for writing, it is unspecified whether this function returns an error. /// @@ -731,6 +741,9 @@ impl File { /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`] /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. /// + /// The lock will be released when this file (along with any other file descriptors/handles + /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. + /// /// # Platform-specific behavior /// /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` and @@ -764,20 +777,25 @@ impl File { self.inner.try_lock() } - /// Acquire a shared advisory lock on the file. - /// Returns `Ok(false)` if the file is exclusively locked. + /// Try to acquire a shared (non-exclusive) advisory lock on the file. + /// + /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another + /// handle/descriptor). /// /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but - /// none may hold an exclusive lock. + /// none may hold an exclusive lock at the same time. /// /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is /// unspecified and platform dependent, including the possibility that it will deadlock. - /// However, if this method returns, then a shared lock is held. + /// However, if this method returns `Ok(true)`, then it has acquired a shared lock. /// /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`], /// [`try_lock`], and [`unlock`]. Its interactions with other methods, such as [`read`] /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. /// + /// The lock will be released when this file (along with any other file descriptors/handles + /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. + /// /// # Platform-specific behavior /// /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` and @@ -813,7 +831,12 @@ impl File { /// Release all locks on the file. /// - /// All remaining locks are released when the file handle, and all clones of it, are dropped. + /// All locks are released when the file (along with any other file descriptors/handles + /// duplicated or inherited from it) is closed. This method allows releasing locks without + /// closing the file. + /// + /// If no lock is currently held via this file descriptor/handle, this method may return an + /// error, or may return successfully without taking any action. /// /// # Platform-specific behavior /// From 10fc0b159ee6e5281bf38f65680082961dd7bec3 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Mon, 27 Jan 2025 04:30:00 +0100 Subject: [PATCH 64/71] introduce `ty::Value` Co-authored-by: FedericoBruzzone --- .../src/intrinsics/simd.rs | 7 +-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- .../src/debuginfo/type_names.rs | 16 +++--- .../rustc_codegen_ssa/src/mir/constant.rs | 2 +- .../src/check_consts/qualifs.rs | 2 +- compiler/rustc_const_eval/src/lib.rs | 9 +++- compiler/rustc_infer/src/infer/freshen.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 2 +- compiler/rustc_middle/src/mir/consts.rs | 22 ++++---- compiler/rustc_middle/src/mir/pretty.rs | 4 +- compiler/rustc_middle/src/query/keys.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 6 +-- compiler/rustc_middle/src/ty/consts.rs | 38 ++++---------- .../rustc_middle/src/ty/consts/valtree.rs | 51 ++++++++++++++++--- compiler/rustc_middle/src/ty/context.rs | 26 ++++++---- compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 51 +++++++++---------- .../rustc_middle/src/ty/structural_impls.rs | 18 +++---- compiler/rustc_middle/src/ty/walk.rs | 2 +- .../src/thir/pattern/const_to_pat.rs | 2 +- .../src/canonicalizer.rs | 2 +- .../rustc_next_trait_solver/src/solve/mod.rs | 6 +-- .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 22 ++++---- compiler/rustc_smir/src/rustc_smir/context.rs | 5 +- .../rustc_smir/src/rustc_smir/convert/ty.rs | 23 +++------ compiler/rustc_symbol_mangling/src/legacy.rs | 7 +-- compiler/rustc_symbol_mangling/src/v0.rs | 7 +-- .../src/solve/fulfill.rs | 2 +- .../src/traits/const_evaluatable.rs | 2 +- .../src/traits/fulfill.rs | 2 +- .../src/traits/select/mod.rs | 2 +- compiler/rustc_transmute/src/lib.rs | 8 +-- compiler/rustc_ty_utils/src/consts.rs | 6 +-- compiler/rustc_ty_utils/src/layout.rs | 19 +++---- compiler/rustc_type_ir/src/const_kind.rs | 4 +- compiler/rustc_type_ir/src/fast_reject.rs | 4 +- compiler/rustc_type_ir/src/inherent.rs | 5 ++ compiler/rustc_type_ir/src/interner.rs | 3 +- compiler/rustc_type_ir/src/relate.rs | 4 +- src/librustdoc/clean/utils.rs | 6 +-- .../clippy_lints/src/large_const_arrays.rs | 5 +- .../clippy_lints/src/large_stack_arrays.rs | 5 +- src/tools/miri/src/intrinsics/simd.rs | 2 +- 44 files changed, 214 insertions(+), 205 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 6d71b8e8aba..d682efd19aa 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -129,12 +129,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; } - let idx = generic_args[2] - .expect_const() - .try_to_valtree() - .expect("expected monomorphic const in codegen") - .0 - .unwrap_branch(); + let idx = generic_args[2].expect_const().to_value().valtree.unwrap_branch(); assert_eq!(x.layout(), y.layout()); let layout = x.layout(); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index eab4a9f30c9..43d6ccfcb4a 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1329,7 +1329,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_shuffle_generic { - let idx = fn_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch(); + let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch(); let n = idx.len() as u64; let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn); diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 869798d8be1..d766ae37e5b 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -673,25 +673,23 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S ty::ConstKind::Param(param) => { write!(output, "{}", param.name) } - ty::ConstKind::Value(ty, valtree) => { - match ty.kind() { + ty::ConstKind::Value(cv) => { + match cv.ty.kind() { ty::Int(ity) => { - // FIXME: directly extract the bits from a valtree instead of evaluating an - // already evaluated `Const` in order to get the bits. - let bits = ct + let bits = cv .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in codegen"); let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; write!(output, "{val}") } ty::Uint(_) => { - let val = ct + let val = cv .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in codegen"); write!(output, "{val}") } ty::Bool => { - let val = ct.try_to_bool().expect("expected monomorphic const in codegen"); + let val = cv.try_to_bool().expect("expected monomorphic const in codegen"); write!(output, "{val}") } _ => { @@ -703,9 +701,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S // avoiding collisions and will make the emitted type names shorter. let hash_short = tcx.with_stable_hashing_context(|mut hcx| { let mut hasher = StableHasher::new(); - hcx.while_hashing_spans(false, |hcx| { - (ty, valtree).hash_stable(hcx, &mut hasher) - }); + hcx.while_hashing_spans(false, |hcx| cv.hash_stable(hcx, &mut hasher)); hasher.finish::() }); diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 7676e1e171a..eafc551501c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -43,7 +43,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Const::Ty(_, c) => match c.kind() { // A constant that came from a const generic but was then used as an argument to // old-style simd_shuffle (passing as argument instead of as a generic param). - rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Ok(valtree)), + rustc_type_ir::ConstKind::Value(cv) => return Ok(Ok(cv.valtree)), other => span_bug!(constant.span, "{other:#?}"), }, // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index e244b50a4b5..5d368b600a0 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -345,7 +345,7 @@ where Const::Ty(_, ct) if matches!( ct.kind(), - ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_, _) + ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_) ) => { None diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index b5adf06b300..ecf9745b779 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -46,8 +46,13 @@ pub fn provide(providers: &mut Providers) { }; providers.hooks.try_destructure_mir_constant_for_user_output = const_eval::try_destructure_mir_constant_for_user_output; - providers.valtree_to_const_val = |tcx, (ty, valtree)| { - const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), ty, valtree) + providers.valtree_to_const_val = |tcx, cv| { + const_eval::valtree_to_const_value( + tcx, + ty::TypingEnv::fully_monomorphized(), + cv.ty, + cv.valtree, + ) }; providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| { util::check_validity_requirement(tcx, init_kind, param_env_and_ty) diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 28eac5b7496..74c8b463fc8 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -170,7 +170,7 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { } ty::ConstKind::Param(_) - | ty::ConstKind::Value(_, _) + | ty::ConstKind::Value(_) | ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) | ty::ConstKind::Error(_) => ct.super_fold_with(self), diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 283ebdfa236..515c9c34098 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1055,7 +1055,7 @@ impl<'tcx> InferCtxt<'tcx> { | ty::ConstKind::Bound(_, _) | ty::ConstKind::Placeholder(_) | ty::ConstKind::Unevaluated(_) - | ty::ConstKind::Value(_, _) + | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => ct, } diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 66d97fda433..923160cc0cc 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -250,7 +250,7 @@ impl<'tcx> Const<'tcx> { // Dont use the outer ty as on invalid code we can wind up with them not being the same. // this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir // was originally `({N: usize} + 1_usize)` under `generic_const_exprs`. - ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Value(cv) => cv.ty, _ => *ty, } } @@ -264,7 +264,7 @@ impl<'tcx> Const<'tcx> { pub fn is_required_const(&self) -> bool { match self { Const::Ty(_, c) => match c.kind() { - ty::ConstKind::Value(_, _) => false, // already a value, cannot error + ty::ConstKind::Value(_) => false, // already a value, cannot error _ => true, }, Const::Val(..) => false, // already a value, cannot error @@ -276,11 +276,11 @@ impl<'tcx> Const<'tcx> { pub fn try_to_scalar(self) -> Option { match self { Const::Ty(_, c) => match c.kind() { - ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => { + ty::ConstKind::Value(cv) if cv.ty.is_primitive() => { // A valtree of a type where leaves directly represent the scalar const value. // Just checking whether it is a leaf is insufficient as e.g. references are leafs // but the leaf value is the value they point to, not the reference itself! - Some(valtree.unwrap_leaf().into()) + Some(cv.valtree.unwrap_leaf().into()) } _ => None, }, @@ -295,9 +295,7 @@ impl<'tcx> Const<'tcx> { match self { Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x), Const::Ty(_, c) => match c.kind() { - ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => { - Some(valtree.unwrap_leaf()) - } + ty::ConstKind::Value(cv) if cv.ty.is_primitive() => Some(cv.valtree.unwrap_leaf()), _ => None, }, _ => None, @@ -328,7 +326,7 @@ impl<'tcx> Const<'tcx> { } match c.kind() { - ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))), + ConstKind::Value(cv) => Ok(tcx.valtree_to_const_val(cv)), ConstKind::Expr(_) => { bug!("Normalization of `ty::ConstKind::Expr` is unimplemented") } @@ -353,13 +351,13 @@ impl<'tcx> Const<'tcx> { typing_env: ty::TypingEnv<'tcx>, ) -> Option { if let Const::Ty(_, c) = self - && let ty::ConstKind::Value(ty, val) = c.kind() - && ty.is_primitive() + && let ty::ConstKind::Value(cv) = c.kind() + && cv.ty.is_primitive() { // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that // are valtree leaves, and *not* on references. (References should return the // pointer here, which valtrees don't represent.) - Some(val.unwrap_leaf().into()) + Some(cv.valtree.unwrap_leaf().into()) } else { self.eval(tcx, typing_env, DUMMY_SP).ok()?.try_to_scalar() } @@ -473,7 +471,7 @@ impl<'tcx> Const<'tcx> { // A valtree may be a reference. Valtree references correspond to a // different allocation each time they are evaluated. Valtrees for primitive // types are fine though. - ty::ConstKind::Value(ty, _) => ty.is_primitive(), + ty::ConstKind::Value(cv) => cv.ty.is_primitive(), ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) => false, // This can happen if evaluation of a constant failed. The result does not matter // much since compilation is doomed. diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 3b4fba97e60..a318bacb866 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1441,7 +1441,9 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { ty::ConstKind::Unevaluated(uv) => { format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,) } - ty::ConstKind::Value(_, val) => format!("ty::Valtree({})", fmt_valtree(&val)), + ty::ConstKind::Value(cv) => { + format!("ty::Valtree({})", fmt_valtree(&cv.valtree)) + } // No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`. ty::ConstKind::Error(_) => "Error".to_string(), // These variants shouldn't exist in the MIR. diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index e243425c0b7..f7090fa69e2 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -550,7 +550,7 @@ impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List>) { } } -impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { +impl<'tcx> Key for ty::Value<'tcx> { type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d83bc19a6a2..560e3bf3ade 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1256,9 +1256,9 @@ rustc_queries! { desc { "evaluating type-level constant" } } - /// Converts a type level constant value into `ConstValue` - query valtree_to_const_val(key: (Ty<'tcx>, ty::ValTree<'tcx>)) -> mir::ConstValue<'tcx> { - desc { "converting type-level constant value to mir constant value"} + /// Converts a type-level constant value into a MIR constant value. + query valtree_to_const_val(key: ty::Value<'tcx>) -> mir::ConstValue<'tcx> { + desc { "converting type-level constant value to MIR constant value"} } /// Destructures array, ADT or tuple constants into the constants diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 31055276422..6875532e28a 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -110,8 +110,8 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn new_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { - Const::new(tcx, ty::ConstKind::Value(ty, val)) + pub fn new_value(tcx: TyCtxt<'tcx>, valtree: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { + Const::new(tcx, ty::ConstKind::Value(ty::Value { ty, valtree })) } #[inline] @@ -214,47 +214,31 @@ impl<'tcx> Const<'tcx> { Self::from_bits(tcx, n as u128, ty::TypingEnv::fully_monomorphized(), tcx.types.usize) } - /// Panics if self.kind != ty::ConstKind::Value - pub fn to_valtree(self) -> (ty::ValTree<'tcx>, Ty<'tcx>) { + /// Panics if `self.kind != ty::ConstKind::Value`. + pub fn to_value(self) -> ty::Value<'tcx> { match self.kind() { - ty::ConstKind::Value(ty, valtree) => (valtree, ty), + ty::ConstKind::Value(cv) => cv, _ => bug!("expected ConstKind::Value, got {:?}", self.kind()), } } - /// Attempts to convert to a `ValTree` - pub fn try_to_valtree(self) -> Option<(ty::ValTree<'tcx>, Ty<'tcx>)> { + /// Attempts to convert to a value. + pub fn try_to_value(self) -> Option> { match self.kind() { - ty::ConstKind::Value(ty, valtree) => Some((valtree, ty)), + ty::ConstKind::Value(cv) => Some(cv), _ => None, } } #[inline] pub fn try_to_scalar(self) -> Option<(Scalar, Ty<'tcx>)> { - let (valtree, ty) = self.try_to_valtree()?; - Some((valtree.try_to_scalar()?, ty)) - } - - pub fn try_to_bool(self) -> Option { - self.try_to_valtree()?.0.try_to_scalar_int()?.try_to_bool().ok() + let cv = self.try_to_value()?; + Some((cv.valtree.try_to_scalar()?, cv.ty)) } #[inline] pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_valtree()?.0.try_to_target_usize(tcx) - } - - /// Attempts to evaluate the given constant to bits. Can fail to evaluate in the presence of - /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it - /// contains const generic parameters or pointers). - #[inline] - pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option { - let (scalar, ty) = self.try_to_scalar()?; - let scalar = scalar.try_to_scalar_int().ok()?; - let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty); - let size = tcx.layout_of(input).ok()?.size; - Some(scalar.to_bits(size)) + self.try_to_value()?.try_to_target_usize(tcx) } pub fn is_ct_infer(self) -> bool { diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 9f9bf41c335..425b68a951c 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -1,11 +1,9 @@ -use rustc_macros::{HashStable, TyDecodable, TyEncodable}; +use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use super::ScalarInt; use crate::mir::interpret::Scalar; use crate::ty::{self, Ty, TyCtxt}; -#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq)] -#[derive(HashStable)] /// This datastructure is used to represent the value of constants used in the type system. /// /// We explicitly choose a different datastructure from the way values are processed within @@ -18,6 +16,8 @@ use crate::ty::{self, Ty, TyCtxt}; /// /// `ValTree` does not have this problem with representation, as it only contains integers or /// lists of (nested) `ValTree`. +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +#[derive(HashStable, TyEncodable, TyDecodable)] pub enum ValTree<'tcx> { /// integers, `bool`, `char` are represented as scalars. /// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values @@ -79,10 +79,6 @@ impl<'tcx> ValTree<'tcx> { } } - pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int().map(|s| s.to_target_usize(tcx)) - } - /// Get the values inside the ValTree as a slice of bytes. This only works for /// constants with types &str, &[u8], or [u8; _]. pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx [u8]> { @@ -107,3 +103,44 @@ impl<'tcx> ValTree<'tcx> { ) } } + +/// A type-level constant value. +/// +/// Represents a typed, fully evaluated constant. +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +#[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)] +pub struct Value<'tcx> { + pub ty: Ty<'tcx>, + pub valtree: ValTree<'tcx>, +} + +impl<'tcx> Value<'tcx> { + /// Attempts to extract the raw bits from the constant. + /// + /// Fails if the value can't be represented as bits (e.g. because it is an aggregate). + #[inline] + pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option { + let scalar = self.valtree.try_to_scalar_int()?; + let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty); + let size = tcx.layout_of(input).ok()?.size; + Some(scalar.to_bits(size)) + } + + pub fn try_to_bool(self) -> Option { + self.valtree.try_to_scalar_int()?.try_to_bool().ok() + } + + pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + self.valtree.try_to_scalar_int().map(|s| s.to_target_usize(tcx)) + } +} + +impl<'tcx> rustc_type_ir::inherent::ValueConst> for Value<'tcx> { + fn ty(self) -> Ty<'tcx> { + self.ty + } + + fn valtree(self) -> ValTree<'tcx> { + self.valtree + } +} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0c22c056dab..69f6fc0ad8a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -142,10 +142,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ParamConst = ty::ParamConst; type BoundConst = ty::BoundVar; - type ValueConst = ty::ValTree<'tcx>; + type ValueConst = ty::Value<'tcx>; type ExprConst = ty::Expr<'tcx>; - type Region = Region<'tcx>; + type ValTree = ty::ValTree<'tcx>; + type Region = Region<'tcx>; type EarlyParamRegion = ty::EarlyParamRegion; type LateParamRegion = ty::LateParamRegion; type BoundRegion = ty::BoundRegion; @@ -1118,15 +1119,18 @@ impl<'tcx> CommonConsts<'tcx> { }; CommonConsts { - unit: mk_const(ty::ConstKind::Value(types.unit, ty::ValTree::zst())), - true_: mk_const(ty::ConstKind::Value( - types.bool, - ty::ValTree::Leaf(ty::ScalarInt::TRUE), - )), - false_: mk_const(ty::ConstKind::Value( - types.bool, - ty::ValTree::Leaf(ty::ScalarInt::FALSE), - )), + unit: mk_const(ty::ConstKind::Value(ty::Value { + ty: types.unit, + valtree: ty::ValTree::zst(), + })), + true_: mk_const(ty::ConstKind::Value(ty::Value { + ty: types.bool, + valtree: ty::ValTree::Leaf(ty::ScalarInt::TRUE), + })), + false_: mk_const(ty::ConstKind::Value(ty::Value { + ty: types.bool, + valtree: ty::ValTree::Leaf(ty::ScalarInt::FALSE), + })), } } } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 0af57f636aa..ec0498b168c 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -381,7 +381,7 @@ impl FlagComputation { self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER); self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } - ty::ConstKind::Value(ty, _) => self.add_ty(ty), + ty::ConstKind::Value(cv) => self.add_ty(cv.ty), ty::ConstKind::Expr(e) => self.add_args(e.args()), ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8cd632790a8..88eea6101b5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -60,7 +60,7 @@ pub use self::closure::{ place_to_string_for_capture, }; pub use self::consts::{ - Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, + Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, Value, }; pub use self::context::{ CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 027a4315b4b..19a39b3a29e 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1484,8 +1484,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { _ => write!(self, "_")?, }, ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)), - ty::ConstKind::Value(ty, value) => { - return self.pretty_print_const_valtree(value, ty, print_ty); + ty::ConstKind::Value(cv) => { + return self.pretty_print_const_valtree(cv.valtree, cv.ty, print_ty); } ty::ConstKind::Bound(debruijn, bound_var) => { @@ -1637,33 +1637,32 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { match ty.kind() { // Byte strings (&[u8; N]) ty::Ref(_, inner, _) => { - if let ty::Array(elem, len) = inner.kind() { - if let ty::Uint(ty::UintTy::U8) = elem.kind() { - if let ty::ConstKind::Value(_, ty::ValTree::Leaf(int)) = len.kind() { - match self.tcx().try_get_global_alloc(prov.alloc_id()) { - Some(GlobalAlloc::Memory(alloc)) => { - let len = int.to_bits(self.tcx().data_layout.pointer_size); - let range = - AllocRange { start: offset, size: Size::from_bytes(len) }; - if let Ok(byte_str) = - alloc.inner().get_bytes_strip_provenance(&self.tcx(), range) - { - p!(pretty_print_byte_str(byte_str)) - } else { - p!("") - } - } - // FIXME: for statics, vtables, and functions, we could in principle print more detail. - Some(GlobalAlloc::Static(def_id)) => { - p!(write("", def_id)) - } - Some(GlobalAlloc::Function { .. }) => p!(""), - Some(GlobalAlloc::VTable(..)) => p!(""), - None => p!(""), + if let ty::Array(elem, len) = inner.kind() + && let ty::Uint(ty::UintTy::U8) = elem.kind() + && let ty::ConstKind::Value(cv) = len.kind() + && let ty::ValTree::Leaf(int) = cv.valtree + { + match self.tcx().try_get_global_alloc(prov.alloc_id()) { + Some(GlobalAlloc::Memory(alloc)) => { + let len = int.to_bits(self.tcx().data_layout.pointer_size); + let range = AllocRange { start: offset, size: Size::from_bytes(len) }; + if let Ok(byte_str) = + alloc.inner().get_bytes_strip_provenance(&self.tcx(), range) + { + p!(pretty_print_byte_str(byte_str)) + } else { + p!("") } - return Ok(()); } + // FIXME: for statics, vtables, and functions, we could in principle print more detail. + Some(GlobalAlloc::Static(def_id)) => { + p!(write("", def_id)) + } + Some(GlobalAlloc::Function { .. }) => p!(""), + Some(GlobalAlloc::VTable(..)) => p!(""), + None => p!(""), } + return Ok(()); } } ty::FnPtr(..) => { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 68cb56f3583..9e9de4fb064 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -162,16 +162,15 @@ impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> { impl<'tcx> fmt::Debug for ty::Const<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // If this is a value, we spend some effort to make it look nice. - if let ConstKind::Value(_, _) = self.kind() { + if let ConstKind::Value(_) = self.kind() { return ty::tls::with(move |tcx| { - // Somehow trying to lift the valtree results in lifetime errors, so we lift the - // entire constant. + // ValTrees aren't interned, so we lift the entire constant. let lifted = tcx.lift(*self).unwrap(); - let ConstKind::Value(ty, valtree) = lifted.kind() else { + let ConstKind::Value(cv) = lifted.kind() else { bug!("we checked that this is a valtree") }; let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS); - cx.pretty_print_const_valtree(valtree, ty, /*print_ty*/ true)?; + cx.pretty_print_const_valtree(cv.valtree, cv.ty, /*print_ty*/ true)?; f.write_str(&cx.into_buffer()) }); } @@ -589,9 +588,7 @@ impl<'tcx> TypeSuperFoldable> for ty::Const<'tcx> { } ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?), ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?), - ConstKind::Value(t, v) => { - ConstKind::Value(t.try_fold_with(folder)?, v.try_fold_with(folder)?) - } + ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?), ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?), ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?), }; @@ -610,10 +607,7 @@ impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { } ConstKind::Placeholder(p) => p.visit_with(visitor), ConstKind::Unevaluated(uv) => uv.visit_with(visitor), - ConstKind::Value(t, v) => { - try_visit!(t.visit_with(visitor)); - v.visit_with(visitor) - } + ConstKind::Value(v) => v.visit_with(visitor), ConstKind::Error(e) => e.visit_with(visitor), ConstKind::Expr(e) => e.visit_with(visitor), } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 2dcba8c2f82..3e8a3d1a289 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -206,7 +206,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Bound(..) | ty::ConstKind::Error(_) => {} - ty::ConstKind::Value(ty, _) => stack.push(ty.into()), + ty::ConstKind::Value(cv) => stack.push(cv.ty.into()), ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()), ty::ConstKind::Unevaluated(ct) => { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 3853b95f78b..c490e3885d4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { match c.kind() { ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty), - ty::ConstKind::Value(_, val) => convert.valtree_to_pat(val, ty), + ty::ConstKind::Value(cv) => convert.valtree_to_pat(cv.valtree, cv.ty), _ => span_bug!(span, "Invalid `ConstKind` for `const_to_pat`: {:?}", c), } } diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 62a7c84bc28..7eeed721d5a 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -522,7 +522,7 @@ impl, I: Interner> TypeFolder for Canonicaliz // FIXME: See comment above -- we could fold the region separately or something. ty::ConstKind::Bound(_, _) | ty::ConstKind::Unevaluated(_) - | ty::ConstKind::Value(_, _) + | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => return c.super_fold_with(self), }; diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 8d1194ee539..1fa35b60304 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -160,9 +160,7 @@ where ty::ConstKind::Infer(_) => { self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } - ty::ConstKind::Placeholder(_) - | ty::ConstKind::Value(_, _) - | ty::ConstKind::Error(_) => { + ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } // We can freely ICE here as: @@ -199,7 +197,7 @@ where unreachable!("`ConstKind::Param` should have been canonicalized to `Placeholder`") } ty::ConstKind::Bound(_, _) => panic!("escaping bound vars in {:?}", ct), - ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Value(cv) => cv.ty(), ty::ConstKind::Placeholder(placeholder) => { self.cx().find_const_ty_from_env(goal.param_env, placeholder) } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 09648e28df4..5f0c1afdf64 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -103,7 +103,7 @@ fn encode_args<'tcx>( /// ). fn encode_const<'tcx>( tcx: TyCtxt<'tcx>, - c: Const<'tcx>, + ct: Const<'tcx>, ct_ty: Ty<'tcx>, dict: &mut FxHashMap, usize>, options: EncodeTyOptions, @@ -111,7 +111,7 @@ fn encode_const<'tcx>( // L[n][]E as literal argument let mut s = String::from('L'); - match c.kind() { + match ct.kind() { // Const parameters ty::ConstKind::Param(..) => { // LE as literal argument @@ -121,18 +121,18 @@ fn encode_const<'tcx>( } // Literal arguments - ty::ConstKind::Value(ct_ty, ..) => { + ty::ConstKind::Value(cv) => { // L[n]E as literal argument // Element type - s.push_str(&encode_ty(tcx, ct_ty, dict, options)); + s.push_str(&encode_ty(tcx, cv.ty, dict, options)); // The only allowed types of const values are bool, u8, u16, u32, // u64, u128, usize i8, i16, i32, i64, i128, isize, and char. The // bool value false is encoded as 0 and true as 1. - match ct_ty.kind() { + match cv.ty.kind() { ty::Int(ity) => { - let bits = c + let bits = cv .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in cfi"); let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128; @@ -142,30 +142,30 @@ fn encode_const<'tcx>( let _ = write!(s, "{val}"); } ty::Uint(_) => { - let val = c + let val = cv .try_to_bits(tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected monomorphic const in cfi"); let _ = write!(s, "{val}"); } ty::Bool => { - let val = c.try_to_bool().expect("expected monomorphic const in cfi"); + let val = cv.try_to_bool().expect("expected monomorphic const in cfi"); let _ = write!(s, "{val}"); } _ => { - bug!("encode_const: unexpected type `{:?}`", ct_ty); + bug!("encode_const: unexpected type `{:?}`", cv.ty); } } } _ => { - bug!("encode_const: unexpected kind `{:?}`", c.kind()); + bug!("encode_const: unexpected kind `{:?}`", ct.kind()); } } // Close the "L..E" pair s.push('E'); - compress(dict, DictKey::Const(c), &mut s); + compress(dict, DictKey::Const(ct), &mut s); s } diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 31c7e6c3eb4..8d4e55dc036 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -450,8 +450,9 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let ty = ty::Ty::new_static_str(tcx); let bytes = value.as_bytes(); - let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes); - let val = tcx.valtree_to_const_val((ty, val_tree)); + let valtree = ty::ValTree::from_raw_bytes(tcx, bytes); + let cv = ty::Value { ty, valtree }; + let val = tcx.valtree_to_const_val(cv); mir::Const::from_value(val, ty).stable(&mut tables) } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index ff452eea23d..a2d95f0f693 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -418,23 +418,16 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { type T = stable_mir::ty::TyConst; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - let kind = match self.kind() { - ty::ConstKind::Value(ty, val) => { - let val = match val { - ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar), - ty::ValTree::Branch(branch) => { - ty::ValTree::Branch(tables.tcx.lift(branch).unwrap()) - } - }; - - let ty = tables.tcx.lift(ty).unwrap(); - let const_val = tables.tcx.valtree_to_const_val((ty, val)); + let ct = tables.tcx.lift(*self).unwrap(); + let kind = match ct.kind() { + ty::ConstKind::Value(cv) => { + let const_val = tables.tcx.valtree_to_const_val(cv); if matches!(const_val, mir::ConstValue::ZeroSized) { - stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables)) + stable_mir::ty::TyConstKind::ZSTValue(cv.ty.stable(tables)) } else { stable_mir::ty::TyConstKind::Value( - ty.stable(tables), - alloc::new_allocation(ty, const_val, tables), + cv.ty.stable(tables), + alloc::new_allocation(cv.ty, const_val, tables), ) } } @@ -449,7 +442,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { ty::ConstKind::Placeholder(_) => unimplemented!(), ty::ConstKind::Expr(_) => unimplemented!(), }; - let id = tables.intern_ty_const(tables.tcx.lift(*self).unwrap()); + let id = tables.intern_ty_const(ct); stable_mir::ty::TyConst::new(kind, id) } } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 879f3fac21f..8ae35572d01 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -274,14 +274,15 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> { fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> { // only print integers match ct.kind() { - ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar)) if ty.is_integral() => { + ty::ConstKind::Value(cv) if cv.ty.is_integral() => { // The `pretty_print_const` formatting depends on -Zverbose-internals // flag, so we cannot reuse it here. - let signed = matches!(ty.kind(), ty::Int(_)); + let scalar = cv.valtree.unwrap_leaf(); + let signed = matches!(cv.ty.kind(), ty::Int(_)); write!( self, "{:#?}", - ty::ConstInt::new(scalar, signed, ty.is_ptr_sized_integral()) + ty::ConstInt::new(scalar, signed, cv.ty.is_ptr_sized_integral()) )?; } _ => self.write_str("_")?, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 4ddf530a00d..5b3272feecd 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -590,8 +590,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> { // We only mangle a typed value if the const can be evaluated. - let (ct_ty, valtree) = match ct.kind() { - ty::ConstKind::Value(ty, val) => (ty, val), + let cv = match ct.kind() { + ty::ConstKind::Value(cv) => cv, // Should only be encountered within the identity-substituted // impl header of an item nested within an impl item. @@ -619,13 +619,14 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { return Ok(()); } + let ty::Value { ty: ct_ty, valtree } = cv; let start = self.out.len(); match ct_ty.kind() { ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => { ct_ty.print(self)?; - let mut bits = ct + let mut bits = cv .try_to_bits(self.tcx, ty::TypingEnv::fully_monomorphized()) .expect("expected const to be monomorphic"); diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 2b7da4bc5ff..c8ae977b5ad 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -264,7 +264,7 @@ fn fulfillment_error_for_no_solution<'tcx>( infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) } ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(obligation.param_env), - ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Value(cv) => cv.ty, kind => span_bug!( obligation.cause.span, "ConstArgHasWrongType failed but we don't know how to compute type for {kind:?}" diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 446f9eaa348..bdee6ca2afe 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -35,7 +35,7 @@ pub fn is_const_evaluatable<'tcx>( ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Placeholder(_) - | ty::ConstKind::Value(_, _) + | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => return Ok(()), ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer), }; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 7529ee128f5..f2d2dd2f3ce 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -479,7 +479,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::ConstKind::Error(_) => { return ProcessResult::Changed(PendingPredicateObligations::new()); } - ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Value(cv) => cv.ty, ty::ConstKind::Unevaluated(uv) => { infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6b6e0b32385..99ce1fd9fb4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -962,7 +962,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Ok(EvaluatedToAmbig); } ty::ConstKind::Error(_) => return Ok(EvaluatedToOk), - ty::ConstKind::Value(ty, _) => ty, + ty::ConstKind::Value(cv) => cv.ty, ty::ConstKind::Unevaluated(uv) => { self.tcx().type_of(uv.def).instantiate(self.tcx(), uv.args) } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index ad86813c87e..a50cc8f5932 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -128,16 +128,16 @@ mod rustc { pub fn from_const<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, - c: Const<'tcx>, + ct: Const<'tcx>, ) -> Option { use rustc_middle::ty::ScalarInt; use rustc_span::sym; - let Some((cv, ty)) = c.try_to_valtree() else { + let Some(cv) = ct.try_to_value() else { return None; }; - let adt_def = ty.ty_adt_def()?; + let adt_def = cv.ty.ty_adt_def()?; assert_eq!( tcx.require_lang_item(LangItem::TransmuteOpts, None), @@ -147,7 +147,7 @@ mod rustc { ); let variant = adt_def.non_enum_variant(); - let fields = match cv { + let fields = match cv.valtree { ValTree::Branch(branch) => branch, _ => { return Some(Self { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 51a7c976f60..931c36137ee 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -22,16 +22,16 @@ fn destructure_const<'tcx>( tcx: TyCtxt<'tcx>, const_: ty::Const<'tcx>, ) -> ty::DestructuredConst<'tcx> { - let ty::ConstKind::Value(ct_ty, valtree) = const_.kind() else { + let ty::ConstKind::Value(cv) = const_.kind() else { bug!("cannot destructure constant {:?}", const_) }; - let branches = match valtree { + let branches = match cv.valtree { ty::ValTree::Branch(b) => b, _ => bug!("cannot destructure constant {:?}", const_), }; - let (fields, variant) = match ct_ty.kind() { + let (fields, variant) = match cv.ty.kind() { ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { // construct the consts for the elements of the array/slice let field_consts = branches diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index a04c7536118..2f258b23f2d 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -144,13 +144,13 @@ fn univariant_uninterned<'tcx>( cx.calc.univariant(fields, repr, kind).map_err(|err| map_error(cx, ty, err)) } -fn validate_const_with_value<'tcx>( +fn extract_const_value<'tcx>( const_: ty::Const<'tcx>, ty: Ty<'tcx>, cx: &LayoutCx<'tcx>, -) -> Result, &'tcx LayoutError<'tcx>> { +) -> Result, &'tcx LayoutError<'tcx>> { match const_.kind() { - ty::ConstKind::Value(..) => Ok(const_), + ty::ConstKind::Value(cv) => Ok(cv), ty::ConstKind::Error(guar) => { return Err(error(cx, LayoutError::ReferencesError(guar))); } @@ -209,13 +209,12 @@ fn layout_of_uncached<'tcx>( &mut layout.backend_repr { if let Some(start) = start { - scalar.valid_range_mut().start = - validate_const_with_value(start, ty, cx)? - .try_to_bits(tcx, cx.typing_env) - .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + scalar.valid_range_mut().start = extract_const_value(start, ty, cx)? + .try_to_bits(tcx, cx.typing_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; } if let Some(end) = end { - let mut end = validate_const_with_value(end, ty, cx)? + let mut end = extract_const_value(end, ty, cx)? .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; if !include_end { @@ -348,9 +347,7 @@ fn layout_of_uncached<'tcx>( // Arrays and slices. ty::Array(element, count) => { - let count = validate_const_with_value(count, ty, cx)? - .to_valtree() - .0 + let count = extract_const_value(count, ty, cx)? .try_to_target_usize(tcx) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 03dfe547ced..aafc0907ae1 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -31,7 +31,7 @@ pub enum ConstKind { Unevaluated(ty::UnevaluatedConst), /// Used to hold computed value. - Value(I::Ty, I::ValueConst), + Value(I::ValueConst), /// A placeholder for a const which could not be computed; this is /// propagated to avoid useless error messages. @@ -52,7 +52,7 @@ impl fmt::Debug for ConstKind { Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var), Placeholder(placeholder) => write!(f, "{placeholder:?}"), Unevaluated(uv) => write!(f, "{uv:?}"), - Value(ty, valtree) => write!(f, "({valtree:?}: {ty:?})"), + Value(val) => write!(f, "{val:?}"), Error(_) => write!(f, "{{const error}}"), Expr(expr) => write!(f, "{expr:?}"), } diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index 9b3ff14d507..9955e92b55a 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -483,8 +483,8 @@ impl match rhs.kind() { - ty::ConstKind::Value(_, rhs_val) => lhs_val == rhs_val, + ty::ConstKind::Value(lhs_val) => match rhs.kind() { + ty::ConstKind::Value(rhs_val) => lhs_val.valtree() == rhs_val.valtree(), _ => false, }, diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 872cf668018..4e6d645e6fa 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -286,6 +286,11 @@ pub trait Const>: } } +pub trait ValueConst>: Copy + Debug + Hash + Eq { + fn ty(self) -> I::Ty; + fn valtree(self) -> I::ValTree; +} + pub trait ExprConst>: Copy + Debug + Hash + Eq + Relate { fn args(self) -> I::GenericArgs; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 0c3b0758f0f..a6c72da0c56 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -112,8 +112,9 @@ pub trait Interner: type PlaceholderConst: PlaceholderLike; type ParamConst: Copy + Debug + Hash + Eq + ParamLike; type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike; - type ValueConst: Copy + Debug + Hash + Eq; + type ValueConst: ValueConst; type ExprConst: ExprConst; + type ValTree: Copy + Debug + Hash + Eq; // Kinds of regions type Region: Region; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index e628b66d2f0..5b696ee5ed4 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -606,7 +606,9 @@ pub fn structurally_relate_consts>( true } (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2, - (ty::ConstKind::Value(_, a_val), ty::ConstKind::Value(_, b_val)) => a_val == b_val, + (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => { + a_val.valtree() == b_val.valtree() + } // While this is slightly incorrect, it shouldn't matter for `min_const_generics` // and is the better alternative to waiting until `generic_const_exprs` can diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 77040aeb94d..0b4fd9c2258 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -344,10 +344,8 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { s } // array lengths are obviously usize - ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar)) - if *ty.kind() == ty::Uint(ty::UintTy::Usize) => - { - scalar.to_string() + ty::ConstKind::Value(cv) if *cv.ty.kind() == ty::Uint(ty::UintTy::Usize) => { + cv.valtree.unwrap_leaf().to_string() } _ => n.to_string(), } diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 623b6b4fcc1..cabf10b7e0e 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -56,9 +56,8 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { && !item.span.from_expansion() && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let ty::Array(element_type, cst) = ty.kind() - && let Some((ty::ValTree::Leaf(element_count), _)) = cx.tcx - .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_valtree() - && let element_count = element_count.to_target_usize(cx.tcx) + && let Some(element_count) = cx.tcx + .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size) { diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 46d7df6995a..6f5c5d6b3ea 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -8,7 +8,7 @@ use clippy_utils::source::snippet; use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, ConstKind}; +use rustc_middle::ty; use rustc_session::impl_lint_pass; use rustc_span::{Span, sym}; @@ -81,8 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { && let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind && !self.is_from_vec_macro(cx, expr.span) && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() - && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() - && let element_count = element_count.to_target_usize(cx.tcx) + && let Some(element_count) = cst.try_to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { matches!( diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index 54bdd3f02c2..63a61dcd148 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -640,7 +640,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (dest, dest_len) = this.project_to_simd(dest)?; let index = - generic_args[2].expect_const().try_to_valtree().unwrap().0.unwrap_branch(); + generic_args[2].expect_const().to_value().valtree.unwrap_branch(); let index_len = index.len(); assert_eq!(left_len, right_len); From 0055fb92db2fcfb8c74d1bf9063f14f65d5dcce0 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Mon, 27 Jan 2025 11:16:19 +0000 Subject: [PATCH 65/71] check the types in `ty::Value` to value conversion and remove `ty::Const::try_to_scalar` because it becomes redundant --- compiler/rustc_middle/src/ty/consts.rs | 7 --- .../rustc_middle/src/ty/consts/valtree.rs | 12 +++++- .../cfi/typeid/itanium_cxx_abi/transform.rs | 10 ++++- .../src/error_reporting/infer/mod.rs | 10 ++--- tests/crashes/131102.rs | 4 -- tests/ui/consts/bad-array-size-in-type-err.rs | 11 +++++ .../consts/bad-array-size-in-type-err.stderr | 43 ++++++++++++++++++- 7 files changed, 75 insertions(+), 22 deletions(-) delete mode 100644 tests/crashes/131102.rs diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 6875532e28a..4ad5d8443b2 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -5,7 +5,6 @@ use rustc_error_messages::MultiSpan; use rustc_macros::HashStable; use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo}; -use crate::mir::interpret::Scalar; use crate::ty::{self, Ty, TyCtxt}; mod int; @@ -230,12 +229,6 @@ impl<'tcx> Const<'tcx> { } } - #[inline] - pub fn try_to_scalar(self) -> Option<(Scalar, Ty<'tcx>)> { - let cv = self.try_to_value()?; - Some((cv.valtree.try_to_scalar()?, cv.ty)) - } - #[inline] pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { self.try_to_value()?.try_to_target_usize(tcx) diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 425b68a951c..d914b7576dc 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -117,9 +117,13 @@ pub struct Value<'tcx> { impl<'tcx> Value<'tcx> { /// Attempts to extract the raw bits from the constant. /// - /// Fails if the value can't be represented as bits (e.g. because it is an aggregate). + /// Fails if the value can't be represented as bits (e.g. because it is a reference + /// or an aggregate). #[inline] pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option { + let (ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Float(_)) = self.ty.kind() else { + return None; + }; let scalar = self.valtree.try_to_scalar_int()?; let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty); let size = tcx.layout_of(input).ok()?.size; @@ -127,10 +131,16 @@ impl<'tcx> Value<'tcx> { } pub fn try_to_bool(self) -> Option { + if !self.ty.is_bool() { + return None; + } self.valtree.try_to_scalar_int()?.try_to_bool().ok() } pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + if !self.ty.is_usize() { + return None; + } self.valtree.try_to_scalar_int().map(|s| s.to_target_usize(tcx)) } } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 9c6186d6882..b711c238d59 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -51,8 +51,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { // Transforms a ty:Ty for being encoded and used in the substitution dictionary. fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match t.kind() { - ty::Array(..) - | ty::Closure(..) + ty::Closure(..) | ty::Coroutine(..) | ty::CoroutineClosure(..) | ty::CoroutineWitness(..) @@ -67,6 +66,13 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { | ty::Tuple(..) | ty::UnsafeBinder(_) => t.super_fold_with(self), + // Don't transform the type of the array length and keep it as `usize`. + // This is required for `try_to_target_usize` to work correctly. + &ty::Array(inner, len) => { + let inner = self.fold_ty(inner); + Ty::new_array_with_const_len(self.tcx, inner, len) + } + ty::Bool => { if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { // Note: on all platforms that Rust's currently supports, its size and alignment diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 9eacd377361..117b6a76425 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2023,14 +2023,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => None, }; if let Some(tykind) = tykind - && let hir::TyKind::Array(_, length) = tykind - && let Some((scalar, ty)) = sz.found.try_to_scalar() - && ty == self.tcx.types.usize + && let hir::TyKind::Array(_, length_arg) = tykind + && let Some(length_val) = sz.found.try_to_target_usize(self.tcx) { - let span = length.span(); Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { - span, - length: scalar.to_target_usize(&self.tcx).unwrap(), + span: length_arg.span(), + length: length_val, }) } else { None diff --git a/tests/crashes/131102.rs b/tests/crashes/131102.rs deleted file mode 100644 index 12b35f8d1b2..00000000000 --- a/tests/crashes/131102.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #131102 -pub struct Blorb([String; N]); -pub struct Wrap(Blorb<0>); -pub const fn i(_: Wrap) {} diff --git a/tests/ui/consts/bad-array-size-in-type-err.rs b/tests/ui/consts/bad-array-size-in-type-err.rs index cb02ad3205d..0490a9d3620 100644 --- a/tests/ui/consts/bad-array-size-in-type-err.rs +++ b/tests/ui/consts/bad-array-size-in-type-err.rs @@ -8,3 +8,14 @@ fn main() { //~^ ERROR mismatched types //~| ERROR the constant `2` is not of type `usize` } + +fn iter(val: BadArraySize::<2>) { + for _ in val.arr {} + //~^ ERROR the constant `2` is not of type `usize` + //~| ERROR `[i32; 2]` is not an iterator +} + +// issue #131102 +pub struct Blorb([String; N]); //~ ERROR the constant `N` is not of type `usize` +pub struct Wrap(Blorb<0>); +pub const fn i(_: Wrap) {} //~ ERROR destructor of `Wrap` cannot be evaluated at compile-time diff --git a/tests/ui/consts/bad-array-size-in-type-err.stderr b/tests/ui/consts/bad-array-size-in-type-err.stderr index c3ff216432e..84e16f8d931 100644 --- a/tests/ui/consts/bad-array-size-in-type-err.stderr +++ b/tests/ui/consts/bad-array-size-in-type-err.stderr @@ -6,6 +6,14 @@ LL | arr: [i32; N], | = note: the length of array `[i32; N]` must be type `usize` +error: the constant `N` is not of type `usize` + --> $DIR/bad-array-size-in-type-err.rs:19:32 + | +LL | pub struct Blorb([String; N]); + | ^^^^^^^^^^^ expected `usize`, found `u16` + | + = note: the length of array `[String; N]` must be type `usize` + error[E0308]: mismatched types --> $DIR/bad-array-size-in-type-err.rs:7:38 | @@ -20,6 +28,37 @@ LL | let _ = BadArraySize::<2> { arr: [0, 0, 0] }; | = note: the length of array `[i32; 2]` must be type `usize` -error: aborting due to 3 previous errors +error: the constant `2` is not of type `usize` + --> $DIR/bad-array-size-in-type-err.rs:13:14 + | +LL | for _ in val.arr {} + | ^^^^^^^ expected `usize`, found `u8` + | + = note: the length of array `[i32; 2]` must be type `usize` -For more information about this error, try `rustc --explain E0308`. +error[E0277]: `[i32; 2]` is not an iterator + --> $DIR/bad-array-size-in-type-err.rs:13:14 + | +LL | for _ in val.arr {} + | ^^^^^^^ `[i32; 2]` is not an iterator; try calling `.into_iter()` or `.iter()` + | + = help: the trait `IntoIterator` is not implemented for `[i32; 2]` + = help: the following other types implement trait `IntoIterator`: + &[T; N] + &[T] + &mut [T; N] + &mut [T] + [T; N] + +error[E0493]: destructor of `Wrap` cannot be evaluated at compile-time + --> $DIR/bad-array-size-in-type-err.rs:21:16 + | +LL | pub const fn i(_: Wrap) {} + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0277, E0308, E0493. +For more information about an error, try `rustc --explain E0277`. From ca3ff832e34cc32d93c9e940d8f6d3e4034203fa Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Thu, 30 Jan 2025 17:22:45 +0100 Subject: [PATCH 66/71] add comments --- compiler/rustc_const_eval/src/const_eval/valtrees.rs | 3 ++- compiler/rustc_middle/src/ty/consts.rs | 6 ++++++ compiler/rustc_middle/src/ty/print/pretty.rs | 1 + compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 4ff8aa9a3b4..4d625f76aba 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -272,7 +272,8 @@ pub(crate) fn eval_to_valtree<'tcx>( /// Converts a `ValTree` to a `ConstValue`, which is needed after mir /// construction has finished. -// FIXME Merge `valtree_to_const_value` and `valtree_into_mplace` into one function +// FIXME(valtrees): Merge `valtree_to_const_value` and `valtree_into_mplace` into one function +// FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately. #[instrument(skip(tcx), level = "debug", ret)] pub fn valtree_to_const_value<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 4ad5d8443b2..d77fb1cc91e 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -222,6 +222,8 @@ impl<'tcx> Const<'tcx> { } /// Attempts to convert to a value. + /// + /// Note that this does not evaluate the constant. pub fn try_to_value(self) -> Option> { match self.kind() { ty::ConstKind::Value(cv) => Some(cv), @@ -229,6 +231,10 @@ impl<'tcx> Const<'tcx> { } } + /// Convenience method to extract the value of a usize constant, + /// useful to get the length of an array type. + /// + /// Note that this does not evaluate the constant. #[inline] pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { self.try_to_value()?.try_to_target_usize(tcx) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 19a39b3a29e..018fcc66aee 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1785,6 +1785,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { Ok(()) } + // FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately. fn pretty_print_const_valtree( &mut self, valtree: ty::ValTree<'tcx>, diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index c490e3885d4..cc6d69710e4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -214,6 +214,7 @@ impl<'tcx> ConstToPat<'tcx> { } // Recursive helper for `to_pat`; invoke that (instead of calling this directly). + // FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately. #[instrument(skip(self), level = "debug")] fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box> { let span = self.span; From 09f68486bdcca5eadc9147c57953bd0fd37bb1db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:10:15 +0800 Subject: [PATCH 67/71] run-make-support: add `-Csymbol-mangling-version` and `-Cprefer-dynamic` helpers to rustc Co-authored-by: binarycat --- .../run-make-support/src/external_deps/rustc.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index b70db7130f6..8d99924a2d1 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -216,6 +216,18 @@ impl Rustc { self } + /// Specify option of `-C symbol-mangling-version`. + pub fn symbol_mangling_version(&mut self, option: &str) -> &mut Self { + self.cmd.arg(format!("-Csymbol-mangling-version={option}")); + self + } + + /// Specify `-C prefer-dynamic`. + pub fn prefer_dynamic(&mut self) -> &mut Self { + self.cmd.arg(format!("-Cprefer-dynamic")); + self + } + /// Specify error format to use pub fn error_format(&mut self, format: &str) -> &mut Self { self.cmd.arg(format!("--error-format={format}")); From 17e0fc6f03e841aeba1304af570a06d4e21a9492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:12:09 +0800 Subject: [PATCH 68/71] run-make-support: collapse re-export --- src/tools/run-make-support/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 7316244b384..245c8d52f4d 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -47,7 +47,9 @@ pub use wasmparser; // tidy-alphabetical-end // Re-exports of external dependencies. -pub use external_deps::{c_build, c_cxx_compiler, clang, htmldocck, llvm, python, rustc, rustdoc}; +pub use external_deps::{ + cargo, c_build, c_cxx_compiler, clang, htmldocck, llvm, python, rustc, rustdoc +}; // These rely on external dependencies. pub use c_cxx_compiler::{Cc, Gcc, cc, cxx, extra_c_flags, extra_cxx_flags, gcc}; @@ -104,4 +106,3 @@ pub use assertion_helpers::{ pub use string::{ count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains, }; -use crate::external_deps::cargo; From c15c9702d6cf1fe36bd8bef7176a98137d6028b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:12:39 +0800 Subject: [PATCH 69/71] run-make-support: add `is_windows_gnu` helper --- src/tools/run-make-support/src/lib.rs | 5 ++++- src/tools/run-make-support/src/targets.rs | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 245c8d52f4d..a8c9bec57fd 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -81,7 +81,10 @@ pub use env::{env_var, env_var_os, set_current_dir}; pub use run::{cmd, run, run_fail, run_with_args}; /// Helpers for checking target information. -pub use targets::{is_aix, is_darwin, is_msvc, is_windows, llvm_components_contain, target, uname, apple_os}; +pub use targets::{ + apple_os, is_aix, is_darwin, is_msvc, is_windows, is_windows_gnu, llvm_components_contain, + target, uname, +}; /// Helpers for building names of output artifacts that are potentially target-specific. pub use artifact_names::{ diff --git a/src/tools/run-make-support/src/targets.rs b/src/tools/run-make-support/src/targets.rs index ae004fd0cbd..a16fca71d2e 100644 --- a/src/tools/run-make-support/src/targets.rs +++ b/src/tools/run-make-support/src/targets.rs @@ -22,6 +22,12 @@ pub fn is_msvc() -> bool { target().contains("msvc") } +/// Check if target is windows-gnu. +#[must_use] +pub fn is_windows_gnu() -> bool { + target().ends_with("windows-gnu") +} + /// Check if target uses macOS. #[must_use] pub fn is_darwin() -> bool { From 0bc1b4f4f6ace5b5e2a7676e498343cfeafab136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:13:16 +0800 Subject: [PATCH 70/71] run-make-support: add `object`-based symbol helpers - `dynamic_symbol_names` - `text_section_global_dynamic_symbol_names` - `global_undefined_dynamic_symbol_names` Also add some missing `#[track_caller]` attributes. Co-authored-by: binarycat --- src/tools/run-make-support/src/symbols.rs | 34 +++++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/tools/run-make-support/src/symbols.rs b/src/tools/run-make-support/src/symbols.rs index fd0c866bcc9..e4d244e14a4 100644 --- a/src/tools/run-make-support/src/symbols.rs +++ b/src/tools/run-make-support/src/symbols.rs @@ -2,28 +2,44 @@ use std::path::Path; use object::{self, Object, ObjectSymbol, SymbolIterator}; -/// Iterate through the symbols in an object file. +/// Given an [`object::File`], find the exported dynamic symbol names via +/// [`object::Object::exports`]. This does not distinguish between which section the symbols appear +/// in. +#[track_caller] +pub fn exported_dynamic_symbol_names<'file>(file: &'file object::File<'file>) -> Vec<&'file str> { + file.exports() + .unwrap() + .into_iter() + .filter_map(|sym| std::str::from_utf8(sym.name()).ok()) + .collect() +} + +/// Iterate through the symbols in an object file. See [`object::Object::symbols`]. /// -/// Uses a callback because `SymbolIterator` does not own its data. -/// -/// Panics if `path` is not a valid object file readable by the current user. +/// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be +/// parsed as a recognized object file. +#[track_caller] pub fn with_symbol_iter(path: P, func: F) -> R where P: AsRef, F: FnOnce(&mut SymbolIterator<'_, '_>) -> R, { - let raw_bytes = crate::fs::read(path); - let f = object::File::parse(raw_bytes.as_slice()).expect("unable to parse file"); + let path = path.as_ref(); + let blob = crate::fs::read(path); + let f = object::File::parse(&*blob) + .unwrap_or_else(|e| panic!("failed to parse `{}`: {e}", path.display())); let mut iter = f.symbols(); func(&mut iter) } /// Check an object file's symbols for substrings. /// -/// Returns `true` if any of the symbols found in the object file at -/// `path` contain a substring listed in `substrings`. +/// Returns `true` if any of the symbols found in the object file at `path` contain a substring +/// listed in `substrings`. /// -/// Panics if `path` is not a valid object file readable by the current user. +/// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be +/// parsed as a recognized object file. +#[track_caller] pub fn any_symbol_contains(path: impl AsRef, substrings: &[&str]) -> bool { with_symbol_iter(path, |syms| { for sym in syms { From 9734ebb9be2ad760385555e36bb0d065e726d6f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:14:51 +0800 Subject: [PATCH 71/71] tests: port `symbol-mangling-hashed` to rmake.rs - Use `object` based test logic instead of processing `nm` human-readable textual output. - Try to expand test coverage to not be limited to only linux + x86_64. Co-authored-by: binarycat --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/symbol-mangling-hashed/Makefile | 48 -------- .../run-make/symbol-mangling-hashed/b_bin.rs | 9 -- .../symbol-mangling-hashed/b_dylib.rs | 9 -- .../symbol-mangling-hashed/default_bin.rs | 9 ++ .../symbol-mangling-hashed/default_dylib.rs | 9 ++ .../{a_dylib.rs => hashed_dylib.rs} | 2 +- .../{a_rlib.rs => hashed_rlib.rs} | 2 +- .../run-make/symbol-mangling-hashed/rmake.rs | 108 ++++++++++++++++++ 9 files changed, 128 insertions(+), 69 deletions(-) delete mode 100644 tests/run-make/symbol-mangling-hashed/Makefile delete mode 100644 tests/run-make/symbol-mangling-hashed/b_bin.rs delete mode 100644 tests/run-make/symbol-mangling-hashed/b_dylib.rs create mode 100644 tests/run-make/symbol-mangling-hashed/default_bin.rs create mode 100644 tests/run-make/symbol-mangling-hashed/default_dylib.rs rename tests/run-make/symbol-mangling-hashed/{a_dylib.rs => hashed_dylib.rs} (74%) rename tests/run-make/symbol-mangling-hashed/{a_rlib.rs => hashed_rlib.rs} (74%) create mode 100644 tests/run-make/symbol-mangling-hashed/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e75d3dc2147..45b40b17ea3 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,2 +1 @@ run-make/split-debuginfo/Makefile -run-make/symbol-mangling-hashed/Makefile diff --git a/tests/run-make/symbol-mangling-hashed/Makefile b/tests/run-make/symbol-mangling-hashed/Makefile deleted file mode 100644 index c95036ead95..00000000000 --- a/tests/run-make/symbol-mangling-hashed/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -include ../tools.mk - -# ignore-cross-compile -# only-linux -# only-x86_64 - -NM=nm -D -RLIB_NAME=liba_rlib.rlib -DYLIB_NAME=liba_dylib.so -SO_NAME=libb_dylib.so -BIN_NAME=b_bin - -ifeq ($(UNAME),Darwin) -NM=nm -gU -RLIB_NAME=liba_rlib.rlib -DYLIB_NAME=liba_dylib.dylib -SO_NAME=libb_dylib.dylib -BIN_NAME=b_bin -endif - -ifdef IS_WINDOWS -NM=nm -g -RLIB_NAME=liba_rlib.dll.a -DYLIB_NAME=liba_dylib.dll -SO_NAME=libb_dylib.dll -BIN_NAME=b_bin.exe -endif - -all: - $(RUSTC) -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=hashed -C metadata=foo a_dylib.rs - $(RUSTC) -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=hashed -C metadata=bar a_rlib.rs - $(RUSTC) -C prefer-dynamic -L $(TMPDIR) b_dylib.rs - $(RUSTC) -C prefer-dynamic -L $(TMPDIR) b_bin.rs - - # Check hashed symbol name - - [ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep -c hello)" -eq "0" ] - [ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep _RNxC7a_dylib | grep -c ' T ')" -eq "2" ] - - [ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep b_dylib | grep -c hello)" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC6a_rlib | grep -c ' T ')" -eq "2" ] - [ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC7a_dylib | grep -c ' U ')" -eq "1" ] - - [ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep _RNxC6a_rlib | grep -c ' U ')" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep _RNxC7a_dylib | grep -c ' U ')" -eq "1" ] - [ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep b_dylib | grep hello | grep -c ' U ')" -eq "1" ] - - $(call RUN,$(BIN_NAME)) diff --git a/tests/run-make/symbol-mangling-hashed/b_bin.rs b/tests/run-make/symbol-mangling-hashed/b_bin.rs deleted file mode 100644 index 8ee7fecda62..00000000000 --- a/tests/run-make/symbol-mangling-hashed/b_bin.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate a_dylib; -extern crate a_rlib; -extern crate b_dylib; - -fn main() { - a_rlib::hello(); - a_dylib::hello(); - b_dylib::hello(); -} diff --git a/tests/run-make/symbol-mangling-hashed/b_dylib.rs b/tests/run-make/symbol-mangling-hashed/b_dylib.rs deleted file mode 100644 index 3252c9c75c2..00000000000 --- a/tests/run-make/symbol-mangling-hashed/b_dylib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_type = "dylib"] - -extern crate a_dylib; -extern crate a_rlib; - -pub fn hello() { - a_rlib::hello(); - a_dylib::hello(); -} diff --git a/tests/run-make/symbol-mangling-hashed/default_bin.rs b/tests/run-make/symbol-mangling-hashed/default_bin.rs new file mode 100644 index 00000000000..387596705c3 --- /dev/null +++ b/tests/run-make/symbol-mangling-hashed/default_bin.rs @@ -0,0 +1,9 @@ +extern crate default_dylib; +extern crate hashed_dylib; +extern crate hashed_rlib; + +fn main() { + hashed_rlib::hrhello(); + hashed_dylib::hdhello(); + default_dylib::ddhello(); +} diff --git a/tests/run-make/symbol-mangling-hashed/default_dylib.rs b/tests/run-make/symbol-mangling-hashed/default_dylib.rs new file mode 100644 index 00000000000..986d1c7b74d --- /dev/null +++ b/tests/run-make/symbol-mangling-hashed/default_dylib.rs @@ -0,0 +1,9 @@ +#![crate_type = "dylib"] + +extern crate hashed_dylib; +extern crate hashed_rlib; + +pub fn ddhello() { + hashed_rlib::hrhello(); + hashed_dylib::hdhello(); +} diff --git a/tests/run-make/symbol-mangling-hashed/a_dylib.rs b/tests/run-make/symbol-mangling-hashed/hashed_dylib.rs similarity index 74% rename from tests/run-make/symbol-mangling-hashed/a_dylib.rs rename to tests/run-make/symbol-mangling-hashed/hashed_dylib.rs index 49d65b72cac..fbb7cba43e0 100644 --- a/tests/run-make/symbol-mangling-hashed/a_dylib.rs +++ b/tests/run-make/symbol-mangling-hashed/hashed_dylib.rs @@ -1,4 +1,4 @@ #![crate_type = "dylib"] -pub fn hello() { +pub fn hdhello() { println!("hello dylib"); } diff --git a/tests/run-make/symbol-mangling-hashed/a_rlib.rs b/tests/run-make/symbol-mangling-hashed/hashed_rlib.rs similarity index 74% rename from tests/run-make/symbol-mangling-hashed/a_rlib.rs rename to tests/run-make/symbol-mangling-hashed/hashed_rlib.rs index 71e44ccc200..048e67784d2 100644 --- a/tests/run-make/symbol-mangling-hashed/a_rlib.rs +++ b/tests/run-make/symbol-mangling-hashed/hashed_rlib.rs @@ -1,5 +1,5 @@ #![crate_type = "rlib"] -pub fn hello() { +pub fn hrhello() { println!("hello rlib"); } diff --git a/tests/run-make/symbol-mangling-hashed/rmake.rs b/tests/run-make/symbol-mangling-hashed/rmake.rs new file mode 100644 index 00000000000..136e6b9fa3a --- /dev/null +++ b/tests/run-make/symbol-mangling-hashed/rmake.rs @@ -0,0 +1,108 @@ +// ignore-tidy-linelength +//! Basic smoke test for the unstable option `-C symbol_mangling_version=hashed` which aims to +//! replace full symbol mangling names based on hash digests to shorten symbol name lengths in +//! dylibs for space savings. +//! +//! # References +//! +//! - MCP #705: Provide option to shorten symbol names by replacing them with a digest: +//! . +//! - Implementation PR: . +//! - PE format: . + +//@ ignore-cross-compile + +#![deny(warnings)] + +use run_make_support::symbols::exported_dynamic_symbol_names; +use run_make_support::{bin_name, cwd, dynamic_lib_name, is_darwin, object, rfs, run, rustc}; + +macro_rules! adjust_symbol_prefix { + ($name:literal) => { + if is_darwin() { concat!("_", $name) } else { $name } + }; +} + +fn main() { + rustc() + .input("hashed_dylib.rs") + .prefer_dynamic() + .arg("-Zunstable-options") + .symbol_mangling_version("hashed") + .metadata("foo") + .run(); + + rustc() + .input("hashed_rlib.rs") + .prefer_dynamic() + .arg("-Zunstable-options") + .symbol_mangling_version("hashed") + .metadata("bar") + .run(); + + rustc().input("default_dylib.rs").library_search_path(cwd()).prefer_dynamic().run(); + rustc().input("default_bin.rs").library_search_path(cwd()).prefer_dynamic().run(); + + { + // Check hashed symbol name + + let dylib_filename = dynamic_lib_name("hashed_dylib"); + println!("checking dylib `{dylib_filename}`"); + + let dylib_blob = rfs::read(&dylib_filename); + let dylib_file = object::File::parse(&*dylib_blob) + .unwrap_or_else(|e| panic!("failed to parse `{dylib_filename}`: {e}")); + + let dynamic_symbols = exported_dynamic_symbol_names(&dylib_file); + + if dynamic_symbols.iter().filter(|sym| sym.contains("hdhello")).count() != 0 { + eprintln!("exported dynamic symbols: {:#?}", dynamic_symbols); + panic!("expected no occurrence of `hdhello`"); + } + + let expected_prefix = adjust_symbol_prefix!("_RNxC12hashed_dylib"); + if dynamic_symbols.iter().filter(|sym| sym.starts_with(expected_prefix)).count() != 2 { + eprintln!("exported dynamic symbols: {:#?}", dynamic_symbols); + panic!("expected two dynamic symbols starting with `{expected_prefix}`"); + } + } + + { + let dylib_filename = dynamic_lib_name("default_dylib"); + println!("checking so `{dylib_filename}`"); + + let dylib_blob = rfs::read(&dylib_filename); + let dylib_file = object::File::parse(&*dylib_blob) + .unwrap_or_else(|e| panic!("failed to parse `{dylib_filename}`: {e}")); + + let dynamic_symbols = exported_dynamic_symbol_names(&dylib_file); + + if dynamic_symbols + .iter() + .filter(|sym| sym.contains("default_dylib") && sym.contains("ddhello")) + .count() + != 1 + { + eprintln!("exported dynamic symbols: {:#?}", dynamic_symbols); + panic!("expected one occurrence of mangled `ddhello`"); + } + + let expected_rlib_prefix = adjust_symbol_prefix!("_RNxC11hashed_rlib"); + if dynamic_symbols.iter().filter(|sym| sym.starts_with(expected_rlib_prefix)).count() != 2 { + eprintln!("exported dynamic symbols: {:#?}", dynamic_symbols); + panic!("expected two exported symbols starting with `{expected_rlib_prefix}`"); + } + + let expected_dylib_prefix = adjust_symbol_prefix!("_RNxC12hashed_dylib"); + if dynamic_symbols.iter().any(|sym| sym.starts_with("_RNxC12hashed_dylib")) { + eprintln!("exported dynamic symbols: {:#?}", dynamic_symbols); + panic!("did not expect any symbols starting with `{expected_dylib_prefix}`"); + } + } + + // Check that the final binary can be run. + { + let bin_filename = bin_name("default_bin"); + run(&bin_filename); + } +}