Auto merge of #53754 - RalfJung:slice_align_to, r=alexcrichton

stabilize slice_align_to

This is very hard to implement correctly, and leads to [serious bugs](https://github.com/llogiq/bytecount/pull/42) when done incorrectly. Moreover, this is needed to be able to run code that opportunistically exploits alignment on miri. So code using `align_to`/`align_to_mut` gets the benefit of a well-tested implementation *and* of being able to run in miri to test for (some kinds of) UB.

This PR also clarifies the guarantee wrt. the middle part being as long as possible.  Should the docs say under which circumstances the middle part could be shorter? Currently, that can only happen when running in miri.
This commit is contained in:
bors 2018-09-16 07:22:24 +00:00
commit f4819878cd
2 changed files with 8 additions and 9 deletions

View file

@ -1739,8 +1739,9 @@ impl<T> [T] {
/// maintained.
///
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
/// slice of a new type, and the suffix slice. The middle slice will have the greatest length
/// possible for a given type and input slice.
/// slice of a new type, and the suffix slice. The method does a best effort to make the
/// middle slice the greatest length possible for a given type and input slice, but only
/// your algorithm's performance should depend on that, not its correctness.
///
/// This method has no purpose when either input element `T` or output element `U` are
/// zero-sized and will return the original slice without splitting anything.
@ -1755,7 +1756,6 @@ impl<T> [T] {
/// Basic usage:
///
/// ```
/// # #![feature(slice_align_to)]
/// unsafe {
/// let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
/// let (prefix, shorts, suffix) = bytes.align_to::<u16>();
@ -1764,7 +1764,7 @@ impl<T> [T] {
/// // less_efficient_algorithm_for_bytes(suffix);
/// }
/// ```
#[unstable(feature = "slice_align_to", issue = "44488")]
#[stable(feature = "slice_align_to", since = "1.30.0")]
pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T]) {
// Note that most of this function will be constant-evaluated,
if ::mem::size_of::<U>() == 0 || ::mem::size_of::<T>() == 0 {
@ -1792,8 +1792,9 @@ impl<T> [T] {
/// maintained.
///
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
/// slice of a new type, and the suffix slice. The middle slice will have the greatest length
/// possible for a given type and input slice.
/// slice of a new type, and the suffix slice. The method does a best effort to make the
/// middle slice the greatest length possible for a given type and input slice, but only
/// your algorithm's performance should depend on that, not its correctness.
///
/// This method has no purpose when either input element `T` or output element `U` are
/// zero-sized and will return the original slice without splitting anything.
@ -1808,7 +1809,6 @@ impl<T> [T] {
/// Basic usage:
///
/// ```
/// # #![feature(slice_align_to)]
/// unsafe {
/// let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
/// let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
@ -1817,7 +1817,7 @@ impl<T> [T] {
/// // less_efficient_algorithm_for_bytes(suffix);
/// }
/// ```
#[unstable(feature = "slice_align_to", issue = "44488")]
#[stable(feature = "slice_align_to", since = "1.30.0")]
pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T]) {
// Note that most of this function will be constant-evaluated,
if ::mem::size_of::<U>() == 0 || ::mem::size_of::<T>() == 0 {

View file

@ -34,7 +34,6 @@
#![feature(try_from)]
#![feature(try_trait)]
#![feature(exact_chunks)]
#![feature(slice_align_to)]
#![feature(align_offset)]
#![feature(reverse_bits)]
#![feature(inner_deref)]