diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index f50d9a8e1bdf3..ac3d84718d54e 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -157,9 +157,10 @@ impl Layout { /// allocate backing structure for `T` (which could be a trait /// or other unsized type like a slice). #[stable(feature = "alloc_layout", since = "1.28.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[must_use] #[inline] - pub fn for_value(t: &T) -> Self { + pub const fn for_value(t: &T) -> Self { let (size, align) = (mem::size_of_val(t), mem::align_of_val(t)); // SAFETY: see rationale in `new` for why this is using the unsafe variant unsafe { Layout::from_size_align_unchecked(size, align) } @@ -191,8 +192,9 @@ impl Layout { /// [trait object]: ../../book/ch17-02-trait-objects.html /// [extern type]: ../../unstable-book/language-features/extern-types.html #[unstable(feature = "layout_for_ptr", issue = "69835")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[must_use] - pub unsafe fn for_value_raw(t: *const T) -> Self { + pub const unsafe fn for_value_raw(t: *const T) -> Self { // SAFETY: we pass along the prerequisites of these functions to the caller let (size, align) = unsafe { (mem::size_of_val_raw(t), mem::align_of_val_raw(t)) }; // SAFETY: see rationale in `new` for why this is using the unsafe variant @@ -229,8 +231,9 @@ impl Layout { /// Returns an error if the combination of `self.size()` and the given /// `align` violates the conditions listed in [`Layout::from_size_align`]. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn align_to(&self, align: usize) -> Result { + pub const fn align_to(&self, align: usize) -> Result { Layout::from_size_align(self.size(), cmp::max(self.align(), align)) } @@ -287,10 +290,11 @@ impl Layout { /// This is equivalent to adding the result of `padding_needed_for` /// to the layout's current size. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[must_use = "this returns a new `Layout`, \ without modifying the original"] #[inline] - pub fn pad_to_align(&self) -> Layout { + pub const fn pad_to_align(&self) -> Layout { let pad = 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`, @@ -311,8 +315,9 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { + pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { // This cannot overflow. Quoting from the invariant of Layout: // > `size`, when rounded up to the nearest multiple of `align`, // > must not overflow isize (i.e., the rounded value must be @@ -321,7 +326,8 @@ impl Layout { let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?; // The safe constructor is called here to enforce the isize size limit. - Layout::from_size_alignment(alloc_size, self.align).map(|layout| (layout, padded_size)) + let layout = Layout::from_size_alignment(alloc_size, self.align)?; + Ok((layout, padded_size)) } /// Creates a layout describing the record for `self` followed by @@ -370,8 +376,9 @@ impl Layout { /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16]))); /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { + pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { let new_align = cmp::max(self.align, next.align); let pad = self.padding_needed_for(next.align()); @@ -396,8 +403,9 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn repeat_packed(&self, n: usize) -> Result { + pub const fn repeat_packed(&self, n: usize) -> Result { let size = self.size().checked_mul(n).ok_or(LayoutError)?; // The safe constructor is called here to enforce the isize size limit. Layout::from_size_alignment(size, self.align) @@ -410,8 +418,9 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn extend_packed(&self, next: Self) -> Result { + pub const fn extend_packed(&self, next: Self) -> Result { let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?; // The safe constructor is called here to enforce the isize size limit. Layout::from_size_alignment(new_size, self.align) @@ -422,13 +431,18 @@ impl Layout { /// On arithmetic overflow or when the total size would exceed /// `isize::MAX`, returns `LayoutError`. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] + #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub fn array(n: usize) -> Result { + pub const fn array(n: usize) -> Result { // Reduce the amount of code we need to monomorphize per `T`. return inner(mem::size_of::(), Alignment::of::(), n); #[inline] - fn inner(element_size: usize, align: Alignment, n: usize) -> Result { + const fn inner( + element_size: usize, + align: Alignment, + n: usize, + ) -> Result { // We need to check two things about the size: // - That the total size won't overflow a `usize`, and // - That the total size still fits in an `isize`. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index e7ea558a95534..1823fd3006279 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -99,6 +99,8 @@ // Library features: #![feature(const_align_offset)] #![feature(const_align_of_val)] +#![feature(const_align_of_val_raw)] +#![feature(const_alloc_layout)] #![feature(const_arguments_as_str)] #![feature(const_array_into_iter_constructors)] #![feature(const_bigint_helper_methods)] @@ -141,6 +143,7 @@ #![feature(const_ptr_write)] #![feature(const_raw_ptr_comparison)] #![feature(const_size_of_val)] +#![feature(const_size_of_val_raw)] #![feature(const_slice_from_raw_parts_mut)] #![feature(const_slice_ptr_len)] #![feature(const_slice_split_at_mut)] diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 1390e09dd96ae..64a5290c3a267 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -9,7 +9,9 @@ use crate::{cmp, fmt, hash, mem, num}; /// Note that particularly large alignments, while representable in this type, /// are likely not to be supported by actual allocators and linkers. #[unstable(feature = "ptr_alignment_type", issue = "102070")] -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq)] +#[cfg_attr(bootstrap, derive(PartialEq))] +#[cfg_attr(not(bootstrap), derive_const(PartialEq))] #[repr(transparent)] pub struct Alignment(AlignmentEnum); @@ -167,16 +169,18 @@ impl From for usize { } } +#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl cmp::Ord for Alignment { +impl const cmp::Ord for Alignment { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { - self.as_nonzero().cmp(&other.as_nonzero()) + self.as_nonzero().get().cmp(&other.as_nonzero().get()) } } +#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl cmp::PartialOrd for Alignment { +impl const cmp::PartialOrd for Alignment { #[inline] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) @@ -198,7 +202,9 @@ type AlignmentEnum = AlignmentEnum32; #[cfg(target_pointer_width = "64")] type AlignmentEnum = AlignmentEnum64; -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq)] +#[cfg_attr(bootstrap, derive(PartialEq))] +#[cfg_attr(not(bootstrap), derive_const(PartialEq))] #[repr(u16)] enum AlignmentEnum16 { _Align1Shl0 = 1 << 0, @@ -219,7 +225,9 @@ enum AlignmentEnum16 { _Align1Shl15 = 1 << 15, } -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq)] +#[cfg_attr(bootstrap, derive(PartialEq))] +#[cfg_attr(not(bootstrap), derive_const(PartialEq))] #[repr(u32)] enum AlignmentEnum32 { _Align1Shl0 = 1 << 0, @@ -256,7 +264,9 @@ enum AlignmentEnum32 { _Align1Shl31 = 1 << 31, } -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq)] +#[cfg_attr(bootstrap, derive(PartialEq))] +#[cfg_attr(not(bootstrap), derive_const(PartialEq))] #[repr(u64)] enum AlignmentEnum64 { _Align1Shl0 = 1 << 0,