From b1976f1f6e467b83d9f91d141924d05b8e580257 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 30 Apr 2015 15:24:39 -0700
Subject: [PATCH] std: Remove index notation on slice iterators

These implementations were intended to be unstable, but currently the stability
attributes cannot handle a stable trait with an unstable `impl` block. This
commit also audits the rest of the standard library for explicitly-`#[unstable]`
impl blocks. No others were removed but some annotations were changed to
`#[stable]` as they're defacto stable anyway.

One particularly interesting `impl` marked `#[stable]` as part of this commit
is the `Add<&[T]>` impl for `Vec<T>`, which uses `push_all` and implicitly
clones all elements of the vector provided.

Closes #24791
---
 src/libcollections/string.rs       |  21 +++---
 src/libcollections/vec.rs          |   9 ++-
 src/libcore/iter.rs                |  13 ++--
 src/libcore/slice.rs               | 110 -----------------------------
 src/libcoretest/slice.rs           |  49 -------------
 src/librustc_driver/lib.rs         |  10 +--
 src/libstd/collections/hash/map.rs |   3 +-
 src/libstd/io/buffered.rs          |   6 +-
 src/libstd/net/parser.rs           |   2 +-
 9 files changed, 30 insertions(+), 193 deletions(-)

diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index be6405dc85a..5b7d05db27f 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -740,8 +740,7 @@ impl<'a> FromIterator<&'a str> for String {
     }
 }
 
-#[unstable(feature = "collections",
-           reason = "waiting on Extend stabilization")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Extend<char> for String {
     fn extend<I: IntoIterator<Item=char>>(&mut self, iterable: I) {
         let iterator = iterable.into_iter();
@@ -753,8 +752,7 @@ impl Extend<char> for String {
     }
 }
 
-#[unstable(feature = "collections",
-           reason = "waiting on Extend stabilization")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Extend<&'a str> for String {
     fn extend<I: IntoIterator<Item=&'a str>>(&mut self, iterable: I) {
         let iterator = iterable.into_iter();
@@ -869,8 +867,7 @@ impl hash::Hash for String {
     }
 }
 
-#[unstable(feature = "collections",
-           reason = "recent addition, needs more experience")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Add<&'a str> for String {
     type Output = String;
 
@@ -964,11 +961,17 @@ pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
     DerefString { x: as_vec(x.as_bytes()) }
 }
 
-#[unstable(feature = "collections", reason = "associated error type may change")]
+/// Error returned from `String::from_str`
+#[unstable(feature = "str_parse_error", reason = "may want to be replaced with \
+                                                  Void if it ever exists")]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct ParseError(());
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for String {
-    type Err = ();
+    type Err = ParseError;
     #[inline]
-    fn from_str(s: &str) -> Result<String, ()> {
+    fn from_str(s: &str) -> Result<String, ParseError> {
         Ok(String::from_str(s))
     }
 }
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 4f0b17a563b..33de6b79736 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1299,7 +1299,7 @@ pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
 // Common trait implementations for Vec
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T:Clone> Clone for Vec<T> {
     #[cfg(not(test))]
     fn clone(&self) -> Vec<T> { <[T]>::to_vec(&**self) }
@@ -1554,7 +1554,7 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
     }
 }
 
-#[unstable(feature = "collections", reason = "waiting on Extend stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Extend<T> for Vec<T> {
     #[inline]
     fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
@@ -1614,8 +1614,7 @@ impl<T: Ord> Ord for Vec<T> {
     }
 }
 
-#[unstable(feature = "collections",
-           reason = "recent addition, needs more experience")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: Clone> Add<&'a [T]> for Vec<T> {
     type Output = Vec<T>;
 
