Skip to content

Commit

Permalink
Redo the docs for Vec::set_len
Browse files Browse the repository at this point in the history
Inspired by the recent conversation on IRLO.
  • Loading branch information
scottmcm committed Dec 2, 2018
1 parent aef4dbf commit 5c11392
Showing 1 changed file with 53 additions and 27 deletions.
80 changes: 53 additions & 27 deletions src/liballoc/vec.rs
Expand Up @@ -748,28 +748,64 @@ impl<T> Vec<T> {
self
}

/// Sets the length of a vector.
/// Forces the length of a vector to a particular value.
///
/// This will explicitly set the size of the vector, without actually
/// modifying its buffers, so it is up to the caller to ensure that the
/// vector is actually the specified size.
/// This is a low-level operation that maintains none of the normal
/// invariants of the type. Normally changing the length of a `Vec`
/// is done using one of the safe operations instead, such as
/// [`truncate`], [`resize`], [`extend`], or [`clear`].
///
/// # Examples
/// [`truncate`]: #method.truncate
/// [`resize`]: #method.resize
/// [`extend`]: #method.extend-1
/// [`clear`]: #method.clear
///
/// ```
/// use std::ptr;
/// # Safety
///
/// let mut vec = vec!['r', 'u', 's', 't'];
/// - `new_len` must be less than or equal to `capacity()`.
/// - All elements between past the previous end up to the `new_len`
/// must be initialized.
///
/// unsafe {
/// ptr::drop_in_place(&mut vec[3]);
/// vec.set_len(3);
/// # Examples
///
/// This method can be useful for situations in which the `Vec` is
/// serving as a buffer for other code, particularly over FFI:
///
/// ```no_run
/// # #![allow(dead_code)]
/// # // This is just a minimal skeleton for the doc example;
/// # // don't use this as a starting point for a real library.
/// # pub struct StreamWrapper { strm: *mut std::ffi::c_void }
/// # const Z_OK: i32 = 0;
/// # extern "C" {
/// # fn deflateGetDictionary(
/// # strm: *mut std::ffi::c_void,
/// # dictionary: *mut u8,
/// # dictLength: *mut usize,
/// # ) -> i32;
/// # }
/// # impl StreamWrapper {
/// pub fn get_dictionary(&self) -> Option<Vec<u8>> {
/// // Per the docs, "32768 bytes is always enough".
/// let mut dict = Vec::with_capacity(32_768);
/// let mut dict_length = 0;
/// unsafe {
/// // Make the FFI call...
/// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
/// if r == Z_OK {
/// // ...and update the length to what was initialized.
/// dict.set_len(dict_length);
/// Some(dict)
/// } else {
/// None
/// }
/// }
/// }
/// assert_eq!(vec, ['r', 'u', 's']);
/// # }
/// ```
///
/// In this example, there is a memory leak since the memory locations
/// owned by the inner vectors were not freed prior to the `set_len` call:
/// While the following example is sound, there is a memory leak since
/// the inner vectors were not freed prior to the `set_len` call:
///
/// ```
/// let mut vec = vec![vec![1, 0, 0],
Expand All @@ -780,21 +816,11 @@ impl<T> Vec<T> {
/// }
/// ```
///
/// In this example, the vector gets expanded from zero to four items
/// without any memory allocations occurring, resulting in vector
/// values of unallocated memory:
///
/// ```
/// let mut vec: Vec<char> = Vec::new();
///
/// unsafe {
/// vec.set_len(4);
/// }
/// ```
/// (Instead, one would normally use [`clear`] in this situation.)
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn set_len(&mut self, len: usize) {
self.len = len;
pub unsafe fn set_len(&mut self, new_len: usize) {
self.len = new_len;
}

/// Removes an element from the vector and returns it.
Expand Down

0 comments on commit 5c11392

Please sign in to comment.