Auto merge of #55366 - Amanieu:stable_layout, r=Amanieu

Add tracking issue for Layout methods (and some API changes)

These methods are already useful when used with the stable global allocator API (stabilized in #51241).

```rust
pub fn align_to(&self, align: usize) -> Result<Layout, LayoutErr>;
pub fn padding_needed_for(&self, align: usize) -> usize;
pub fn repeat(&self, n: usize) -> Result<(Layout, usize), LayoutErr>;
pub fn extend(&self, next: Layout) -> Result<(Layout, usize), LayoutErr>;
pub fn repeat_packed(&self, n: usize) -> Result<Layout, LayoutErr>;
pub fn extend_packed(&self, next: Layout) -> Result<Layout, LayoutErr>;
pub fn array<T>(n: usize) -> Result<Layout, LayoutErr>;
```

cc #32838

r? @SimonSapin
This commit is contained in:
bors 2018-11-08 06:52:27 +00:00
commit 1d834550d5
3 changed files with 18 additions and 24 deletions

View File

@ -119,6 +119,7 @@
#![feature(const_vec_new)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit)]
#![feature(alloc_layout_extra)]
// Allow testing this library

View File

@ -164,15 +164,13 @@ pub fn for_value<T: ?Sized>(t: &T) -> Self {
/// alignment. In other words, if `K` has size 16, `K.align_to(32)`
/// will *still* have size 16.
///
/// # Panics
///
/// Panics if the combination of `self.size()` and the given `align`
/// violates the conditions listed in
/// Returns an error if the combination of `self.size()` and the given
/// `align` violates the conditions listed in
/// [`Layout::from_size_align`](#method.from_size_align).
#[unstable(feature = "allocator_api", issue = "32838")]
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn align_to(&self, align: usize) -> Self {
Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap()
pub fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
Layout::from_size_align(self.size(), cmp::max(self.align(), align))
}
/// Returns the amount of padding we must insert after `self`
@ -191,7 +189,7 @@ pub fn align_to(&self, align: usize) -> Self {
/// 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 = "allocator_api", issue = "32838")]
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn padding_needed_for(&self, align: usize) -> usize {
let len = self.size();
@ -228,7 +226,7 @@ pub fn padding_needed_for(&self, align: usize) -> usize {
/// of each element in the array.
///
/// On arithmetic overflow, returns `LayoutErr`.
#[unstable(feature = "allocator_api", issue = "32838")]
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
let padded_size = self.size().checked_add(self.padding_needed_for(self.align()))
@ -248,13 +246,16 @@ pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
/// will be properly aligned. Note that the result layout will
/// satisfy the alignment properties of both `self` and `next`.
///
/// The resulting layout will be the same as that of a C struct containing
/// two fields with the layouts of `self` and `next`, in that order.
///
/// Returns `Some((k, offset))`, where `k` is layout of the concatenated
/// record and `offset` is the relative location, in bytes, of the
/// start of the `next` embedded within the concatenated record
/// (assuming that the record itself starts at offset 0).
///
/// On arithmetic overflow, returns `LayoutErr`.
#[unstable(feature = "allocator_api", issue = "32838")]
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
let new_align = cmp::max(self.align(), next.align());
@ -281,7 +282,7 @@ pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
/// aligned.
///
/// On arithmetic overflow, returns `LayoutErr`.
#[unstable(feature = "allocator_api", issue = "32838")]
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
@ -293,29 +294,20 @@ pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
/// padding is inserted, the alignment of `next` is irrelevant,
/// and is not incorporated *at all* into the resulting layout.
///
/// Returns `(k, offset)`, where `k` is layout of the concatenated
/// record and `offset` is the relative location, in bytes, of the
/// start of the `next` embedded within the concatenated record
/// (assuming that the record itself starts at offset 0).
///
/// (The `offset` is always the same as `self.size()`; we use this
/// signature out of convenience in matching the signature of
/// `extend`.)
///
/// On arithmetic overflow, returns `LayoutErr`.
#[unstable(feature = "allocator_api", issue = "32838")]
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
let new_size = self.size().checked_add(next.size())
.ok_or(LayoutErr { private: () })?;
let layout = Layout::from_size_align(new_size, self.align())?;
Ok((layout, self.size()))
Ok(layout)
}
/// Creates a layout describing the record for a `[T; n]`.
///
/// On arithmetic overflow, returns `LayoutErr`.
#[unstable(feature = "allocator_api", issue = "32838")]
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
Layout::new::<T>()

View File

@ -310,6 +310,7 @@
#![feature(doc_keyword)]
#![feature(panic_info_message)]
#![feature(non_exhaustive)]
#![feature(alloc_layout_extra)]
#![default_lib_allocator]