@@ -1694,7 +1693,7 @@ impl<'a> From<&'a str> for Vec<u8> {
 // Clone-on-write
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
     fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Cow<'a, [T]> {
         Cow::Owned(FromIterator::from_iter(it))
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 0fa27a4312d..a9b99c33ee5 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -626,12 +626,10 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert!(it.any(|x| *x == 3));
-    /// assert_eq!(&it[..], [4, 5]);
-    ///
+    /// assert_eq!(it.collect::<Vec<_>>(), [&4, &5]);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -654,11 +652,10 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.find(|&x| *x == 3).unwrap(), &3);
-    /// assert_eq!(&it[..], [4, 5]);
+    /// assert_eq!(it.collect::<Vec<_>>(), [&4, &5]);
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
@@ -678,11 +675,10 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.position(|x| *x == 3).unwrap(), 2);
-    /// assert_eq!(&it[..], [4, 5]);
+    /// assert_eq!(it.collect::<Vec<_>>(), [&4, &5]);
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
@@ -708,11 +704,10 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(core)]
     /// let a = [1, 2, 2, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.rposition(|x| *x == 2).unwrap(), 2);
-    /// assert_eq!(&it[..], [1, 2]);
+    /// assert_eq!(it.collect::<Vec<_>>(), [&1, &2]);
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 38e66c5a3d6..f0accef92ce 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -762,46 +762,6 @@ pub struct Iter<'a, T: 'a> {
 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];
