diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index f7a0bbdceafc9..4ff38247dae24 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -748,28 +748,64 @@ impl Vec { 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> { + /// // 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], @@ -780,21 +816,11 @@ impl Vec { /// } /// ``` /// - /// 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 = 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.