Rollup merge of #102207 - CraftSpider:const-layout, r=scottmcm
Constify remaining `Layout` methods Makes the methods on `Layout` that aren't yet unstably const, under the same feature and issue, #67521. Most of them required no changes, only non-trivial change is probably constifying `ValidAlignment` which may affect #102072
This commit is contained in:
commit
1625435fa4
3 changed files with 45 additions and 18 deletions
|
@ -157,9 +157,10 @@ impl Layout {
|
||||||
/// allocate backing structure for `T` (which could be a trait
|
/// allocate backing structure for `T` (which could be a trait
|
||||||
/// or other unsized type like a slice).
|
/// or other unsized type like a slice).
|
||||||
#[stable(feature = "alloc_layout", since = "1.28.0")]
|
#[stable(feature = "alloc_layout", since = "1.28.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_value<T: ?Sized>(t: &T) -> Self {
|
pub const fn for_value<T: ?Sized>(t: &T) -> Self {
|
||||||
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
|
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
|
// SAFETY: see rationale in `new` for why this is using the unsafe variant
|
||||||
unsafe { Layout::from_size_align_unchecked(size, align) }
|
unsafe { Layout::from_size_align_unchecked(size, align) }
|
||||||
|
@ -191,8 +192,9 @@ impl Layout {
|
||||||
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
/// [trait object]: ../../book/ch17-02-trait-objects.html
|
||||||
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
/// [extern type]: ../../unstable-book/language-features/extern-types.html
|
||||||
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
#[unstable(feature = "layout_for_ptr", issue = "69835")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
|
pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
|
||||||
// SAFETY: we pass along the prerequisites of these functions to the caller
|
// 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)) };
|
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
|
// 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
|
/// Returns an error if the combination of `self.size()` and the given
|
||||||
/// `align` violates the conditions listed in [`Layout::from_size_align`].
|
/// `align` violates the conditions listed in [`Layout::from_size_align`].
|
||||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
|
pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
|
||||||
Layout::from_size_align(self.size(), cmp::max(self.align(), align))
|
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`
|
/// This is equivalent to adding the result of `padding_needed_for`
|
||||||
/// to the layout's current size.
|
/// to the layout's current size.
|
||||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
#[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`, \
|
#[must_use = "this returns a new `Layout`, \
|
||||||
without modifying the original"]
|
without modifying the original"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pad_to_align(&self) -> Layout {
|
pub const fn pad_to_align(&self) -> Layout {
|
||||||
let pad = self.padding_needed_for(self.align());
|
let pad = self.padding_needed_for(self.align());
|
||||||
// This cannot overflow. Quoting from the invariant of Layout:
|
// This cannot overflow. Quoting from the invariant of Layout:
|
||||||
// > `size`, when rounded up to the nearest multiple of `align`,
|
// > `size`, when rounded up to the nearest multiple of `align`,
|
||||||
|
@ -311,8 +315,9 @@ impl Layout {
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutError`.
|
/// On arithmetic overflow, returns `LayoutError`.
|
||||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[inline]
|
#[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:
|
// This cannot overflow. Quoting from the invariant of Layout:
|
||||||
// > `size`, when rounded up to the nearest multiple of `align`,
|
// > `size`, when rounded up to the nearest multiple of `align`,
|
||||||
// > must not overflow isize (i.e., the rounded value must be
|
// > 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)?;
|
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?;
|
||||||
|
|
||||||
// The safe constructor is called here to enforce the isize size limit.
|
// 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
|
/// 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])));
|
/// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16])));
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[inline]
|
#[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 new_align = cmp::max(self.align, next.align);
|
||||||
let pad = self.padding_needed_for(next.align());
|
let pad = self.padding_needed_for(next.align());
|
||||||
|
|
||||||
|
@ -396,8 +403,9 @@ impl Layout {
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutError`.
|
/// On arithmetic overflow, returns `LayoutError`.
|
||||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
|
pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
|
||||||
let size = self.size().checked_mul(n).ok_or(LayoutError)?;
|
let size = self.size().checked_mul(n).ok_or(LayoutError)?;
|
||||||
// The safe constructor is called here to enforce the isize size limit.
|
// The safe constructor is called here to enforce the isize size limit.
|
||||||
Layout::from_size_alignment(size, self.align)
|
Layout::from_size_alignment(size, self.align)
|
||||||
|
@ -410,8 +418,9 @@ impl Layout {
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutError`.
|
/// On arithmetic overflow, returns `LayoutError`.
|
||||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
|
pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
|
||||||
let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
|
let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
|
||||||
// The safe constructor is called here to enforce the isize size limit.
|
// The safe constructor is called here to enforce the isize size limit.
|
||||||
Layout::from_size_alignment(new_size, self.align)
|
Layout::from_size_alignment(new_size, self.align)
|
||||||
|
@ -422,13 +431,18 @@ impl Layout {
|
||||||
/// On arithmetic overflow or when the total size would exceed
|
/// On arithmetic overflow or when the total size would exceed
|
||||||
/// `isize::MAX`, returns `LayoutError`.
|
/// `isize::MAX`, returns `LayoutError`.
|
||||||
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
#[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn array<T>(n: usize) -> Result<Self, LayoutError> {
|
pub const fn array<T>(n: usize) -> Result<Self, LayoutError> {
|
||||||
// Reduce the amount of code we need to monomorphize per `T`.
|
// Reduce the amount of code we need to monomorphize per `T`.
|
||||||
return inner(mem::size_of::<T>(), Alignment::of::<T>(), n);
|
return inner(mem::size_of::<T>(), Alignment::of::<T>(), n);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inner(element_size: usize, align: Alignment, n: usize) -> Result<Layout, LayoutError> {
|
const fn inner(
|
||||||
|
element_size: usize,
|
||||||
|
align: Alignment,
|
||||||
|
n: usize,
|
||||||
|
) -> Result<Layout, LayoutError> {
|
||||||
// We need to check two things about the size:
|
// We need to check two things about the size:
|
||||||
// - That the total size won't overflow a `usize`, and
|
// - That the total size won't overflow a `usize`, and
|
||||||
// - That the total size still fits in an `isize`.
|
// - That the total size still fits in an `isize`.
|
||||||
|
|
|
@ -99,6 +99,8 @@
|
||||||
// Library features:
|
// Library features:
|
||||||
#![feature(const_align_offset)]
|
#![feature(const_align_offset)]
|
||||||
#![feature(const_align_of_val)]
|
#![feature(const_align_of_val)]
|
||||||
|
#![feature(const_align_of_val_raw)]
|
||||||
|
#![feature(const_alloc_layout)]
|
||||||
#![feature(const_arguments_as_str)]
|
#![feature(const_arguments_as_str)]
|
||||||
#![feature(const_array_into_iter_constructors)]
|
#![feature(const_array_into_iter_constructors)]
|
||||||
#![feature(const_bigint_helper_methods)]
|
#![feature(const_bigint_helper_methods)]
|
||||||
|
@ -141,6 +143,7 @@
|
||||||
#![feature(const_ptr_write)]
|
#![feature(const_ptr_write)]
|
||||||
#![feature(const_raw_ptr_comparison)]
|
#![feature(const_raw_ptr_comparison)]
|
||||||
#![feature(const_size_of_val)]
|
#![feature(const_size_of_val)]
|
||||||
|
#![feature(const_size_of_val_raw)]
|
||||||
#![feature(const_slice_from_raw_parts_mut)]
|
#![feature(const_slice_from_raw_parts_mut)]
|
||||||
#![feature(const_slice_ptr_len)]
|
#![feature(const_slice_ptr_len)]
|
||||||
#![feature(const_slice_split_at_mut)]
|
#![feature(const_slice_split_at_mut)]
|
||||||
|
|
|
@ -9,7 +9,9 @@ use crate::{cmp, fmt, hash, mem, num};
|
||||||
/// Note that particularly large alignments, while representable in this type,
|
/// Note that particularly large alignments, while representable in this type,
|
||||||
/// are likely not to be supported by actual allocators and linkers.
|
/// are likely not to be supported by actual allocators and linkers.
|
||||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[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)]
|
#[repr(transparent)]
|
||||||
pub struct Alignment(AlignmentEnum);
|
pub struct Alignment(AlignmentEnum);
|
||||||
|
|
||||||
|
@ -167,16 +169,18 @@ impl From<Alignment> for usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
|
||||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
impl cmp::Ord for Alignment {
|
impl const cmp::Ord for Alignment {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
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")]
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
impl cmp::PartialOrd for Alignment {
|
impl const cmp::PartialOrd for Alignment {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
||||||
Some(self.cmp(other))
|
Some(self.cmp(other))
|
||||||
|
@ -198,7 +202,9 @@ type AlignmentEnum = AlignmentEnum32;
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
type AlignmentEnum = AlignmentEnum64;
|
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)]
|
#[repr(u16)]
|
||||||
enum AlignmentEnum16 {
|
enum AlignmentEnum16 {
|
||||||
_Align1Shl0 = 1 << 0,
|
_Align1Shl0 = 1 << 0,
|
||||||
|
@ -219,7 +225,9 @@ enum AlignmentEnum16 {
|
||||||
_Align1Shl15 = 1 << 15,
|
_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)]
|
#[repr(u32)]
|
||||||
enum AlignmentEnum32 {
|
enum AlignmentEnum32 {
|
||||||
_Align1Shl0 = 1 << 0,
|
_Align1Shl0 = 1 << 0,
|
||||||
|
@ -256,7 +264,9 @@ enum AlignmentEnum32 {
|
||||||
_Align1Shl31 = 1 << 31,
|
_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)]
|
#[repr(u64)]
|
||||||
enum AlignmentEnum64 {
|
enum AlignmentEnum64 {
|
||||||
_Align1Shl0 = 1 << 0,
|
_Align1Shl0 = 1 << 0,
|
||||||
|
|
Loading…
Add table
Reference in a new issue