diff --git a/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch index f3d1d5c43ea10..6ed0b17f679ca 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch @@ -14,11 +14,10 @@ diff --git a/coretests/tests/lib.rs b/coretests/tests/lib.rs index 1e336bf..35e6f54 100644 --- a/coretests/tests/lib.rs +++ b/coretests/tests/lib.rs -@@ -2,5 +2,4 @@ +@@ -2,4 +2,3 @@ // tidy-alphabetical-start -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_select))] - #![feature(alloc_layout_extra)] #![feature(array_ptr_get)] diff --git a/coretests/tests/atomic.rs b/coretests/tests/atomic.rs index b735957..ea728b6 100644 diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 39450f69ce30a..1065c4c99b639 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -184,7 +184,7 @@ impl Global { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = if zeroed { alloc_zeroed(layout) } else { alloc(layout) }; @@ -314,7 +314,7 @@ unsafe impl Allocator for Global { // SAFETY: conditions must be upheld by the caller 0 => unsafe { self.deallocate(ptr, old_layout); - Ok(NonNull::slice_from_raw_parts(new_layout.dangling(), 0)) + Ok(NonNull::slice_from_raw_parts(new_layout.dangling_ptr(), 0)) }, // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 1cce36606d2c0..b50810b8d923d 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -245,7 +245,7 @@ impl WithHeader { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); - layout.dangling() + layout.dangling_ptr() } else { let ptr = alloc::alloc(layout); if ptr.is_null() { @@ -282,7 +282,7 @@ impl WithHeader { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. debug_assert!(value_offset == 0 && size_of::() == 0 && size_of::() == 0); - layout.dangling() + layout.dangling_ptr() } else { let ptr = alloc::alloc(layout); if ptr.is_null() { diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 73197d021f1a3..b3c4605eb2412 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -86,7 +86,6 @@ // Library features: // tidy-alphabetical-start #![cfg_attr(not(no_global_oom_handling), feature(string_replace_in_place))] -#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_into_iter_constructors)] #![feature(array_windows)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 89520e68920e7..9ec437e3b8740 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -261,7 +261,7 @@ use core::panic::{RefUnwindSafe, UnwindSafe}; #[cfg(not(no_global_oom_handling))] use core::pin::Pin; use core::pin::PinCoerceUnsized; -use core::ptr::{self, NonNull, drop_in_place}; +use core::ptr::{self, Alignment, NonNull, drop_in_place}; #[cfg(not(no_global_oom_handling))] use core::slice::from_raw_parts_mut; use core::{borrow, fmt, hint}; @@ -3761,11 +3761,11 @@ unsafe fn data_offset(ptr: *const T) -> usize { // and extern types, the input safety requirement is currently enough to // satisfy the requirements of align_of_val_raw; this is an implementation // detail of the language that must not be relied upon outside of std. - unsafe { data_offset_align(align_of_val_raw(ptr)) } + unsafe { data_offset_align(Alignment::new_unchecked(align_of_val_raw(ptr))) } } #[inline] -fn data_offset_align(align: usize) -> usize { +fn data_offset_align(align: Alignment) -> usize { let layout = Layout::new::>(); layout.size() + layout.padding_needed_for(align) } @@ -4379,7 +4379,7 @@ impl UniqueRcUninit { /// Returns the pointer to be written into to initialize the [`Rc`]. fn data_ptr(&mut self) -> *mut T { - let offset = data_offset_align(self.layout_for_value.align()); + let offset = data_offset_align(self.layout_for_value.alignment()); unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index ccf26ba4c2ac9..cce670db89b4b 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -26,7 +26,7 @@ use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Lega use core::ops::{Residual, Try}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::{Pin, PinCoerceUnsized}; -use core::ptr::{self, NonNull}; +use core::ptr::{self, Alignment, NonNull}; #[cfg(not(no_global_oom_handling))] use core::slice::from_raw_parts_mut; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release}; @@ -4119,11 +4119,11 @@ unsafe fn data_offset(ptr: *const T) -> usize { // and extern types, the input safety requirement is currently enough to // satisfy the requirements of align_of_val_raw; this is an implementation // detail of the language that must not be relied upon outside of std. - unsafe { data_offset_align(align_of_val_raw(ptr)) } + unsafe { data_offset_align(Alignment::new_unchecked(align_of_val_raw(ptr))) } } #[inline] -fn data_offset_align(align: usize) -> usize { +fn data_offset_align(align: Alignment) -> usize { let layout = Layout::new::>(); layout.size() + layout.padding_needed_for(align) } @@ -4156,7 +4156,7 @@ impl UniqueArcUninit { /// Returns the pointer to be written into to initialize the [`Arc`]. fn data_ptr(&mut self) -> *mut T { - let offset = data_offset_align(self.layout_for_value.align()); + let offset = data_offset_align(self.layout_for_value.alignment()); unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } } diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index efdcb893bfeef..83ffd216f1bdb 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -14,7 +14,6 @@ // // Library features: // tidy-alphabetical-start -#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_into_iter_constructors)] #![feature(assert_matches)] diff --git a/library/alloctests/tests/boxed.rs b/library/alloctests/tests/boxed.rs index 94389cf2de933..83fd1ef7449a3 100644 --- a/library/alloctests/tests/boxed.rs +++ b/library/alloctests/tests/boxed.rs @@ -104,7 +104,7 @@ pub struct ConstAllocator; unsafe impl Allocator for ConstAllocator { fn allocate(&self, layout: Layout) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), _ => unsafe { let ptr = core::intrinsics::const_allocate(layout.size(), layout.align()); Ok(NonNull::new_unchecked(ptr as *mut [u8; 0] as *mut [u8])) diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 52124495f8c36..d6f3608b7c86c 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -1,5 +1,4 @@ #![feature(allocator_api)] -#![feature(alloc_layout_extra)] #![feature(iter_array_chunks)] #![feature(assert_matches)] #![feature(wtf8_internals)] diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 1f37c978fecfd..ef2bb65269bb6 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -230,10 +230,11 @@ impl Layout { /// be that of a valid pointer, which means this must not be used /// as a "not yet initialized" sentinel value. /// Types that lazily allocate must track initialization by some other means. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] - pub const fn dangling(&self) -> NonNull { + pub const fn dangling_ptr(&self) -> NonNull { NonNull::without_provenance(self.align.as_nonzero()) } @@ -263,29 +264,23 @@ impl Layout { } /// Returns the amount of padding we must insert after `self` - /// to ensure that the following address will satisfy `align` - /// (measured in bytes). + /// to ensure that the following address will satisfy `alignment`. /// - /// e.g., if `self.size()` is 9, then `self.padding_needed_for(4)` + /// e.g., if `self.size()` is 9, then `self.padding_needed_for(alignment4)` + /// (where `alignment4.as_usize() == 4`) /// returns 3, because that is the minimum number of bytes of /// padding required to get a 4-aligned address (assuming that the /// corresponding memory block starts at a 4-aligned address). /// - /// The return value of this function has no meaning if `align` is - /// not a power-of-two. - /// - /// Note that the utility of the returned value requires `align` + /// Note that the utility of the returned value requires `alignment` /// to be less than or equal to the alignment of the starting /// address for the whole allocated block of memory. One way to - /// satisfy this constraint is to ensure `align <= self.align()`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[must_use = "this returns the padding needed, \ - without modifying the `Layout`"] + /// satisfy this constraint is to ensure `alignment.as_usize() <= self.align()`. + #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[must_use = "this returns the padding needed, without modifying the `Layout`"] #[inline] - pub const fn padding_needed_for(&self, align: usize) -> usize { - // FIXME: Can we just change the type on this to `Alignment`? - let Some(align) = Alignment::new(align) else { return usize::MAX }; - let len_rounded_up = self.size_rounded_up_to_custom_align(align); + pub const fn padding_needed_for(&self, alignment: Alignment) -> usize { + let len_rounded_up = self.size_rounded_up_to_custom_align(alignment); // SAFETY: Cannot overflow because the rounded-up value is never less unsafe { unchecked_sub(len_rounded_up, self.size) } } @@ -348,6 +343,8 @@ impl Layout { /// layout of the array and `offs` is the distance between the start /// of each element in the array. /// + /// Does not include padding after the trailing element. + /// /// (That distance between elements is sometimes known as "stride".) /// /// On arithmetic overflow, returns `LayoutError`. @@ -355,7 +352,6 @@ impl Layout { /// # Examples /// /// ``` - /// #![feature(alloc_layout_extra)] /// use std::alloc::Layout; /// /// // All rust types have a size that's a multiple of their alignment. @@ -366,17 +362,26 @@ impl Layout { /// // But you can manually make layouts which don't meet that rule. /// let padding_needed = Layout::from_size_align(6, 4).unwrap(); /// let repeated = padding_needed.repeat(3).unwrap(); - /// assert_eq!(repeated, (Layout::from_size_align(24, 4).unwrap(), 8)); + /// assert_eq!(repeated, (Layout::from_size_align(22, 4).unwrap(), 8)); /// ``` - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { + // FIXME(const-hack): the following could be way shorter with `?` let padded = self.pad_to_align(); - if let Ok(repeated) = padded.repeat_packed(n) { - Ok((repeated, padded.size())) + let Ok(result) = (if let Some(k) = n.checked_sub(1) { + let Ok(repeated) = padded.repeat_packed(k) else { + return Err(LayoutError); + }; + repeated.extend_packed(*self) } else { - Err(LayoutError) - } + debug_assert!(n == 0); + self.repeat_packed(0) + }) else { + return Err(LayoutError); + }; + Ok((result, padded.size())) } /// Creates a layout describing the record for `self` followed by @@ -456,7 +461,8 @@ impl Layout { /// aligned. /// /// On arithmetic overflow, returns `LayoutError`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn repeat_packed(&self, n: usize) -> Result { if let Some(size) = self.size.checked_mul(n) { @@ -473,7 +479,8 @@ impl Layout { /// and is not incorporated *at all* into the resulting layout. /// /// On arithmetic overflow, returns `LayoutError`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "alloc_layout_extra", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn extend_packed(&self, next: Self) -> Result { // SAFETY: each `size` is at most `isize::MAX == usize::MAX/2`, so the diff --git a/library/coretests/tests/alloc.rs b/library/coretests/tests/alloc.rs index a4af6fd32a11d..aac1d60ce32c4 100644 --- a/library/coretests/tests/alloc.rs +++ b/library/coretests/tests/alloc.rs @@ -6,7 +6,7 @@ fn const_unchecked_layout() { const SIZE: usize = 0x2000; const ALIGN: usize = 0x1000; const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) }; - const DANGLING: NonNull = LAYOUT.dangling(); + const DANGLING: NonNull = LAYOUT.dangling_ptr(); assert_eq!(LAYOUT.size(), SIZE); assert_eq!(LAYOUT.align(), ALIGN); assert_eq!(Some(DANGLING), NonNull::new(ptr::without_provenance_mut(ALIGN))); diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 80b62038c40ec..c31759680f9a1 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -1,7 +1,6 @@ // tidy-alphabetical-start #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_select))] -#![feature(alloc_layout_extra)] #![feature(array_ptr_get)] #![feature(array_try_from_fn)] #![feature(array_windows)] diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index daa25c5a50dd6..8d162cc7af2c8 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -135,7 +135,7 @@ impl System { #[inline] fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), + 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0)), // SAFETY: `layout` is non-zero in size, size => unsafe { let raw_ptr = if zeroed { @@ -259,7 +259,7 @@ unsafe impl Allocator for System { // SAFETY: conditions must be upheld by the caller 0 => unsafe { Allocator::deallocate(self, ptr, old_layout); - Ok(NonNull::slice_from_raw_parts(new_layout.dangling(), 0)) + Ok(NonNull::slice_from_raw_parts(new_layout.dangling_ptr(), 0)) }, // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 7b6cfbfe0f259..6edd7fdff2fa5 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -372,7 +372,6 @@ // // Library features (alloc): // tidy-alphabetical-start -#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(get_mut_unchecked)] #![feature(map_try_insert)]