]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #22669 - dotdash:fast_slice_iter, r=huonw
authorbors <bors@rust-lang.org>
Sat, 28 Feb 2015 03:37:20 +0000 (03:37 +0000)
committerbors <bors@rust-lang.org>
Sat, 28 Feb 2015 03:37:20 +0000 (03:37 +0000)
This adds the assume() calls back that got lost when rebasing #21886.

1  2 
src/libcollections/vec.rs
src/libcore/slice.rs

index 78ab9b6ab9bad15d8cce464a09cc6b0d45926fe4,404c2fc8e8f3fe555968ee023b0226e935806bfb..805e4623396b849b22041fc1281d42b3406f7067
@@@ -93,7 -93,7 +93,7 @@@ use borrow::{Cow, IntoCow}
  /// for x in vec.iter() {
  ///     println!("{}", x);
  /// }
 -/// assert_eq!(vec, vec![7, 1, 2, 3]);
 +/// assert_eq!(vec, [7, 1, 2, 3]);
  /// ```
  ///
  /// The `vec!` macro is provided to make initialization more convenient:
  /// ```
  /// let mut vec = vec![1, 2, 3];
  /// vec.push(4);
 -/// assert_eq!(vec, vec![1, 2, 3, 4]);
 +/// assert_eq!(vec, [1, 2, 3, 4]);
  /// ```
  ///
  /// Use a `Vec<T>` as an efficient stack:
