@@ -483,15 +483,13 @@ impl<T> Vec<T> {
483
483
Self :: with_capacity_in ( capacity, Global )
484
484
}
485
485
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 .
487
487
///
488
488
/// # Safety
489
489
///
490
490
/// This is highly unsafe, due to the number of invariants that aren't
491
491
/// checked:
492
492
///
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).
495
493
/// * `T` needs to have the same alignment as what `ptr` was allocated with.
496
494
/// (`T` having a less strict alignment is not sufficient, the alignment really
497
495
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
@@ -500,6 +498,14 @@ impl<T> Vec<T> {
500
498
/// to be the same size as the pointer was allocated with. (Because similar to
501
499
/// alignment, [`dealloc`] must be called with the same layout `size`.)
502
500
/// * `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.
503
509
///
504
510
/// Violating these may cause problems like corrupting the allocator's
505
511
/// internal data structures. For example it is normally **not** safe
@@ -551,6 +557,32 @@ impl<T> Vec<T> {
551
557
/// assert_eq!(rebuilt, [4, 5, 6]);
552
558
/// }
553
559
/// ```
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
+ /// ```
554
586
#[ inline]
555
587
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
556
588
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> {
641
673
Vec { buf : RawVec :: with_capacity_in ( capacity, alloc) , len : 0 }
642
674
}
643
675
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.
645
678
///
646
679
/// # Safety
647
680
///
648
681
/// This is highly unsafe, due to the number of invariants that aren't
649
682
/// checked:
650
683
///
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.
654
685
/// (`T` having a less strict alignment is not sufficient, the alignment really
655
686
/// needs to be equal to satisfy the [`dealloc`] requirement that memory must be
656
687
/// 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`.)
657
691
/// * `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.
659
700
///
660
701
/// Violating these may cause problems like corrupting the allocator's
661
702
/// internal data structures. For example it is **not** safe
@@ -673,6 +714,7 @@ impl<T, A: Allocator> Vec<T, A> {
673
714
///
674
715
/// [`String`]: crate::string::String
675
716
/// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
717
+ /// [*fit*]: crate::alloc::Allocator#memory-fitting
676
718
///
677
719
/// # Examples
678
720
///
@@ -711,6 +753,29 @@ impl<T, A: Allocator> Vec<T, A> {
711
753
/// assert_eq!(rebuilt, [4, 5, 6]);
712
754
/// }
713
755
/// ```
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
+ /// ```
714
779
#[ inline]
715
780
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
716
781
pub unsafe fn from_raw_parts_in ( ptr : * mut T , length : usize , capacity : usize , alloc : A ) -> Self {
0 commit comments