]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #34951 - tomgarcia:covariant-vec, r=brson
authorbors <bors@rust-lang.org>
Thu, 28 Jul 2016 12:24:31 +0000 (05:24 -0700)
committerGitHub <noreply@github.com>
Thu, 28 Jul 2016 12:24:31 +0000 (05:24 -0700)
Make vec::Drain and binary_heap::Drain covariant

I removed all mutable pointers/references, and added covariance tests similar to the ones in #32635. It builds and passes the tests, but I noticed that there weren't any tests of Drain's behaviour (at least not in libcollectionstest), so I'm not sure if my changes accidently broke Drain's behaviour. Should I add some tests for that (and if so, what should the tests include)?

1  2 
src/libcollections/vec.rs

index 967baccd2740a7f724dbd17ca5a732aab33ac847,f3d31ceea1347441bd4123f26feee5e1b41a87ea..275f38b2f787d469a8596be0b0d6bcce64fc3b19
@@@ -73,6 -73,7 +73,7 @@@ use core::mem
  use core::ops::{Index, IndexMut};
  use core::ops;
  use core::ptr;
+ use core::ptr::Shared;
  use core::slice;
  
  use super::SpecExtend;
@@@ -541,14 -542,6 +542,14 @@@ impl<T> Vec<T> 
      /// Extracts a slice containing the entire vector.
      ///
      /// Equivalent to `&s[..]`.
 +    ///
 +    /// # Examples
 +    ///
 +    /// ```
 +    /// use std::io::{self, Write};
 +    /// let buffer = vec![1, 2, 3, 5, 8];
 +    /// io::sink().write(buffer.as_slice()).unwrap();
 +    /// ```
      #[inline]
      #[stable(feature = "vec_as_slice", since = "1.7.0")]
      pub fn as_slice(&self) -> &[T] {
      /// Extracts a mutable slice of the entire vector.
      ///
      /// Equivalent to `&mut s[..]`.
 +    ///
 +    /// # Examples
 +    ///
 +    /// ```
 +    /// use std::io::{self, Read};
 +    /// let mut buffer = vec![0; 3];
 +    /// io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
 +    /// ```
      #[inline]
      #[stable(feature = "vec_as_slice", since = "1.7.0")]
      pub fn as_mut_slice(&mut self) -> &mut [T] {
      /// # Examples
      ///
      /// ```
 -    /// let mut v = vec![1, 2, 3, 4];
 +    /// use std::ptr;
 +    ///
 +    /// let mut vec = vec!['r', 'u', 's', 't'];
 +    ///
 +    /// unsafe {
 +    ///     ptr::drop_in_place(&mut vec[3]);
 +    ///     vec.set_len(3);
 +    /// }
 +    /// 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:
 +    ///
 +    /// ```
 +    /// let mut vec = vec![vec![1, 0, 0],
 +    ///                    vec![0, 1, 0],
 +    ///                    vec![0, 0, 1]];
 +    /// 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 {
 -    ///     v.set_len(1);
 +    ///     vec.set_len(4);
      /// }
      /// ```
      #[inline]
              Drain {
                  tail_start: end,
                  tail_len: len - end,
-                 iter: range_slice.iter_mut(),
-                 vec: self as *mut _,
+                 iter: range_slice.iter(),
+                 vec: Shared::new(self as *mut _),
              }
          }
      }
@@@ -1806,8 -1762,8 +1807,8 @@@ pub struct Drain<'a, T: 'a> 
      /// Length of tail
      tail_len: usize,
      /// Current remaining range to remove
-     iter: slice::IterMut<'a, T>,
-     vec: *mut Vec<T>,
+     iter: slice::Iter<'a, T>,
+     vec: Shared<Vec<T>>,
  }
  
  #[stable(feature = "drain", since = "1.6.0")]
@@@ -1845,7 -1801,7 +1846,7 @@@ impl<'a, T> Drop for Drain<'a, T> 
  
          if self.tail_len > 0 {
              unsafe {
-                 let source_vec = &mut *self.vec;
+                 let source_vec = &mut **self.vec;
                  // memmove back untouched tail, update to new length
                  let start = source_vec.len();
                  let tail = self.tail_start;