about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-01-12 11:22:20 +0000
committerbors <bors@rust-lang.org>2019-01-12 11:22:20 +0000
commitd6525ef539a04cb43de40080bdabc5f2f5a4a197 (patch)
tree8abef858718c138adecb80e45339ba8df8bf9f97 /src/liballoc
parent1190f7cdf7a62e25c9a8eaf58e0906849692bf2b (diff)
parent3117784c1846e8d45c711703d1693e835cf4679e (diff)
downloadrust-d6525ef539a04cb43de40080bdabc5f2f5a4a197.tar.gz
rust-d6525ef539a04cb43de40080bdabc5f2f5a4a197.zip
Auto merge of #57542 - Centril:rollup, r=Centril
Rollup of 26 pull requests

Successful merges:

 - #56425 (Redo the docs for Vec::set_len)
 - #56906 (Issue #56905)
 - #57042 (Don't call `FieldPlacement::count` when count is too large)
 - #57175 (Stabilize `let` bindings and destructuring in constants and const fn)
 - #57192 (Change std::error::Error trait documentation to talk about `source` instead of `cause`)
 - #57296 (Fixed the link to the ? operator)
 - #57368 (Use CMAKE_{C,CXX}_COMPILER_LAUNCHER for ccache)
 - #57400 (Rustdoc: update Source Serif Pro and replace Heuristica italic)
 - #57417 (rustdoc: use text-based doctest parsing if a macro is wrapping main)
 - #57433 (Add link destination for `read-ownership`)
 - #57434 (Remove `CrateNum::Invalid`.)
 - #57441 (Supporting backtrace for x86_64-fortanix-unknown-sgx.)
 - #57450 (actually take a slice in this example)
 - #57459 (Reference tracking issue for inherent associated types in diagnostic)
 - #57463 (docs: Fix some 'second-edition' links)
 - #57466 (Remove outdated comment)
 - #57493 (use structured suggestion when casting a reference)
 - #57498 (make note of one more normalization that Paths do)
 - #57499 (note that FromStr does not work for borrowed types)
 - #57505 (Remove submodule step from README)
 - #57510 (Add a profiles section to the manifest)
 - #57511 (Fix undefined behavior)
 - #57519 (Correct RELEASES.md for 1.32.0)
 - #57522 (don't unwrap unexpected tokens in `format!`)
 - #57530 (Fixing a typographical error.)
 - #57535 (Stabilise irrefutable if-let and while-let patterns)

Failed merges:

r? @ghost
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/vec.rs89
1 files changed, 62 insertions, 27 deletions
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index b69c114ed45..e1c5ab15bb5 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -738,53 +738,88 @@ impl<T> Vec<T> {
         self
     }
 
-    /// Sets the length of a vector.
+    /// Forces the length of the vector to `new_len`.
     ///
-    /// 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 vector
+    /// 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()`].
+    /// - The elements at `old_len..new_len` must be initialized.
     ///
-    /// unsafe {
-    ///     ptr::drop_in_place(&mut vec[3]);
-    ///     vec.set_len(3);
+    /// [`capacity()`]: #method.capacity
+    ///
+    /// # Examples
+    ///
+    /// This method can be useful for situations in which the vector
+    /// 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 FFI method's docs, "32768 bytes is always enough".
+    ///     let mut dict = Vec::with_capacity(32_768);
+    ///     let mut dict_length = 0;
+    ///     // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    ///     // 1. `dict_length` elements were initialized.
+    ///     // 2. `dict_length` <= the capacity (32_768)
+    ///     // which makes `set_len` safe to call.
+    ///     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],
     ///                    vec![0, 1, 0],
     ///                    vec![0, 0, 1]];
+    /// // SAFETY:
+    /// // 1. `old_len..0` is empty so no elements need to be initialized.
+    /// // 2. `0 <= capacity` always holds whatever `capacity` is.
     /// unsafe {
     ///     vec.set_len(0);
     /// }
     /// ```
     ///
-    /// 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);
-    /// }
-    /// ```
+    /// Normally, here, one would use [`clear`] instead to correctly drop
+    /// the contents and thus not leak memory.
     #[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.