@@@ -242,7 -242,7 +242,7 @@@ impl<T> Vec<T> 
      ///
      ///         // Put everything back together into a Vec
      ///         let rebuilt = Vec::from_raw_parts(p, len, cap);
 -    ///         assert_eq!(rebuilt, vec![4, 5, 6]);
 +    ///         assert_eq!(rebuilt, [4, 5, 6]);
      ///     }
      /// }
      /// ```
      pub unsafe fn from_raw_buf(ptr: *const T, elts: usize) -> Vec<T> {
          let mut dst = Vec::with_capacity(elts);
          dst.set_len(elts);
 -        ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
 +        ptr::copy_nonoverlapping(dst.as_mut_ptr(), ptr, elts);
          dst
      }
  
      pub fn into_boxed_slice(mut self) -> Box<[T]> {
          self.shrink_to_fit();
          unsafe {
 -            let xs: Box<[T]> = mem::transmute(&mut *self);
 +            let xs: Box<[T]> = Box::from_raw(&mut *self);
              mem::forget(self);
              xs
          }
      /// ```
      /// let mut vec = vec![1, 2, 3, 4];
      /// vec.truncate(2);
 -    /// assert_eq!(vec, vec![1, 2]);
 +    /// assert_eq!(vec, [1, 2]);
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn truncate(&mut self, len: usize) {
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn as_mut_slice(&mut self) -> &mut [T] {
          unsafe {
+             let ptr = *self.ptr;
+             assume(!ptr.is_null());
              mem::transmute(RawSlice {
-                 data: *self.ptr,
+                 data: ptr,
                  len: self.len,
              })
          }
      pub fn into_iter(self) -> IntoIter<T> {
          unsafe {
              let ptr = *self.ptr;
+             assume(!ptr.is_null());
              let cap = self.cap;
              let begin = ptr as *const T;
              let end = if mem::size_of::<T>() == 0 {
      /// let mut v = vec!["foo", "bar", "baz", "qux"];
      ///
      /// assert_eq!(v.swap_remove(1), "bar");
 -    /// assert_eq!(v, vec!["foo", "qux", "baz"]);
 +    /// assert_eq!(v, ["foo", "qux", "baz"]);
      ///
      /// assert_eq!(v.swap_remove(0), "foo");
 -    /// assert_eq!(v, vec!["baz", "qux"]);
 +    /// assert_eq!(v, ["baz", "qux"]);
      /// ```
      #[inline]
      #[stable(feature = "rust1", since = "1.0.0")]
      /// ```
      /// let mut vec = vec![1, 2, 3];
      /// vec.insert(1, 4);
 -    /// assert_eq!(vec, vec![1, 4, 2, 3]);
 +    /// assert_eq!(vec, [1, 4, 2, 3]);
      /// vec.insert(4, 5);
 -    /// assert_eq!(vec, vec![1, 4, 2, 3, 5]);
 +    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn insert(&mut self, index: usize, element: T) {
                  let p = self.as_mut_ptr().offset(index as isize);
                  // Shift everything over to make space. (Duplicating the
                  // `index`th element into two consecutive places.)
 -                ptr::copy_memory(p.offset(1), &*p, len - index);
 +                ptr::copy(p.offset(1), &*p, len - index);
                  // Write it in, overwriting the first copy of the `index`th
                  // element.
                  ptr::write(&mut *p, element);
      /// ```
      /// let mut v = vec![1, 2, 3];
      /// assert_eq!(v.remove(1), 2);
 -    /// assert_eq!(v, vec![1, 3]);
 +    /// assert_eq!(v, [1, 3]);
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn remove(&mut self, index: usize) -> T {
                  ret = ptr::read(ptr);
  
                  // Shift everything down to fill in that spot.
 -                ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
 +                ptr::copy(ptr, &*ptr.offset(1), len - index - 1);
              }
              self.set_len(len - 1);
              ret
      /// ```
      /// let mut vec = vec![1, 2, 3, 4];
      /// vec.retain(|&x| x%2 == 0);
 -    /// assert_eq!(vec, vec![2, 4]);
 +    /// assert_eq!(vec, [2, 4]);
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
      /// ```rust
      /// let mut vec = vec!(1, 2);
      /// vec.push(3);
 -    /// assert_eq!(vec, vec!(1, 2, 3));
 +    /// assert_eq!(vec, [1, 2, 3]);
      /// ```
      #[inline]
      #[stable(feature = "rust1", since = "1.0.0")]
      /// ```rust
      /// let mut vec = vec![1, 2, 3];
      /// assert_eq!(vec.pop(), Some(3));
 -    /// assert_eq!(vec, vec![1, 2]);
 +    /// assert_eq!(vec, [1, 2]);
      /// ```
      #[inline]
      #[stable(feature = "rust1", since = "1.0.0")]
      /// let mut vec = vec![1, 2, 3];
      /// let mut vec2 = vec![4, 5, 6];
      /// vec.append(&mut vec2);
 -    /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]);
 -    /// assert_eq!(vec2, vec![]);
 +    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
 +    /// assert_eq!(vec2, []);
      /// ```
      #[inline]
      #[unstable(feature = "collections",
          self.reserve(other.len());
          let len = self.len();
          unsafe {
 -            ptr::copy_nonoverlapping_memory(
 +            ptr::copy_nonoverlapping(
                  self.get_unchecked_mut(len),
                  other.as_ptr(),
                  other.len());
      /// ```
      /// let mut vec = vec![1,2,3];
      /// let vec2 = vec.split_off(1);
 -    /// assert_eq!(vec, vec![1]);
 -    /// assert_eq!(vec2, vec![2, 3]);
 +    /// assert_eq!(vec, [1]);
 +    /// assert_eq!(vec2, [2, 3]);
      /// ```
      #[inline]
      #[unstable(feature = "collections",
              self.set_len(at);
              other.set_len(other_len);
  
 -            ptr::copy_nonoverlapping_memory(
 +            ptr::copy_nonoverlapping(
                  other.as_mut_ptr(),
                  self.as_ptr().offset(at as isize),
                  other.len());
@@@ -1057,11 -1060,11 +1060,11 @@@ impl<T: Clone> Vec<T> 
      /// ```
      /// let mut vec = vec!["hello"];
      /// vec.resize(3, "world");
 -    /// assert_eq!(vec, vec!["hello", "world", "world"]);
 +    /// assert_eq!(vec, ["hello", "world", "world"]);
      ///
      /// let mut vec = vec![1, 2, 3, 4];
      /// vec.resize(2, 0);
 -    /// assert_eq!(vec, vec![1, 2]);
 +    /// assert_eq!(vec, [1, 2]);
      /// ```
      #[unstable(feature = "collections",
                 reason = "matches collection reform specification; waiting for dust to settle")]
      /// ```
      /// let mut vec = vec![1];
      /// vec.push_all(&[2, 3, 4]);
 -    /// assert_eq!(vec, vec![1, 2, 3, 4]);
 +    /// assert_eq!(vec, [1, 2, 3, 4]);
      /// ```
      #[inline]
      #[unstable(feature = "collections",
@@@ -1121,7 -1124,7 +1124,7 @@@ impl<T: PartialEq> Vec<T> 
      ///
      /// vec.dedup();
      ///
 -    /// assert_eq!(vec, vec![1, 2, 3, 2]);
 +    /// assert_eq!(vec, [1, 2, 3, 2]);
      /// ```
      #[stable(feature = "rust1", since = "1.0.0")]
      pub fn dedup(&mut self) {
@@@ -1493,34 -1496,69 +1496,34 @@@ impl<T> Extend<T> for Vec<T> 
      }
  }
  
 -impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
 -    #[inline]
 -    fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
 -    #[inline]
 -    fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
 -}
 -
 -macro_rules! impl_eq {
 -    ($lhs:ty, $rhs:ty) => {
 -        impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq<B> {
 -            #[inline]
 -            fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
 -            #[inline]
 -            fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
 -        }
 -
 -        impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq<A> {
 -            #[inline]
 -            fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
 -            #[inline]
 -            fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
 -        }
 +__impl_slice_eq1! { Vec<A>, Vec<B> }
 +__impl_slice_eq2! { Vec<A>, &'b [B] }
 +__impl_slice_eq2! { Vec<A>, &'b mut [B] }
 +__impl_slice_eq2! { CowVec<'a, A>, &'b [B], Clone }
 +__impl_slice_eq2! { CowVec<'a, A>, &'b mut [B], Clone }
 +__impl_slice_eq2! { CowVec<'a, A>, Vec<B>, Clone }
 +
 +macro_rules! array_impls {
 +    ($($N: expr)+) => {
 +        $(
 +            // NOTE: some less important impls are omitted to reduce code bloat
 +            __impl_slice_eq2! { Vec<A>, [B; $N] }
 +            __impl_slice_eq2! { Vec<A>, &'b [B; $N] }
 +            // __impl_slice_eq2! { Vec<A>, &'b mut [B; $N] }
 +            // __impl_slice_eq2! { CowVec<'a, A>, [B; $N], Clone }
 +            // __impl_slice_eq2! { CowVec<'a, A>, &'b [B; $N], Clone }
 +            // __impl_slice_eq2! { CowVec<'a, A>, &'b mut [B; $N], Clone }
 +        )+
      }
  }
  
 -impl_eq! { Vec<A>, &'b [B] }
 -impl_eq! { Vec<A>, &'b mut [B] }
 -
 -impl<'a, A, B> PartialEq<Vec<B>> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
 -    #[inline]
 -    fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
 -    #[inline]
 -    fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
 -}
 -
 -impl<'a, A, B> PartialEq<Cow<'a, [A]>> for Vec<B> where A: Clone, B: PartialEq<A> {
 -    #[inline]
 -    fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
 -    #[inline]
 -    fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
 -}
 -
 -macro_rules! impl_eq_for_cowvec {
 -    ($rhs:ty) => {
 -        impl<'a, 'b, A, B> PartialEq<$rhs> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
 -            #[inline]
 -            fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
 -            #[inline]
 -            fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
 -        }
 -
 -        impl<'a, 'b, A, B> PartialEq<Cow<'a, [A]>> for $rhs where A: Clone, B: PartialEq<A> {
 -            #[inline]
 -            fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
 -            #[inline]
 -            fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
 -        }
 -    }
 +array_impls! {
 +     0  1  2  3  4  5  6  7  8  9
 +    10 11 12 13 14 15 16 17 18 19
 +    20 21 22 23 24 25 26 27 28 29
 +    30 31 32
  }
  
 -impl_eq_for_cowvec! { &'b [B] }
 -impl_eq_for_cowvec! { &'b mut [B] }
 -
  #[stable(feature = "rust1", since = "1.0.0")]
  impl<T: PartialOrd> PartialOrd for Vec<T> {
      #[inline]
@@@ -1755,9 -1793,6 +1758,9 @@@ pub struct Drain<'a, T:'a> 
      marker: PhantomData<&'a T>,
  }
  
 +unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
 +unsafe impl<'a, T: Send> Send for Drain<'a, T> {}
 +
  #[stable(feature = "rust1", since = "1.0.0")]
  impl<'a, T> Iterator for Drain<'a, T> {
      type Item = T;
@@@ -2093,7 -2128,7 +2096,7 @@@ mod tests 
              let (left, right) = values.split_at_mut(2);
              {
                  let left: &[_] = left;
 -                assert!(&left[..left.len()] == &[1, 2][]);
 +                assert!(&left[..left.len()] == &[1, 2]);
              }
              for p in left {
                  *p += 1;
  
              {
                  let right: &[_] = right;
 -                assert!(&right[..right.len()] == &[3, 4, 5][]);
 +                assert!(&right[..right.len()] == &[3, 4, 5]);
              }
              for p in right {
                  *p += 2;
              }
          }
  
 -        assert!(values == vec![2, 3, 5, 6, 7]);
 +        assert_eq!(values, [2, 3, 5, 6, 7]);
      }
  
      #[test]
      fn test_retain() {
          let mut vec = vec![1, 2, 3, 4];
          vec.retain(|&x| x % 2 == 0);
 -        assert!(vec == vec![2, 4]);
 +        assert_eq!(vec, [2, 4]);
      }
  
      #[test]
              let a = [1, 2, 3];
              let ptr = a.as_ptr();
              let b = Vec::from_raw_buf(ptr, 3);
 -            assert_eq!(b, vec![1, 2, 3]);
 +            assert_eq!(b, [1, 2, 3]);
  
              // Test on-heap copy-from-buf.
              let c = vec![1, 2, 3, 4, 5];
              let ptr = c.as_ptr();
              let d = Vec::from_raw_buf(ptr, 5);
 -            assert_eq!(d, vec![1, 2, 3, 4, 5]);
 +            assert_eq!(d, [1, 2, 3, 4, 5]);
          }
      }
  
          for i in vec {
              vec2.push(i);
          }
 -        assert!(vec2 == vec![1, 2, 3]);
 +        assert_eq!(vec2, [1, 2, 3]);
      }
  
      #[test]
          for i in vec.into_iter().rev() {
              vec2.push(i);
          }
 -        assert!(vec2 == vec![3, 2, 1]);
 +        assert_eq!(vec2, [3, 2, 1]);
      }
  
      #[test]
          for i in vec {
              vec2.push(i);
          }
 -        assert!(vec2 == vec![(), (), ()]);
 +        assert_eq!(vec2, [(), (), ()]);
      }
  
      #[test]
      fn test_into_boxed_slice() {
          let xs = vec![1, 2, 3];
          let ys = xs.into_boxed_slice();
 -        assert_eq!(ys, [1, 2, 3]);
 +        assert_eq!(&*ys, [1, 2, 3]);
      }
  
      #[test]
          let mut vec = vec![1, 2, 3];
          let mut vec2 = vec![4, 5, 6];
          vec.append(&mut vec2);
 -        assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]);
 -        assert_eq!(vec2, vec![]);
 +        assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
 +        assert_eq!(vec2, []);
      }
  
      #[test]
      fn test_split_off() {
          let mut vec = vec![1, 2, 3, 4, 5, 6];
          let vec2 = vec.split_off(4);
 -        assert_eq!(vec, vec![1, 2, 3, 4]);
 -        assert_eq!(vec2, vec![5, 6]);
 +        assert_eq!(vec, [1, 2, 3, 4]);
 +        assert_eq!(vec2, [5, 6]);
      }
  
      #[bench]
diff --combined src/libcore/slice.rs
index 91cad4330f20464441fdf623ee39219dcf81f58c,6774906516ad01f8db7f6c96766397e04e9ea2e5..5b78da34eddde0e7dd363383b3fd0d4b719c5640
@@@ -40,6 -40,7 +40,7 @@@ use cmp::{Ordering, PartialEq, PartialO
  use cmp::Ordering::{Less, Equal, Greater};
  use cmp;
  use default::Default;
+ use intrinsics::assume;
  use iter::*;
  use ops::{FnMut, self, Index};
  use ops::RangeFull;
@@@ -51,7 -52,7 +52,7 @@@ use ptr
  use ptr::PtrExt;
  use mem;
  use mem::size_of;
 -use marker::{Sized, self};
 +use marker::{Send, Sized, Sync, self};
  use raw::Repr;
  // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
  use raw::Slice as RawSlice;
@@@ -137,6 -138,7 +138,7 @@@ impl<T> SliceExt for [T] 
      fn iter<'a>(&'a self) -> Iter<'a, T> {
          unsafe {
              let p = self.as_ptr();
+             assume(!p.is_null());
              if mem::size_of::<T>() == 0 {
                  Iter {ptr: p,
                        end: (p as usize + self.len()) as *const T,
      fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
          unsafe {
              let p = self.as_mut_ptr();
+             assume(!p.is_null());
              if mem::size_of::<T>() == 0 {
                  IterMut {ptr: p,
                           end: (p as usize + self.len()) as *mut T,
@@@ -657,8 -660,6 +660,8 @@@ macro_rules! iterator 
              fn next(&mut self) -> Option<$elem> {
                  // could be implemented with slices, but this avoids bounds checks
                  unsafe {
 +                    ::intrinsics::assume(!self.ptr.is_null());
 +                    ::intrinsics::assume(!self.end.is_null());
                      if self.ptr == self.end {
                          None
                      } else {
              fn next_back(&mut self) -> Option<$elem> {
                  // could be implemented with slices, but this avoids bounds checks
                  unsafe {
 +                    ::intrinsics::assume(!self.ptr.is_null());
 +                    ::intrinsics::assume(!self.end.is_null());
                      if self.end == self.ptr {
                          None
                      } else {
@@@ -740,9 -739,6 +743,9 @@@ pub struct Iter<'a, T: 'a> 
      _marker: marker::PhantomData<&'a T>,
  }
  
 +unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {}
 +unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
 +
  #[unstable(feature = "core")]
  impl<'a, T> ops::Index<ops::Range<usize>> for Iter<'a, T> {
      type Output = [T];
@@@ -833,8 -829,6 +836,8 @@@ pub struct IterMut<'a, T: 'a> 
      _marker: marker::PhantomData<&'a mut T>,
  }
  
 +unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
 +unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
  
  #[unstable(feature = "core")]
  impl<'a, T> ops::Index<ops::Range<usize>> for IterMut<'a, T> {
@@@ -1505,7 -1499,7 +1508,7 @@@ pub mod bytes 
      impl MutableByteVector for [u8] {
          #[inline]
          fn set_memory(&mut self, value: u8) {
 -            unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
 +            unsafe { ptr::write_bytes(self.as_mut_ptr(), value, self.len()) };
          }
      }
  
          // `dst` is unaliasable, so we know statically it doesn't overlap
          // with `src`.
          unsafe {
 -            ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(),
 -                                            src.as_ptr(),
 -                                            len_src);
 +            ptr::copy_nonoverlapping(dst.as_mut_ptr(),
 +                                     src.as_ptr(),
 +                                     len_src);
          }
      }
  }