diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index fd21b3671182b..09a1991f3a76f 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -87,7 +87,6 @@ // // Library features: #![cfg_attr(not(no_global_oom_handling), feature(alloc_c_string))] -#![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_chunks)] #![feature(array_methods)] @@ -121,6 +120,7 @@ #![feature(inplace_iteration)] #![feature(iter_advance_by)] #![feature(layout_for_ptr)] +#![feature(layout_padding_needed_for)] #![feature(maybe_uninit_slice)] #![cfg_attr(test, feature(new_uninit))] #![feature(nonnull_slice_from_raw_parts)] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 601a87aa4ac89..5634261500a00 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -1,8 +1,8 @@ #![feature(allocator_api)] -#![feature(alloc_layout_extra)] #![feature(assert_matches)] #![feature(box_syntax)] #![feature(cow_is_borrowed)] +#![feature(const_alloc_layout)] #![feature(const_box)] #![feature(const_convert)] #![feature(const_cow_is_borrowed)] diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index cf864039a23ba..6ac2f02637b3c 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -187,8 +187,8 @@ impl Layout { /// 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")] - #[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[must_use] #[inline] pub const fn dangling(&self) -> NonNull { @@ -232,7 +232,7 @@ impl Layout { /// 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")] + #[unstable(feature = "layout_padding_needed_for", issue = "55724")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[must_use = "this returns the padding needed, \ without modifying the `Layout`"] @@ -288,24 +288,30 @@ impl Layout { /// Creates a layout describing the record for `n` instances of /// `self`, with a suitable amount of padding between each to /// ensure that each instance is given its requested size and - /// alignment. On success, returns `(k, offs)` where `k` is the - /// layout of the array and `offs` is the distance between the start - /// of each element in the array. + /// alignment, but *no trailing padding*. On success, returns `(k, offs)` + /// where `k` is the layout of the repetition and `offs` is the distance + /// between the start of each element in the repetition. This is equivalent + /// to calling `extend` multiple times. /// /// On arithmetic overflow, returns `LayoutError`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "1.63.0")] #[inline] pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { + let padding = self.padding_needed_for(self.align()); + // This cannot overflow. Quoting from the invariant of Layout: // > `size`, when rounded up to the nearest multiple of `align`, // > must not overflow (i.e., the rounded value must be less than // > `usize::MAX`) - let padded_size = self.size() + self.padding_needed_for(self.align()); - let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?; - - // SAFETY: self.align is already known to be valid and alloc_size has been - // padded already. - unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) } + let padded_size = self.size() + padding; + let array_size = padded_size.checked_mul(n).ok_or(LayoutError)?; + let repetition_size = array_size - padding; + + Ok(( + // SAFETY: self.align is already known to be valid and array_size doesn't overflow. + unsafe { Layout::from_size_align_unchecked(repetition_size, self.align()) }, + padded_size, + )) } /// Creates a layout describing the record for `self` followed by @@ -378,7 +384,7 @@ impl Layout { /// aligned. /// /// On arithmetic overflow, returns `LayoutError`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_extra", since = "1.63.0")] #[inline] pub fn repeat_packed(&self, n: usize) -> Result { let size = self.size().checked_mul(n).ok_or(LayoutError)?; @@ -391,7 +397,7 @@ 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 = "1.63.0")] #[inline] pub fn extend_packed(&self, next: Self) -> Result { let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?; diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 9ea374e1045a5..4ce14408532b4 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,10 +1,10 @@ -#![feature(alloc_layout_extra)] #![feature(array_chunks)] #![feature(array_methods)] #![feature(array_windows)] #![feature(bench_black_box)] #![feature(box_syntax)] #![feature(cell_update)] +#![feature(const_alloc_layout)] #![feature(const_assume)] #![feature(const_black_box)] #![feature(const_bool_to_option)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 6dc3fd9858451..4ca63d32677b7 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -291,7 +291,6 @@ #![feature(strict_provenance)] // // Library features (alloc): -#![feature(alloc_layout_extra)] #![feature(alloc_c_string)] #![feature(allocator_api)] #![feature(get_mut_unchecked)]