mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #95393 - Dylan-DPC:rollup-l72f39g, r=Dylan-DPC
Rollup of 4 pull requests Successful merges: - #88375 (Clarify that ManuallyDrop<T> has same layout as T) - #93755 (Allow comparing `Vec`s with different allocators using `==`) - #95016 (Docs: make Vec::from_raw_parts documentation less strict) - #95098 (impl From<&[T; N]> and From<&mut [T; N]> for Vec<T>) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
93313d108f
@ -479,12 +479,14 @@ impl<T> Vec<T> {
|
||||
///
|
||||
/// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
|
||||
/// (at least, it's highly likely to be incorrect if it wasn't).
|
||||
/// * `T` needs to have the same size and alignment as what `ptr` was allocated with.
|
||||
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
|
||||
/// (`T` having a less strict alignment is not sufficient, the alignment really
|
||||
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
|
||||
/// allocated and deallocated with the same layout.)
|
||||
/// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
|
||||
/// to be the same size as the pointer was allocated with. (Because similar to
|
||||
/// alignment, [`dealloc`] must be called with the same layout `size`.)
|
||||
/// * `length` needs to be less than or equal to `capacity`.
|
||||
/// * `capacity` needs to be the capacity that the pointer was allocated with.
|
||||
///
|
||||
/// Violating these may cause problems like corrupting the allocator's
|
||||
/// internal data structures. For example it is **not** safe
|
||||
@ -492,7 +494,9 @@ impl<T> Vec<T> {
|
||||
/// It's also not safe to build one from a `Vec<u16>` and its length, because
|
||||
/// the allocator cares about the alignment, and these two types have different
|
||||
/// alignments. The buffer was allocated with alignment 2 (for `u16`), but after
|
||||
/// turning it into a `Vec<u8>` it'll be deallocated with alignment 1.
|
||||
/// turning it into a `Vec<u8>` it'll be deallocated with alignment 1. To avoid
|
||||
/// these issues, it is often preferable to do casting/transmuting using
|
||||
/// [`slice::from_raw_parts`] instead.
|
||||
///
|
||||
/// The ownership of `ptr` is effectively transferred to the
|
||||
/// `Vec<T>` which may then deallocate, reallocate or change the
|
||||
@ -2929,6 +2933,48 @@ impl<T, const N: usize> From<[T; N]> for Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[stable(feature = "vec_from_array_ref", since = "1.61.0")]
|
||||
impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> {
|
||||
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(Vec::from(b"raw"), vec![b'r', b'a', b'w']);
|
||||
/// ```
|
||||
#[cfg(not(test))]
|
||||
fn from(s: &[T; N]) -> Vec<T> {
|
||||
s.to_vec()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn from(s: &[T; N]) -> Vec<T> {
|
||||
crate::slice::to_vec(s, Global)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
#[stable(feature = "vec_from_array_ref", since = "1.61.0")]
|
||||
impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> {
|
||||
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
|
||||
/// ```
|
||||
#[cfg(not(test))]
|
||||
fn from(s: &mut [T; N]) -> Vec<T> {
|
||||
s.to_vec()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn from(s: &mut [T; N]) -> Vec<T> {
|
||||
crate::slice::to_vec(s, Global)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "vec_from_cow_slice", since = "1.14.0")]
|
||||
impl<'a, T> From<Cow<'a, [T]>> for Vec<T>
|
||||
where
|
||||
|
@ -20,7 +20,7 @@ macro_rules! __impl_slice_eq1 {
|
||||
}
|
||||
}
|
||||
|
||||
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, Vec<U, A>, #[stable(feature = "rust1", since = "1.0.0")] }
|
||||
__impl_slice_eq1! { [A1: Allocator, A2: Allocator] Vec<T, A1>, Vec<U, A2>, #[stable(feature = "rust1", since = "1.0.0")] }
|
||||
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &[U], #[stable(feature = "rust1", since = "1.0.0")] }
|
||||
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &mut [U], #[stable(feature = "rust1", since = "1.0.0")] }
|
||||
__impl_slice_eq1! { [A: Allocator] &[T], Vec<U, A>, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] }
|
||||
|
@ -4,11 +4,12 @@ use crate::ptr;
|
||||
/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
|
||||
/// This wrapper is 0-cost.
|
||||
///
|
||||
/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
|
||||
/// As a consequence, it has *no effect* on the assumptions that the compiler makes
|
||||
/// about its contents. For example, initializing a `ManuallyDrop<&mut T>`
|
||||
/// with [`mem::zeroed`] is undefined behavior.
|
||||
/// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
|
||||
/// `ManuallyDrop<T>` is guaranteed to have the same layout as `T`, and is subject
|
||||
/// to the same layout optimizations as `T`. As a consequence, it has *no effect*
|
||||
/// on the assumptions that the compiler makes about its contents. For example,
|
||||
/// initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined
|
||||
/// behavior. If you need to handle uninitialized data, use [`MaybeUninit<T>`]
|
||||
/// instead.
|
||||
///
|
||||
/// Note that accessing the value inside a `ManuallyDrop<T>` is safe.
|
||||
/// This means that a `ManuallyDrop<T>` whose content has been dropped must not
|
||||
|
Loading…
Reference in New Issue
Block a user