-
-    #[inline]
-    fn index(&self, index: ops::Range<usize>) -> &[T] {
-        self.as_slice().index(index)
-    }
-}
-
-#[unstable(feature = "core")]
-impl<'a, T> ops::Index<ops::RangeTo<usize>> for Iter<'a, T> {
-    type Output = [T];
-
-    #[inline]
-    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
-        self.as_slice().index(index)
-    }
-}
-
-#[unstable(feature = "core")]
-impl<'a, T> ops::Index<ops::RangeFrom<usize>> for Iter<'a, T> {
-    type Output = [T];
-
-    #[inline]
-    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
-        self.as_slice().index(index)
-    }
-}
-
-#[unstable(feature = "core")]
-impl<'a, T> ops::Index<RangeFull> for Iter<'a, T> {
-    type Output = [T];
-
-    #[inline]
-    fn index(&self, _index: RangeFull) -> &[T] {
-        self.as_slice()
-    }
-}
-
 impl<'a, T> Iter<'a, T> {
     /// View the underlying data as a subslice of the original data.
     ///
@@ -873,76 +833,6 @@ pub struct IterMut<'a, T: 'a> {
 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> {
-    type Output = [T];
-
-    #[inline]
-    fn index(&self, index: ops::Range<usize>) -> &[T] {
-        self.index(RangeFull).index(index)
-    }
-}
-#[unstable(feature = "core")]
-impl<'a, T> ops::Index<ops::RangeTo<usize>> for IterMut<'a, T> {
-    type Output = [T];
-
-    #[inline]
-    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
-        self.index(RangeFull).index(index)
-    }
-}
-#[unstable(feature = "core")]
-impl<'a, T> ops::Index<ops::RangeFrom<usize>> for IterMut<'a, T> {
-    type Output = [T];
-
-    #[inline]
-    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
-        self.index(RangeFull).index(index)
-    }
-}
-#[unstable(feature = "core")]
-impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
-    type Output = [T];
-
-    #[inline]
-    fn index(&self, _index: RangeFull) -> &[T] {
-        make_slice!(T => &[T]: self.ptr, self.end)
-    }
-}
-
-#[unstable(feature = "core")]
-impl<'a, T> ops::IndexMut<ops::Range<usize>> for IterMut<'a, T> {
-    #[inline]
-    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
-        self.index_mut(RangeFull).index_mut(index)
-    }
-}
-#[unstable(feature = "core")]
-impl<'a, T> ops::IndexMut<ops::RangeTo<usize>> for IterMut<'a, T> {
-
-    #[inline]
-    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
-        self.index_mut(RangeFull).index_mut(index)
-    }
-}
-#[unstable(feature = "core")]
-impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> {
-
-    #[inline]
-    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
-        self.index_mut(RangeFull).index_mut(index)
-    }
-}
-#[unstable(feature = "core")]
-impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
-
-    #[inline]
-    fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
-        make_mut_slice!(T => &mut [T]: self.ptr, self.end)
-    }
-}
-
-
 impl<'a, T> IterMut<'a, T> {
     /// View the underlying data as a subslice of the original data.
     ///
diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs
index 7c884a73ce0..5a1166aeb50 100644
--- a/src/libcoretest/slice.rs
+++ b/src/libcoretest/slice.rs
@@ -34,55 +34,6 @@ fn binary_search_not_found() {
     assert!(b.binary_search_by(|v| v.cmp(&9)) == Err(6));
 }
 
-#[test]
-fn iterator_to_slice() {
-    macro_rules! test {
-        ($data: expr) => {{
-            let data: &mut [_] = &mut $data;
-            let other_data: &mut [_] = &mut $data;
-
-            {
-                let mut iter = data.iter();
-                assert_eq!(&iter[..], &other_data[..]);
-
-                iter.next();
-                assert_eq!(&iter[..], &other_data[1..]);
-
-                iter.next_back();
-                assert_eq!(&iter[..], &other_data[1..2]);
-
-                let s = iter.as_slice();
-                iter.next();
-                assert_eq!(s, &other_data[1..2]);
-            }
-            {
-                let mut iter = data.iter_mut();
-                assert_eq!(&iter[..], &other_data[..]);
-                // mutability:
-                assert!(&mut iter[..] == other_data);
-
-                iter.next();
-                assert_eq!(&iter[..], &other_data[1..]);
-                assert!(&mut iter[..] == &mut other_data[1..]);
-
-                iter.next_back();
-
-                assert_eq!(&iter[..], &other_data[1..2]);
-                assert!(&mut iter[..] == &mut other_data[1..2]);
-
-                let s = iter.into_slice();
-                assert!(s == &mut other_data[1..2]);
-            }
-        }}
-    }
-
-    // try types of a variety of sizes
-    test!([(1u64, 1u64, 1u8), (2, 2, 2), (3, 3, 3)]);
-    test!([1u64,2,3]);
-    test!([1u8,2,3]);
-    test!([(),(),()]);
-}
-
 #[test]
 fn test_iterator_nth() {
     let v: &[_] = &[0, 1, 2, 3, 4];
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 8dff0f1d3f4..a618f4b6ef6 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -852,11 +852,11 @@ pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
 pub fn diagnostics_registry() -> diagnostics::registry::Registry {
     use syntax::diagnostics::registry::Registry;
 
-    let all_errors = Vec::new() +
-        &rustc::DIAGNOSTICS[..] +
-        &rustc_typeck::DIAGNOSTICS[..] +
-        &rustc_borrowck::DIAGNOSTICS[..] +
-        &rustc_resolve::DIAGNOSTICS[..];
+    let mut all_errors = Vec::new();
+    all_errors.push_all(&rustc::DIAGNOSTICS);
+    all_errors.push_all(&rustc_typeck::DIAGNOSTICS);
+    all_errors.push_all(&rustc_borrowck::DIAGNOSTICS);
+    all_errors.push_all(&rustc_resolve::DIAGNOSTICS);
 
     Registry::new(&*all_errors)
 }
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 9ba90c470f8..ec130e8233a 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1605,8 +1605,7 @@ impl HashState for RandomState {
     }
 }
 
-#[unstable(feature = "std_misc",
-           reason = "hashing an hash maps may be altered")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Default for RandomState {
     #[inline]
     fn default() -> RandomState {
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index ed6023b2b81..30a61e66dd2 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -118,7 +118,7 @@ impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug {
     }
 }
 
-#[unstable(feature = "buf_seek", reason = "recently added")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Seek> Seek for BufReader<R> {
     /// Seek to an offset, in bytes, in the underlying reader.
     ///
@@ -282,8 +282,8 @@ impl<W: Write> fmt::Debug for BufWriter<W> where W: fmt::Debug {
     }
 }
 
-#[unstable(feature = "buf_seek", reason = "recently added")]
-impl<W: Write+Seek> Seek for BufWriter<W> {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<W: Write + Seek> Seek for BufWriter<W> {
     /// Seek to the offset, in bytes, in the underlying writer.
     ///
     /// Seeking always writes out the internal buffer before seeking.
diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs
index 7c1667a603f..88cfc5a7b2d 100644
--- a/src/libstd/net/parser.rs
+++ b/src/libstd/net/parser.rs
@@ -291,7 +291,7 @@ impl<'a> Parser<'a> {
     }
 }
 
-#[unstable(feature = "ip_addr", reason = "recent addition")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for IpAddr {
     type Err = AddrParseError;
     fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {