about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-10-02 23:42:31 +0000
committerbors <bors@rust-lang.org>2014-10-02 23:42:31 +0000
commitd0af3feebb57bc58c52de69ab51f92dc7082500b (patch)
treed39de6be5866c0f0f37f9f3219b8217c873d8b52 /src/libcore
parentb2d4eb186e99b66051be9089f836c66a558dd995 (diff)
parentd2ea0315e09cbd495a67c9e3d5053b57e2b5a8b7 (diff)
downloadrust-d0af3feebb57bc58c52de69ab51f92dc7082500b.tar.gz
rust-d0af3feebb57bc58c52de69ab51f92dc7082500b.zip
auto merge of #17715 : aturon/rust/revert-slice-ops-libs, r=alexcrichton
This PR reverts https://github.com/rust-lang/rust/pull/17620, which caused a significant regression for slices.

As discussed with @alexcrichton, all of the public-facing changes of the earlier PR need to be rolled back, and it's not clear that we should move the libraries over to this new notation yet anyway (especially given its feature-gated status).

Closes #17710
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/fmt/float.rs8
-rw-r--r--src/libcore/fmt/mod.rs8
-rw-r--r--src/libcore/fmt/num.rs4
-rw-r--r--src/libcore/lib.rs3
-rw-r--r--src/libcore/ops.rs57
-rw-r--r--src/libcore/slice.rs217
-rw-r--r--src/libcore/str.rs100
7 files changed, 191 insertions, 206 deletions
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 343ab7cfd28..92ef0c281f2 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -17,7 +17,7 @@ use iter::{range, DoubleEndedIterator};
 use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive};
 use num::{Zero, One, cast};
 use result::Ok;
-use slice::MutableSlice;
+use slice::{ImmutableSlice, MutableSlice};
 use slice;
 use str::StrSlice;
 
@@ -173,7 +173,7 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
         _ => ()
     }
 
-    buf[mut ..end].reverse();
+    buf.slice_to_mut(end).reverse();
 
     // Remember start of the fractional digits.
     // Points one beyond end of buf if none get generated,
@@ -310,7 +310,7 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
 
             impl<'a> fmt::FormatWriter for Filler<'a> {
                 fn write(&mut self, bytes: &[u8]) -> fmt::Result {
-                    slice::bytes::copy_memory(self.buf[mut *self.end..],
+                    slice::bytes::copy_memory(self.buf.slice_from_mut(*self.end),
                                               bytes);
                     *self.end += bytes.len();
                     Ok(())
@@ -328,5 +328,5 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
         }
     }
 
-    f(buf[..end])
+    f(buf.slice_to(end))
 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 28ee522346f..7bab59960b0 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -423,7 +423,7 @@ impl<'a> Formatter<'a> {
             for c in sign.into_iter() {
                 let mut b = [0, ..4];
                 let n = c.encode_utf8(b).unwrap_or(0);
-                try!(f.buf.write(b[..n]));
+                try!(f.buf.write(b.slice_to(n)));
             }
             if prefixed { f.buf.write(prefix.as_bytes()) }
             else { Ok(()) }
@@ -530,13 +530,13 @@ impl<'a> Formatter<'a> {
         let len = self.fill.encode_utf8(fill).unwrap_or(0);
 
         for _ in range(0, pre_pad) {
-            try!(self.buf.write(fill[..len]));
+            try!(self.buf.write(fill.slice_to(len)));
         }
 
         try!(f(self));
 
         for _ in range(0, post_pad) {
-            try!(self.buf.write(fill[..len]));
+            try!(self.buf.write(fill.slice_to(len)));
         }
 
         Ok(())
@@ -611,7 +611,7 @@ impl Char for char {
 
         let mut utf8 = [0u8, ..4];
         let amt = self.encode_utf8(utf8).unwrap_or(0);
-        let s: &str = unsafe { mem::transmute(utf8[..amt]) };
+        let s: &str = unsafe { mem::transmute(utf8.slice_to(amt)) };
         secret_string(&s, f)
     }
 }
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index e57c4999483..afcd0d1d645 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -18,7 +18,7 @@ use collections::Collection;
 use fmt;
 use iter::DoubleEndedIterator;
 use num::{Int, cast, zero};
-use slice::{MutableSlice};
+use slice::{ImmutableSlice, MutableSlice};
 
 /// A type that represents a specific radix
 #[doc(hidden)]
@@ -60,7 +60,7 @@ trait GenericRadix {
                 if x == zero() { break; }                 // No more digits left to accumulate.
             }
         }
-        f.pad_integral(is_positive, self.prefix(), buf[curr..])
+        f.pad_integral(is_positive, self.prefix(), buf.slice_from(curr))
     }
 }
 
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 4890dc2bb73..7e2ea492d4c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -57,9 +57,8 @@
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![no_std]
-#![allow(unknown_features)]
 #![feature(globs, intrinsics, lang_items, macro_rules, managed_boxes, phase)]
-#![feature(simd, unsafe_destructor, slicing_syntax)]
+#![feature(simd, unsafe_destructor)]
 #![deny(missing_doc)]
 
 mod macros;
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 422c496995b..ad0f128a02e 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -684,23 +684,23 @@ pub trait IndexMut<Index, Result> {
  * A trivial implementation of `Slice`. When `Foo[..Foo]` happens, it ends up
  * calling `slice_to`, and therefore, `main` prints `Slicing!`.
  *
- * ```ignore
+ * ```
  * struct Foo;
  *
  * impl ::core::ops::Slice<Foo, Foo> for Foo {
- *     fn as_slice<'a>(&'a self) -> &'a Foo {
+ *     fn as_slice_<'a>(&'a self) -> &'a Foo {
  *         println!("Slicing!");
  *         self
  *     }
- *     fn slice_from<'a>(&'a self, from: &Foo) -> &'a Foo {
+ *     fn slice_from_<'a>(&'a self, from: &Foo) -> &'a Foo {
  *         println!("Slicing!");
  *         self
  *     }
- *     fn slice_to<'a>(&'a self, to: &Foo) -> &'a Foo {
+ *     fn slice_to_<'a>(&'a self, to: &Foo) -> &'a Foo {
  *         println!("Slicing!");
  *         self
  *     }
- *     fn slice<'a>(&'a self, from: &Foo, to: &Foo) -> &'a Foo {
+ *     fn slice_<'a>(&'a self, from: &Foo, to: &Foo) -> &'a Foo {
  *         println!("Slicing!");
  *         self
  *     }
@@ -711,22 +711,7 @@ pub trait IndexMut<Index, Result> {
  * }
  * ```
  */
-#[cfg(not(stage0))]
-#[lang="slice"]
-pub trait Slice<Idx, Sized? Result> for Sized? {
-    /// The method for the slicing operation foo[]
-    fn as_slice<'a>(&'a self) -> &'a Result;
-    /// The method for the slicing operation foo[from..]
-    fn slice_from<'a>(&'a self, from: &Idx) -> &'a Result;
-    /// The method for the slicing operation foo[..to]
-    fn slice_to<'a>(&'a self, to: &Idx) -> &'a Result;
-    /// The method for the slicing operation foo[from..to]
-    fn slice<'a>(&'a self, from: &Idx, to: &Idx) -> &'a Result;
-}
-/**
- *
- */
-#[cfg(stage0)]
+// FIXME(#17273) remove the postscript _s
 #[lang="slice"]
 pub trait Slice<Idx, Sized? Result> for Sized? {
     /// The method for the slicing operation foo[]
@@ -749,49 +734,34 @@ pub trait Slice<Idx, Sized? Result> for Sized? {
  * A trivial implementation of `SliceMut`. When `Foo[Foo..]` happens, it ends up
  * calling `slice_from_mut`, and therefore, `main` prints `Slicing!`.
  *
- * ```ignore
+ * ```
  * struct Foo;
  *
  * impl ::core::ops::SliceMut<Foo, Foo> for Foo {
- *     fn as_mut_slice<'a>(&'a mut self) -> &'a mut Foo {
+ *     fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo {
  *         println!("Slicing!");
  *         self
  *     }
- *     fn slice_from_mut<'a>(&'a mut self, from: &Foo) -> &'a mut Foo {
+ *     fn slice_from_mut_<'a>(&'a mut self, from: &Foo) -> &'a mut Foo {
  *         println!("Slicing!");
  *         self
  *     }
- *     fn slice_to_mut<'a>(&'a mut self, to: &Foo) -> &'a mut Foo {
+ *     fn slice_to_mut_<'a>(&'a mut self, to: &Foo) -> &'a mut Foo {
  *         println!("Slicing!");
  *         self
  *     }
- *     fn slice_mut<'a>(&'a mut self, from: &Foo, to: &Foo) -> &'a mut Foo {
+ *     fn slice_mut_<'a>(&'a mut self, from: &Foo, to: &Foo) -> &'a mut Foo {
  *         println!("Slicing!");
  *         self
  *     }
  * }
  *
- * pub fn main() {
+ * fn main() {
  *     Foo[mut Foo..];
  * }
  * ```
  */
-#[cfg(not(stage0))]
-#[lang="slice_mut"]
-pub trait SliceMut<Idx, Sized? Result> for Sized? {
-    /// The method for the slicing operation foo[]
-    fn as_mut_slice<'a>(&'a mut self) -> &'a mut Result;
-    /// The method for the slicing operation foo[from..]
-    fn slice_from_mut<'a>(&'a mut self, from: &Idx) -> &'a mut Result;
-    /// The method for the slicing operation foo[..to]
-    fn slice_to_mut<'a>(&'a mut self, to: &Idx) -> &'a mut Result;
-    /// The method for the slicing operation foo[from..to]
-    fn slice_mut<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result;
-}
-/**
- *
- */
-#[cfg(stage0)]
+// FIXME(#17273) remove the postscript _s
 #[lang="slice_mut"]
 pub trait SliceMut<Idx, Sized? Result> for Sized? {
     /// The method for the slicing operation foo[mut]
@@ -803,7 +773,6 @@ pub trait SliceMut<Idx, Sized? Result> for Sized? {
     /// The method for the slicing operation foo[mut from..to]
     fn slice_mut_<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result;
 }
-
 /**
  *
  * The `Deref` trait is used to specify the functionality of dereferencing
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index a8becb315b2..1a00107a216 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -61,6 +61,31 @@ use raw::Slice as RawSlice;
 /// Extension methods for immutable slices.
 #[unstable = "may merge with other traits; region parameter may disappear"]
 pub trait ImmutableSlice<'a, T> {
+    /// Returns a subslice spanning the interval [`start`, `end`).
+    ///
+    /// Fails when the end of the new slice lies beyond the end of the
+    /// original slice (i.e. when `end > self.len()`) or when `start > end`.
+    ///
+    /// Slicing with `start` equal to `end` yields an empty slice.
+    #[unstable = "waiting on final error conventions"]
+    fn slice(&self, start: uint, end: uint) -> &'a [T];
+
+    /// Returns a subslice from `start` to the end of the slice.
+    ///
+    /// Fails when `start` is strictly greater than the length of the original slice.
+    ///
+    /// Slicing from `self.len()` yields an empty slice.
+    #[unstable = "waiting on final error conventions"]
+    fn slice_from(&self, start: uint) -> &'a [T];
+
+    /// Returns a subslice from the start of the slice to `end`.
+    ///
+    /// Fails when `end` is strictly greater than the length of the original slice.
+    ///
+    /// Slicing to `0` yields an empty slice.
+    #[unstable = "waiting on final error conventions"]
+    fn slice_to(&self, end: uint) -> &'a [T];
+
     /// Divides one slice into two at an index.
     ///
     /// The first will contain all indices from `[0, mid)` (excluding
@@ -215,7 +240,7 @@ pub trait ImmutableSlice<'a, T> {
      * ```ignore
      *     if self.len() == 0 { return None }
      *     let head = &self[0];
-     *     *self = self[1..];
+     *     *self = self.slice_from(1);
      *     Some(head)
      * ```
      *
@@ -234,7 +259,7 @@ pub trait ImmutableSlice<'a, T> {
      * ```ignore
      *     if self.len() == 0 { return None; }
      *     let tail = &self[self.len() - 1];
-     *     *self = self[..self.len() - 1];
+     *     *self = self.slice_to(self.len() - 1);
      *     Some(tail)
      * ```
      *
@@ -247,8 +272,30 @@ pub trait ImmutableSlice<'a, T> {
 #[unstable]
 impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
     #[inline]
+    fn slice(&self, start: uint, end: uint) -> &'a [T] {
+        assert!(start <= end);
+        assert!(end <= self.len());
+        unsafe {
+            transmute(RawSlice {
+                    data: self.as_ptr().offset(start as int),
+                    len: (end - start)
+                })
+        }
+    }
+
+    #[inline]
+    fn slice_from(&self, start: uint) -> &'a [T] {
+        self.slice(start, self.len())
+    }
+
+    #[inline]
+    fn slice_to(&self, end: uint) -> &'a [T] {
+        self.slice(0, end)
+    }
+
+    #[inline]
     fn split_at(&self, mid: uint) -> (&'a [T], &'a [T]) {
-        ((*self)[..mid], (*self)[mid..])
+        (self.slice(0, mid), self.slice(mid, self.len()))
     }
 
     #[inline]
@@ -317,21 +364,21 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
     }
 
     #[inline]
-    fn tail(&self) -> &'a [T] { (*self)[1..] }
+    fn tail(&self) -> &'a [T] { self.slice(1, self.len()) }
 
     #[inline]
     #[deprecated = "use slice_from"]
-    fn tailn(&self, n: uint) -> &'a [T] { (*self)[n..] }
+    fn tailn(&self, n: uint) -> &'a [T] { self.slice(n, self.len()) }
 
     #[inline]
     fn init(&self) -> &'a [T] {
-        (*self)[..self.len() - 1]
+        self.slice(0, self.len() - 1)
     }
 
     #[inline]
     #[deprecated = "use slice_to but note the arguments are different"]
     fn initn(&self, n: uint) -> &'a [T] {
-        (*self)[..self.len() - n]
+        self.slice(0, self.len() - n)
     }
 
     #[inline]
@@ -417,35 +464,6 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
     }
 }
 
-#[cfg(not(stage0))]
-impl<T> ops::Slice<uint, [T]> for [T] {
-    #[inline]
-    fn as_slice<'a>(&'a self) -> &'a [T] {
-        self
-    }
-
-    #[inline]
-    fn slice_from<'a>(&'a self, start: &uint) -> &'a [T] {
-        self.slice(start, &self.len())
-    }
-
-    #[inline]
-    fn slice_to<'a>(&'a self, end: &uint) -> &'a [T] {
-        self.slice(&0, end)
-    }
-    #[inline]
-    fn slice<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
-        assert!(*start <= *end);
-        assert!(*end <= self.len());
-        unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(*start as int),
-                    len: (*end - *start)
-                })
-        }
-    }
-}
-#[cfg(stage0)]
 impl<T> ops::Slice<uint, [T]> for [T] {
     #[inline]
     fn as_slice_<'a>(&'a self) -> &'a [T] {
@@ -473,36 +491,7 @@ impl<T> ops::Slice<uint, [T]> for [T] {
         }
     }
 }
-#[cfg(not(stage0))]
-impl<T> ops::SliceMut<uint, [T]> for [T] {
-    #[inline]
-    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
-        self
-    }
 
-    #[inline]
-    fn slice_from_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
-        let len = &self.len();
-        self.slice_mut(start, len)
-    }
-
-    #[inline]
-    fn slice_to_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
-        self.slice_mut(&0, end)
-    }
-    #[inline]
-    fn slice_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
-        assert!(*start <= *end);
-        assert!(*end <= self.len());
-        unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(*start as int),
-                    len: (*end - *start)
-                })
-        }
-    }
-}
-#[cfg(stage0)]
 impl<T> ops::SliceMut<uint, [T]> for [T] {
     #[inline]
     fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
@@ -544,6 +533,49 @@ pub trait MutableSlice<'a, T> {
     /// Primarily intended for getting a &mut [T] from a [T, ..N].
     fn as_mut_slice(self) -> &'a mut [T];
 
+    /// Deprecated: use `slice_mut`.
+    #[deprecated = "use slice_mut"]
+    fn mut_slice(self, start: uint, end: uint) -> &'a mut [T] {
+        self.slice_mut(start, end)
+    }
+
+    /// Returns a mutable subslice spanning the interval [`start`, `end`).
+    ///
+    /// Fails when the end of the new slice lies beyond the end of the
+    /// original slice (i.e. when `end > self.len()`) or when `start > end`.
+    ///
+    /// Slicing with `start` equal to `end` yields an empty slice.
+    #[unstable = "waiting on final error conventions"]
+    fn slice_mut(self, start: uint, end: uint) -> &'a mut [T];
+
+    /// Deprecated: use `slice_from_mut`.
+    #[deprecated = "use slice_from_mut"]
+    fn mut_slice_from(self, start: uint) -> &'a mut [T] {
+        self.slice_from_mut(start)
+    }
+
+    /// Returns a mutable subslice from `start` to the end of the slice.
+    ///
+    /// Fails when `start` is strictly greater than the length of the original slice.
+    ///
+    /// Slicing from `self.len()` yields an empty slice.
+    #[unstable = "waiting on final error conventions"]
+    fn slice_from_mut(self, start: uint) -> &'a mut [T];
+
+    /// Deprecated: use `slice_to_mut`.
+    #[deprecated = "use slice_to_mut"]
+    fn mut_slice_to(self, end: uint) -> &'a mut [T] {
+        self.slice_to_mut(end)
+    }
+
+    /// Returns a mutable subslice from the start of the slice to `end`.
+    ///
+    /// Fails when `end` is strictly greater than the length of the original slice.
+    ///
+    /// Slicing to `0` yields an empty slice.
+    #[unstable = "waiting on final error conventions"]
+    fn slice_to_mut(self, end: uint) -> &'a mut [T];
+
     /// Deprecated: use `iter_mut`.
     #[deprecated = "use iter_mut"]
     fn mut_iter(self) -> MutItems<'a, T> {
@@ -627,7 +659,7 @@ pub trait MutableSlice<'a, T> {
      * ```ignore
      *     if self.len() == 0 { return None; }
      *     let head = &mut self[0];
-     *     *self = self[mut 1..];
+     *     *self = self.slice_from_mut(1);
      *     Some(head)
      * ```
      *
@@ -646,7 +678,7 @@ pub trait MutableSlice<'a, T> {
      * ```ignore
      *     if self.len() == 0 { return None; }
      *     let tail = &mut self[self.len() - 1];
-     *     *self = self[mut ..self.len() - 1];
+     *     *self = self.slice_to_mut(self.len() - 1);
      *     Some(tail)
      * ```
      *
@@ -771,11 +803,34 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
     #[inline]
     fn as_mut_slice(self) -> &'a mut [T] { self }
 
+    fn slice_mut(self, start: uint, end: uint) -> &'a mut [T] {
+        assert!(start <= end);
+        assert!(end <= self.len());
+        unsafe {
+            transmute(RawSlice {
+                    data: self.as_mut_ptr().offset(start as int) as *const T,
+                    len: (end - start)
+                })
+        }
+    }
+
+    #[inline]
+    fn slice_from_mut(self, start: uint) -> &'a mut [T] {
+        let len = self.len();
+        self.slice_mut(start, len)
+    }
+
+    #[inline]
+    fn slice_to_mut(self, end: uint) -> &'a mut [T] {
+        self.slice_mut(0, end)
+    }
+
     #[inline]
     fn split_at_mut(self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
         unsafe {
+            let len = self.len();
             let self2: &'a mut [T] = mem::transmute_copy(&self);
-            (self[mut ..mid], self2[mut mid..])
+            (self.slice_mut(0, mid), self2.slice_mut(mid, len))
         }
     }
 
@@ -812,13 +867,13 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
     #[inline]
     fn tail_mut(self) -> &'a mut [T] {
         let len = self.len();
-        self[mut 1..len]
+        self.slice_mut(1, len)
     }
 
     #[inline]
     fn init_mut(self) -> &'a mut [T] {
         let len = self.len();
-        self[mut 0..len - 1]
+        self.slice_mut(0, len - 1)
     }
 
     #[inline]
@@ -965,13 +1020,13 @@ impl<'a,T:PartialEq> ImmutablePartialEqSlice<T> for &'a [T] {
     #[inline]
     fn starts_with(&self, needle: &[T]) -> bool {
         let n = needle.len();
-        self.len() >= n && needle == (*self)[..n]
+        self.len() >= n && needle == self.slice_to(n)
     }
 
     #[inline]
     fn ends_with(&self, needle: &[T]) -> bool {
         let (m, n) = (self.len(), needle.len());
-        m >= n && needle == (*self)[m-n..]
+        m >= n && needle == self.slice_from(m - n)
     }
 }
 
@@ -1244,8 +1299,8 @@ impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
         match self.v.iter().position(|x| (self.pred)(x)) {
             None => self.finish(),
             Some(idx) => {
-                let ret = Some(self.v[..idx]);
-                self.v = self.v[idx + 1..];
+                let ret = Some(self.v.slice(0, idx));
+                self.v = self.v.slice(idx + 1, self.v.len());
                 ret
             }
         }
@@ -1270,8 +1325,8 @@ impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
         match self.v.iter().rposition(|x| (self.pred)(x)) {
             None => self.finish(),
             Some(idx) => {
-                let ret = Some(self.v[idx + 1..]);
-                self.v = self.v[..idx];
+                let ret = Some(self.v.slice(idx + 1, self.v.len()));
+                self.v = self.v.slice(0, idx);
                 ret
             }
         }
@@ -1321,7 +1376,7 @@ impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
             Some(idx) => {
                 let tmp = mem::replace(&mut self.v, &mut []);
                 let (head, tail) = tmp.split_at_mut(idx);
-                self.v = tail[mut 1..];
+                self.v = tail.slice_from_mut(1);
                 Some(head)
             }
         }
@@ -1355,7 +1410,7 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
                 let tmp = mem::replace(&mut self.v, &mut []);
                 let (head, tail) = tmp.split_at_mut(idx);
                 self.v = head;
-                Some(tail[mut 1..])
+                Some(tail.slice_from_mut(1))
             }
         }
     }
@@ -1403,8 +1458,8 @@ impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
         if self.size > self.v.len() {
             None
         } else {
-            let ret = Some(self.v[..self.size]);
-            self.v = self.v[1..];
+            let ret = Some(self.v.slice(0, self.size));
+            self.v = self.v.slice(1, self.v.len());
             ret
         }
     }
@@ -1488,7 +1543,7 @@ impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> {
             let mut hi = lo + self.size;
             if hi < lo || hi > self.v.len() { hi = self.v.len(); }
 
-            Some(self.v[lo..hi])
+            Some(self.v.slice(lo, hi))
         } else {
             None
         }
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 1c20d364bf8..fd7c63a6b32 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -30,7 +30,7 @@ use iter::range;
 use num::{CheckedMul, Saturating};
 use option::{Option, None, Some};
 use raw::Repr;
-use slice::ImmutableSlice;
+use slice::{ImmutableSlice, MutableSlice};
 use slice;
 use uint;
 
@@ -393,7 +393,7 @@ impl NaiveSearcher {
 
     fn next(&mut self, haystack: &[u8], needle: &[u8]) -> Option<(uint, uint)> {
         while self.position + needle.len() <= haystack.len() {
-            if haystack[self.position .. self.position + needle.len()] == needle {
+            if haystack.slice(self.position, self.position + needle.len()) == needle {
                 let match_pos = self.position;
                 self.position += needle.len(); // add 1 for all matches
                 return Some((match_pos, match_pos + needle.len()));
@@ -514,10 +514,10 @@ impl TwoWaySearcher {
         //
         // What's going on is we have some critical factorization (u, v) of the
         // needle, and we want to determine whether u is a suffix of
-        // v[..period]. If it is, we use "Algorithm CP1". Otherwise we use
+        // v.slice_to(period). If it is, we use "Algorithm CP1". Otherwise we use
         // "Algorithm CP2", which is optimized for when the period of the needle
         // is large.
-        if needle[..crit_pos] == needle[period.. period + crit_pos] {
+        if needle.slice_to(crit_pos) == needle.slice(period, period + crit_pos) {
             TwoWaySearcher {
                 crit_pos: crit_pos,
                 period: period,
@@ -741,7 +741,7 @@ impl<'a> Iterator<u16> for Utf16CodeUnits<'a> {
 
         let mut buf = [0u16, ..2];
         self.chars.next().map(|ch| {
-            let n = ch.encode_utf16(buf[mut]).unwrap_or(0);
+            let n = ch.encode_utf16(buf.as_mut_slice()).unwrap_or(0);
             if n == 2 { self.extra = buf[1]; }
             buf[0]
         })
@@ -1007,7 +1007,7 @@ pub fn utf16_items<'a>(v: &'a [u16]) -> Utf16Items<'a> {
 pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
     match v.iter().position(|c| *c == 0) {
         // don't include the 0
-        Some(i) => v[..i],
+        Some(i) => v.slice_to(i),
         None => v
     }
 }
@@ -1164,7 +1164,6 @@ pub mod traits {
         fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
     }
 
-    #[cfg(stage0)]
     impl ops::Slice<uint, str> for str {
         #[inline]
         fn as_slice_<'a>(&'a self) -> &'a str {
@@ -1173,39 +1172,17 @@ pub mod traits {
 
         #[inline]
         fn slice_from_<'a>(&'a self, from: &uint) -> &'a str {
-            super::slice_from_impl(&self, *from)
+            self.slice_from(*from)
         }
 
         #[inline]
         fn slice_to_<'a>(&'a self, to: &uint) -> &'a str {
-            super::slice_to_impl(&self, *to)
+            self.slice_to(*to)
         }
 
         #[inline]
         fn slice_<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
-            super::slice_impl(&self, *from, *to)
-        }
-    }
-    #[cfg(not(stage0))]
-    impl ops::Slice<uint, str> for str {
-        #[inline]
-        fn as_slice<'a>(&'a self) -> &'a str {
-            self
-        }
-
-        #[inline]
-        fn slice_from<'a>(&'a self, from: &uint) -> &'a str {
-            super::slice_from_impl(&self, *from)
-        }
-
-        #[inline]
-        fn slice_to<'a>(&'a self, to: &uint) -> &'a str {
-            super::slice_to_impl(&self, *to)
-        }
-
-        #[inline]
-        fn slice<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
-            super::slice_impl(&self, *from, *to)
+            self.slice(*from, *to)
         }
     }
 }
@@ -1858,38 +1835,6 @@ fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! {
           begin, end, s);
 }
 
-#[inline]
-fn slice_impl<'a>(this: &&'a str, begin: uint, end: uint) -> &'a str {
-    // is_char_boundary checks that the index is in [0, .len()]
-    if begin <= end &&
-       this.is_char_boundary(begin) &&
-       this.is_char_boundary(end) {
-        unsafe { raw::slice_unchecked(*this, begin, end) }
-    } else {
-        slice_error_fail(*this, begin, end)
-    }
-}
-
-#[inline]
-fn slice_from_impl<'a>(this: &&'a str, begin: uint) -> &'a str {
-    // is_char_boundary checks that the index is in [0, .len()]
-    if this.is_char_boundary(begin) {
-        unsafe { raw::slice_unchecked(*this, begin, this.len()) }
-    } else {
-        slice_error_fail(*this, begin, this.len())
-    }
-}
-
-#[inline]
-fn slice_to_impl<'a>(this: &&'a str, end: uint) -> &'a str {
-    // is_char_boundary checks that the index is in [0, .len()]
-    if this.is_char_boundary(end) {
-        unsafe { raw::slice_unchecked(*this, 0, end) }
-    } else {
-        slice_error_fail(*this, 0, end)
-    }
-}
-
 impl<'a> StrSlice<'a> for &'a str {
     #[inline]
     fn contains<'a>(&self, needle: &'a str) -> bool {
@@ -1993,17 +1938,34 @@ impl<'a> StrSlice<'a> for &'a str {
 
     #[inline]
     fn slice(&self, begin: uint, end: uint) -> &'a str {
-        slice_impl(self, begin, end)
+        // is_char_boundary checks that the index is in [0, .len()]
+        if begin <= end &&
+           self.is_char_boundary(begin) &&
+           self.is_char_boundary(end) {
+            unsafe { raw::slice_unchecked(*self, begin, end) }
+        } else {
+            slice_error_fail(*self, begin, end)
+        }
     }
 
     #[inline]
     fn slice_from(&self, begin: uint) -> &'a str {
-        slice_from_impl(self, begin)
+        // is_char_boundary checks that the index is in [0, .len()]
+        if self.is_char_boundary(begin) {
+            unsafe { raw::slice_unchecked(*self, begin, self.len()) }
+        } else {
+            slice_error_fail(*self, begin, self.len())
+        }
     }
 
     #[inline]
     fn slice_to(&self, end: uint) -> &'a str {
-        slice_to_impl(self, end)
+        // is_char_boundary checks that the index is in [0, .len()]
+        if self.is_char_boundary(end) {
+            unsafe { raw::slice_unchecked(*self, 0, end) }
+        } else {
+            slice_error_fail(*self, 0, end)
+        }
     }
 
     fn slice_chars(&self, begin: uint, end: uint) -> &'a str {
@@ -2032,13 +1994,13 @@ impl<'a> StrSlice<'a> for &'a str {
     #[inline]
     fn starts_with<'a>(&self, needle: &'a str) -> bool {
         let n = needle.len();
-        self.len() >= n && needle.as_bytes() == self.as_bytes()[..n]
+        self.len() >= n && needle.as_bytes() == self.as_bytes().slice_to(n)
     }
 
     #[inline]
     fn ends_with(&self, needle: &str) -> bool {
         let (m, n) = (self.len(), needle.len());
-        m >= n && needle.as_bytes() == self.as_bytes()[m-n..]
+        m >= n && needle.as_bytes() == self.as_bytes().slice_from(m - n)
     }
 
     #[inline]