@@ -483,15 +483,13 @@ impl<T> Vec<T> {
483483 Self :: with_capacity_in ( capacity, Global )
484484 }
485485
486- /// Creates a `Vec<T>` directly from the raw components of another vector .
486+ /// Creates a `Vec<T>` directly from a pointer, a capacity, and a length .
487487 ///
488488 /// # Safety
489489 ///
490490 /// This is highly unsafe, due to the number of invariants that aren't
491491 /// checked:
492492 ///
493- /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
494- /// (at least, it's highly likely to be incorrect if it wasn't).
495493 /// * `T` needs to have the same alignment as what `ptr` was allocated with.
496494 /// (`T` having a less strict alignment is not sufficient, the alignment really
497495 /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
@@ -500,6 +498,14 @@ impl<T> Vec<T> {
500498 /// to be the same size as the pointer was allocated with. (Because similar to
501499 /// alignment, [`dealloc`] must be called with the same layout `size`.)
502500 /// * `length` needs to be less than or equal to `capacity`.
501+ /// * The first `length` values must be properly initialized values of type `T`.
502+ /// * `capacity` needs to be the capacity that the pointer was allocated with.
503+ /// * The allocated size in bytes must be no larger than `isize::MAX`.
504+ /// See the safety documentation of [`pointer::offset`].
505+ ///
506+ /// These requirements are always upheld by any `ptr` that has been allocated
507+ /// via `Vec<T>`. Other allocation sources are allowed if the invariants are
508+ /// upheld.
503509 ///
504510 /// Violating these may cause problems like corrupting the allocator's
505511 /// internal data structures. For example it is normally **not** safe
@@ -551,6 +557,32 @@ impl<T> Vec<T> {
551557 /// assert_eq!(rebuilt, [4, 5, 6]);
552558 /// }
553559 /// ```
560+ ///
561+ /// Using memory that was allocated elsewhere:
562+ ///
563+ /// ```rust
564+ /// #![feature(allocator_api)]
565+ ///
566+ /// use std::alloc::{AllocError, Allocator, Global, Layout};
567+ ///
568+ /// fn main() {
569+ /// let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
570+ ///
571+ /// let vec = unsafe {
572+ /// let mem = match Global.allocate(layout) {
573+ /// Ok(mem) => mem.cast::<u32>().as_ptr(),
574+ /// Err(AllocError) => return,
575+ /// };
576+ ///
577+ /// mem.write(1_000_000);
578+ ///
579+ /// Vec::from_raw_parts_in(mem, 1, 16, Global)
580+ /// };
581+ ///
582+ /// assert_eq!(vec, &[1_000_000]);
583+ /// assert_eq!(vec.capacity(), 16);
584+ /// }
585+ /// ```
554586 #[ inline]
555587 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
556588 pub unsafe fn from_raw_parts ( ptr : * mut T , length : usize , capacity : usize ) -> Self {
@@ -641,21 +673,30 @@ impl<T, A: Allocator> Vec<T, A> {
641673 Vec { buf : RawVec :: with_capacity_in ( capacity, alloc) , len : 0 }
642674 }
643675
644- /// Creates a `Vec<T, A>` directly from the raw components of another vector.
676+ /// Creates a `Vec<T, A>` directly from a pointer, a capacity, a length,
677+ /// and an allocator.
645678 ///
646679 /// # Safety
647680 ///
648681 /// This is highly unsafe, due to the number of invariants that aren't
649682 /// checked:
650683 ///
651- /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
652- /// (at least, it's highly likely to be incorrect if it wasn't).
653- /// * `T` needs to have the same size and alignment as what `ptr` was allocated with.
684+ /// * `T` needs to have the same alignment as what `ptr` was allocated with.
654685 /// (`T` having a less strict alignment is not sufficient, the alignment really
655686 /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
656687 /// allocated and deallocated with the same layout.)
688+ /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
689+ /// to be the same size as the pointer was allocated with. (Because similar to
690+ /// alignment, [`dealloc`] must be called with the same layout `size`.)
657691 /// * `length` needs to be less than or equal to `capacity`.
658- /// * `capacity` needs to be the capacity that the pointer was allocated with.
692+ /// * The first `length` values must be properly initialized values of type `T`.
693+ /// * `capacity` needs to [*fit*] the layout size that the pointer was allocated with.
694+ /// * The allocated size in bytes must be no larger than `isize::MAX`.
695+ /// See the safety documentation of [`pointer::offset`].
696+ ///
697+ /// These requirements are always upheld by any `ptr` that has been allocated
698+ /// via `Vec<T, A>`. Other allocation sources are allowed if the invariants are
699+ /// upheld.
659700 ///
660701 /// Violating these may cause problems like corrupting the allocator's
661702 /// internal data structures. For example it is **not** safe
@@ -673,6 +714,7 @@ impl<T, A: Allocator> Vec<T, A> {
673714 ///
674715 /// [`String`]: crate::string::String
675716 /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
717+ /// [*fit*]: crate::alloc::Allocator#memory-fitting
676718 ///
677719 /// # Examples
678720 ///
@@ -711,6 +753,29 @@ impl<T, A: Allocator> Vec<T, A> {
711753 /// assert_eq!(rebuilt, [4, 5, 6]);
712754 /// }
713755 /// ```
756+ ///
757+ /// Using memory that was allocated elsewhere:
758+ ///
759+ /// ```rust
760+ /// use std::alloc::{alloc, Layout};
761+ ///
762+ /// fn main() {
763+ /// let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
764+ /// let vec = unsafe {
765+ /// let mem = alloc(layout).cast::<u32>();
766+ /// if mem.is_null() {
767+ /// return;
768+ /// }
769+ ///
770+ /// mem.write(1_000_000);
771+ ///
772+ /// Vec::from_raw_parts(mem, 1, 16)
773+ /// };
774+ ///
775+ /// assert_eq!(vec, &[1_000_000]);
776+ /// assert_eq!(vec.capacity(), 16);
777+ /// }
778+ /// ```
714779 #[ inline]
715780 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
716781 pub unsafe fn from_raw_parts_in ( ptr : * mut T , length : usize , capacity : usize , alloc : A ) -> Self {
0 commit comments