about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-06 15:05:53 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-06 15:05:53 -0800
commit1afe8a4fb86fe54be8008b033de166d9c1f8f650 (patch)
treec7f8c61d1f944c6f2b4a1c59979bfa4b0fae3cfa /src/libcore
parentea6f65c5f1a3f84e010d2cef02a0160804e9567a (diff)
parent0c7f7a5fb8919c6a382f9acd1e921c51f807f625 (diff)
rollup merge of #20562: nick29581/arrays-3
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/array.rs36
-rw-r--r--src/libcore/fmt/float.rs4
-rw-r--r--src/libcore/fmt/mod.rs8
-rw-r--r--src/libcore/fmt/num.rs3
-rw-r--r--src/libcore/num/mod.rs4
-rw-r--r--src/libcore/ops.rs101
-rw-r--r--src/libcore/prelude.rs2
-rw-r--r--src/libcore/slice.rs244
-rw-r--r--src/libcore/str/mod.rs43
9 files changed, 212 insertions, 233 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index ba7714ad9bc..a4b32f2b6a2 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -18,7 +18,7 @@ use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use fmt;
 use kinds::Copy;
-use ops::Deref;
+use ops::{Deref, FullRange, Index};
 use option::Option;
 
 // macro for implementing n-ary tuple functions and operations
@@ -35,7 +35,7 @@ macro_rules! array_impls {
             #[unstable = "waiting for Show to stabilize"]
             impl<T:fmt::Show> fmt::Show for [T; $N] {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-                    fmt::Show::fmt(&self[], f)
+                    fmt::Show::fmt(&self.index(&FullRange), f)
                 }
             }
 
@@ -43,11 +43,11 @@ macro_rules! array_impls {
             impl<A, B> PartialEq<[B; $N]> for [A; $N] where A: PartialEq<B> {
                 #[inline]
                 fn eq(&self, other: &[B; $N]) -> bool {
-                    self[] == other[]
+                    self.index(&FullRange) == other.index(&FullRange)
                 }
                 #[inline]
                 fn ne(&self, other: &[B; $N]) -> bool {
-                    self[] != other[]
+                    self.index(&FullRange) != other.index(&FullRange)
                 }
             }
 
@@ -57,9 +57,13 @@ macro_rules! array_impls {
                 Rhs: Deref<Target=[B]>,
             {
                 #[inline(always)]
-                fn eq(&self, other: &Rhs) -> bool { PartialEq::eq(self[], &**other) }
+                fn eq(&self, other: &Rhs) -> bool {
+                    PartialEq::eq(self.index(&FullRange), &**other)
+                }
                 #[inline(always)]
-                fn ne(&self, other: &Rhs) -> bool { PartialEq::ne(self[], &**other) }
+                fn ne(&self, other: &Rhs) -> bool {
+                    PartialEq::ne(self.index(&FullRange), &**other)
+                }
             }
 
             #[stable]
@@ -68,9 +72,13 @@ macro_rules! array_impls {
                 Lhs: Deref<Target=[A]>
             {
                 #[inline(always)]
-                fn eq(&self, other: &[B; $N]) -> bool { PartialEq::eq(&**self, other[]) }
+                fn eq(&self, other: &[B; $N]) -> bool {
+                    PartialEq::eq(&**self, other.index(&FullRange))
+                }
                 #[inline(always)]
-                fn ne(&self, other: &[B; $N]) -> bool { PartialEq::ne(&**self, other[]) }
+                fn ne(&self, other: &[B; $N]) -> bool {
+                    PartialEq::ne(&**self, other.index(&FullRange))
+                }
             }
 
             #[stable]
@@ -80,23 +88,23 @@ macro_rules! array_impls {
             impl<T:PartialOrd> PartialOrd for [T; $N] {
                 #[inline]
                 fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
-                    PartialOrd::partial_cmp(&self[], &other[])
+                    PartialOrd::partial_cmp(&self.index(&FullRange), &other.index(&FullRange))
                 }
                 #[inline]
                 fn lt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::lt(&self[], &other[])
+                    PartialOrd::lt(&self.index(&FullRange), &other.index(&FullRange))
                 }
                 #[inline]
                 fn le(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::le(&self[], &other[])
+                    PartialOrd::le(&self.index(&FullRange), &other.index(&FullRange))
                 }
                 #[inline]
                 fn ge(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::ge(&self[], &other[])
+                    PartialOrd::ge(&self.index(&FullRange), &other.index(&FullRange))
                 }
                 #[inline]
                 fn gt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::gt(&self[], &other[])
+                    PartialOrd::gt(&self.index(&FullRange), &other.index(&FullRange))
                 }
             }
 
@@ -104,7 +112,7 @@ macro_rules! array_impls {
             impl<T:Ord> Ord for [T; $N] {
                 #[inline]
                 fn cmp(&self, other: &[T; $N]) -> Ordering {
-                    Ord::cmp(&self[], &other[])
+                    Ord::cmp(&self.index(&FullRange), &other.index(&FullRange))
                 }
             }
         )+
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index f63242b4f85..d833b8fed77 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -20,7 +20,7 @@ use fmt;
 use iter::{IteratorExt, range};
 use num::{cast, Float, ToPrimitive};
 use num::FpCategory as Fp;
-use ops::FnOnce;
+use ops::{FnOnce, Index};
 use result::Result::Ok;
 use slice::{self, SliceExt};
 use str::{self, StrExt};
@@ -332,5 +332,5 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
         }
     }
 
-    f(unsafe { str::from_utf8_unchecked(buf[..end]) })
+    f(unsafe { str::from_utf8_unchecked(buf.index(&(0..end))) })
 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 951f5c29f00..76c2671cfd0 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -19,8 +19,8 @@ use kinds::{Copy, Sized};
 use mem;
 use option::Option;
 use option::Option::{Some, None};
-use ops::{Deref, FnOnce};
 use result::Result::Ok;
+use ops::{Deref, FnOnce, Index};
 use result;
 use slice::SliceExt;
 use slice;
@@ -413,7 +413,7 @@ impl<'a> Formatter<'a> {
             for c in sign.into_iter() {
                 let mut b = [0; 4];
                 let n = c.encode_utf8(&mut b).unwrap_or(0);
-                let b = unsafe { str::from_utf8_unchecked(b[0..n]) };
+                let b = unsafe { str::from_utf8_unchecked(b.index(&(0..n))) };
                 try!(f.buf.write_str(b));
             }
             if prefixed { f.buf.write_str(prefix) }
@@ -521,7 +521,7 @@ impl<'a> Formatter<'a> {
 
         let mut fill = [0u8; 4];
         let len = self.fill.encode_utf8(&mut fill).unwrap_or(0);
-        let fill = unsafe { str::from_utf8_unchecked(fill[..len]) };
+        let fill = unsafe { str::from_utf8_unchecked(fill.index(&(..len))) };
 
         for _ in range(0, pre_pad) {
             try!(self.buf.write_str(fill));
@@ -620,7 +620,7 @@ impl Show for char {
 
         let mut utf8 = [0u8; 4];
         let amt = self.encode_utf8(&mut utf8).unwrap_or(0);
-        let s: &str = unsafe { mem::transmute(utf8[..amt]) };
+        let s: &str = unsafe { mem::transmute(utf8.index(&(0..amt))) };
         Show::fmt(s, f)
     }
 }
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index e0724fc2da5..89337e0584b 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -16,6 +16,7 @@
 
 use fmt;
 use iter::IteratorExt;
+use ops::Index;
 use num::{Int, cast};
 use slice::SliceExt;
 use str;
@@ -61,7 +62,7 @@ trait GenericRadix {
                 if x == zero { break };                   // No more digits left to accumulate.
             }
         }
-        let buf = unsafe { str::from_utf8_unchecked(buf[curr..]) };
+        let buf = unsafe { str::from_utf8_unchecked(buf.index(&(curr..))) };
         f.pad_integral(is_positive, self.prefix(), buf)
     }
 }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 192d6063f6b..3bcdd54463f 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -24,7 +24,7 @@ use iter::IteratorExt;
 use kinds::Copy;
 use mem::size_of;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
-use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
+use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr, Index};
 use option::Option;
 use option::Option::{Some, None};
 use str::{FromStr, StrExt};
@@ -1577,7 +1577,7 @@ macro_rules! from_str_radix_float_impl {
                         };
 
                         // Parse the exponent as decimal integer
-                        let src = src[offset..];
+                        let src = src.index(&(offset..));
                         let (is_positive, exp) = match src.slice_shift_char() {
                             Some(('-', src)) => (false, src.parse::<uint>()),
                             Some(('+', src)) => (true,  src.parse::<uint>()),
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 97d94e73bb3..2a7e6eb4795 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -846,105 +846,6 @@ pub trait IndexMut<Index: ?Sized> {
     fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output;
 }
 
-/// The `Slice` trait is used to specify the functionality of slicing operations
-/// like `arr[from..to]` when used in an immutable context.
-///
-/// # Example
-///
-/// A trivial implementation of `Slice`. When `Foo[..Foo]` happens, it ends up
-/// calling `slice_to`, and therefore, `main` prints `Slicing!`.
-///
-/// ```ignore
-/// use std::ops::Slice;
-///
-/// #[derive(Copy)]
-/// struct Foo;
-///
-/// impl Slice<Foo, Foo> for Foo {
-///     fn as_slice_<'a>(&'a self) -> &'a Foo {
-///         println!("Slicing!");
-///         self
-///     }
-///     fn slice_from_or_fail<'a>(&'a self, _from: &Foo) -> &'a Foo {
-///         println!("Slicing!");
-///         self
-///     }
-///     fn slice_to_or_fail<'a>(&'a self, _to: &Foo) -> &'a Foo {
-///         println!("Slicing!");
-///         self
-///     }
-///     fn slice_or_fail<'a>(&'a self, _from: &Foo, _to: &Foo) -> &'a Foo {
-///         println!("Slicing!");
-///         self
-///     }
-/// }
-///
-/// fn main() {
-///     Foo[..Foo];
-/// }
-/// ```
-#[lang="slice"]
-pub trait Slice<Idx: ?Sized, Result: ?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_or_fail<'a>(&'a self, from: &Idx) -> &'a Result;
-    /// The method for the slicing operation foo[..to]
-    fn slice_to_or_fail<'a>(&'a self, to: &Idx) -> &'a Result;
-    /// The method for the slicing operation foo[from..to]
-    fn slice_or_fail<'a>(&'a self, from: &Idx, to: &Idx) -> &'a Result;
-}
-
-/// The `SliceMut` trait is used to specify the functionality of slicing
-/// operations like `arr[from..to]`, when used in a mutable context.
-///
-/// # Example
-///
-/// A trivial implementation of `SliceMut`. When `Foo[Foo..]` happens, it ends up
-/// calling `slice_from_mut`, and therefore, `main` prints `Slicing!`.
-///
-/// ```ignore
-/// use std::ops::SliceMut;
-///
-/// #[derive(Copy)]
-/// struct Foo;
-///
-/// impl SliceMut<Foo, Foo> for Foo {
-///     fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo {
-///         println!("Slicing!");
-///         self
-///     }
-///     fn slice_from_or_fail_mut<'a>(&'a mut self, _from: &Foo) -> &'a mut Foo {
-///         println!("Slicing!");
-///         self
-///     }
-///     fn slice_to_or_fail_mut<'a>(&'a mut self, _to: &Foo) -> &'a mut Foo {
-///         println!("Slicing!");
-///         self
-///     }
-///     fn slice_or_fail_mut<'a>(&'a mut self, _from: &Foo, _to: &Foo) -> &'a mut Foo {
-///         println!("Slicing!");
-///         self
-///     }
-/// }
-///
-/// pub fn main() {
-///     Foo[mut Foo..];
-/// }
-/// ```
-#[lang="slice_mut"]
-pub trait SliceMut<Idx: ?Sized, Result: ?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_or_fail_mut<'a>(&'a mut self, from: &Idx) -> &'a mut Result;
-    /// The method for the slicing operation foo[..to]
-    fn slice_to_or_fail_mut<'a>(&'a mut self, to: &Idx) -> &'a mut Result;
-    /// The method for the slicing operation foo[from..to]
-    fn slice_or_fail_mut<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result;
-}
-
-
 /// An unbounded range.
 #[derive(Copy)]
 #[lang="full_range"]
@@ -962,8 +863,6 @@ pub struct Range<Idx> {
     pub end: Idx,
 }
 
-// FIXME(#19391) needs a snapshot
-//impl<Idx: Clone + Step<T=uint>> Iterator<Idx> for Range<Idx> {
 #[unstable = "API still in development"]
 impl<Idx: Clone + Step> Iterator for Range<Idx> {
     type Item = Idx;
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index e88cb73c8a9..a560b68db01 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -30,7 +30,7 @@
 
 // Reexported core operators
 pub use kinds::{Copy, Send, Sized, Sync};
-pub use ops::{Drop, Fn, FnMut, FnOnce};
+pub use ops::{Drop, Fn, FnMut, FnOnce, FullRange};
 
 // Reexported functions
 pub use iter::range;
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 093ed0b242f..8ab927f701a 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -43,7 +43,7 @@ use default::Default;
 use iter::*;
 use kinds::Copy;
 use num::Int;
-use ops::{FnMut, self};
+use ops::{FnMut, self, Index};
 use option::Option;
 use option::Option::{None, Some};
 use result::Result;
@@ -159,7 +159,7 @@ impl<T> SliceExt for [T] {
 
     #[inline]
     fn split_at(&self, mid: uint) -> (&[T], &[T]) {
-        (self[..mid], self[mid..])
+        (self.index(&(0..mid)), self.index(&(mid..)))
     }
 
     #[inline]
@@ -236,11 +236,11 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
-    fn tail(&self) -> &[T] { self[1..] }
+    fn tail(&self) -> &[T] { self.index(&(1..)) }
 
     #[inline]
     fn init(&self) -> &[T] {
-        self[..self.len() - 1]
+        self.index(&(0..(self.len() - 1)))
     }
 
     #[inline]
@@ -292,17 +292,17 @@ impl<T> SliceExt for [T] {
     fn as_mut_slice(&mut self) -> &mut [T] { self }
 
     fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] {
-        ops::SliceMut::slice_or_fail_mut(self, &start, &end)
+        ops::IndexMut::index_mut(self, &ops::Range { start: start, end: end } )
     }
 
     #[inline]
     fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
-        ops::SliceMut::slice_from_or_fail_mut(self, &start)
+        ops::IndexMut::index_mut(self, &ops::RangeFrom { start: start } )
     }
 
     #[inline]
     fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
-        ops::SliceMut::slice_to_or_fail_mut(self, &end)
+        ops::IndexMut::index_mut(self, &ops::RangeTo { end: end } )
     }
 
     #[inline]
@@ -310,8 +310,8 @@ impl<T> SliceExt for [T] {
         unsafe {
             let self2: &mut [T] = mem::transmute_copy(&self);
 
-            (ops::SliceMut::slice_to_or_fail_mut(self, &mid),
-             ops::SliceMut::slice_from_or_fail_mut(self2, &mid))
+            (ops::IndexMut::index_mut(self, &ops::RangeTo { end: mid } ),
+             ops::IndexMut::index_mut(self2, &ops::RangeFrom { start: mid } ))
         }
     }
 
@@ -443,13 +443,13 @@ impl<T> SliceExt for [T] {
     #[inline]
     fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
         let n = needle.len();
-        self.len() >= n && needle == self[..n]
+        self.len() >= n && needle == self.index(&(0..n))
     }
 
     #[inline]
     fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
         let (m, n) = (self.len(), needle.len());
-        m >= n && needle == self[m-n..]
+        m >= n && needle == self.index(&((m-n)..))
     }
 
     #[unstable]
@@ -551,62 +551,79 @@ impl<T> ops::IndexMut<uint> for [T] {
     }
 }
 
-impl<T> ops::Slice<uint, [T]> for [T] {
+impl<T> ops::Index<ops::Range<uint>> for [T] {
+    type Output = [T];
     #[inline]
-    fn as_slice_<'a>(&'a self) -> &'a [T] {
-        self
-    }
-
-    #[inline]
-    fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
-        self.slice_or_fail(start, &self.len())
-    }
-
-    #[inline]
-    fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
-        self.slice_or_fail(&0, end)
-    }
-    #[inline]
-    fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
-        assert!(*start <= *end);
-        assert!(*end <= self.len());
+    fn index(&self, index: &ops::Range<uint>) -> &[T] {
+        assert!(index.start <= index.end);
+        assert!(index.end <= self.len());
         unsafe {
             transmute(RawSlice {
-                    data: self.as_ptr().offset(*start as int),
-                    len: (*end - *start)
+                    data: self.as_ptr().offset(index.start as int),
+                    len: index.end - index.start
                 })
         }
     }
 }
-
-impl<T> ops::SliceMut<uint, [T]> for [T] {
+impl<T> ops::Index<ops::RangeTo<uint>> for [T] {
+    type Output = [T];
     #[inline]
-    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
-        self
+    fn index(&self, index: &ops::RangeTo<uint>) -> &[T] {
+        self.index(&ops::Range{ start: 0, end: index.end })
     }
-
+}
+impl<T> ops::Index<ops::RangeFrom<uint>> for [T] {
+    type Output = [T];
     #[inline]
-    fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
-        let len = &self.len();
-        self.slice_or_fail_mut(start, len)
+    fn index(&self, index: &ops::RangeFrom<uint>) -> &[T] {
+        self.index(&ops::Range{ start: index.start, end: self.len() })
     }
-
+}
+impl<T> ops::Index<ops::FullRange> for [T] {
+    type Output = [T];
     #[inline]
-    fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
-        self.slice_or_fail_mut(&0, end)
+    fn index(&self, _index: &ops::FullRange) -> &[T] {
+        self
     }
+}
+
+impl<T> ops::IndexMut<ops::Range<uint>> for [T] {
+    type Output = [T];
     #[inline]
-    fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
-        assert!(*start <= *end);
-        assert!(*end <= self.len());
+    fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] {
+        assert!(index.start <= index.end);
+        assert!(index.end <= self.len());
         unsafe {
             transmute(RawSlice {
-                    data: self.as_ptr().offset(*start as int),
-                    len: (*end - *start)
+                    data: self.as_ptr().offset(index.start as int),
+                    len: index.end - index.start
                 })
         }
     }
 }
+impl<T> ops::IndexMut<ops::RangeTo<uint>> for [T] {
+    type Output = [T];
+    #[inline]
+    fn index_mut(&mut self, index: &ops::RangeTo<uint>) -> &mut [T] {
+        self.index_mut(&ops::Range{ start: 0, end: index.end })
+    }
+}
+impl<T> ops::IndexMut<ops::RangeFrom<uint>> for [T] {
+    type Output = [T];
+    #[inline]
+    fn index_mut(&mut self, index: &ops::RangeFrom<uint>) -> &mut [T] {
+        let len = self.len();
+        self.index_mut(&ops::Range{ start: index.start, end: len })
+    }
+}
+impl<T> ops::IndexMut<ops::FullRange> for [T] {
+    type Output = [T];
+    #[inline]
+    fn index_mut(&mut self, _index: &ops::FullRange) -> &mut [T] {
+        self
+    }
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // Common traits
@@ -738,21 +755,38 @@ pub struct Iter<'a, T: 'a> {
 }
 
 #[experimental]
-impl<'a, T> ops::Slice<uint, [T]> for Iter<'a, T> {
-    fn as_slice_(&self) -> &[T] {
-        self.as_slice()
+impl<'a, T> ops::Index<ops::Range<uint>> for Iter<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, index: &ops::Range<uint>) -> &[T] {
+        self.as_slice().index(index)
     }
-    fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] {
-        use ops::Slice;
-        self.as_slice().slice_from_or_fail(from)
+}
+
+#[experimental]
+impl<'a, T> ops::Index<ops::RangeTo<uint>> for Iter<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, index: &ops::RangeTo<uint>) -> &[T] {
+        self.as_slice().index(index)
     }
-    fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] {
-        use ops::Slice;
-        self.as_slice().slice_to_or_fail(to)
+}
+
+#[experimental]
+impl<'a, T> ops::Index<ops::RangeFrom<uint>> for Iter<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, index: &ops::RangeFrom<uint>) -> &[T] {
+        self.as_slice().index(index)
     }
-    fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] {
-        use ops::Slice;
-        self.as_slice().slice_or_fail(from, to)
+}
+
+#[experimental]
+impl<'a, T> ops::Index<ops::FullRange> for Iter<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, _index: &ops::FullRange) -> &[T] {
+        self.as_slice()
     }
 }
 
@@ -812,44 +846,74 @@ pub struct IterMut<'a, T: 'a> {
     marker: marker::ContravariantLifetime<'a>,
 }
 
+
 #[experimental]
-impl<'a, T> ops::Slice<uint, [T]> for IterMut<'a, T> {
-    fn as_slice_<'b>(&'b self) -> &'b [T] {
-        make_slice!(T -> &'b [T]: self.ptr, self.end)
+impl<'a, T> ops::Index<ops::Range<uint>> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, index: &ops::Range<uint>) -> &[T] {
+        self.index(&ops::FullRange).index(index)
     }
-    fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] {
-        use ops::Slice;
-        self.as_slice_().slice_from_or_fail(from)
+}
+#[experimental]
+impl<'a, T> ops::Index<ops::RangeTo<uint>> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, index: &ops::RangeTo<uint>) -> &[T] {
+        self.index(&ops::FullRange).index(index)
     }
-    fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] {
-        use ops::Slice;
-        self.as_slice_().slice_to_or_fail(to)
+}
+#[experimental]
+impl<'a, T> ops::Index<ops::RangeFrom<uint>> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, index: &ops::RangeFrom<uint>) -> &[T] {
+        self.index(&ops::FullRange).index(index)
     }
-    fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] {
-        use ops::Slice;
-        self.as_slice_().slice_or_fail(from, to)
+}
+#[experimental]
+impl<'a, T> ops::Index<ops::FullRange> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, _index: &ops::FullRange) -> &[T] {
+        make_slice!(T -> &[T]: self.ptr, self.end)
     }
 }
 
 #[experimental]
-impl<'a, T> ops::SliceMut<uint, [T]> for IterMut<'a, T> {
-    fn as_mut_slice_<'b>(&'b mut self) -> &'b mut [T] {
-        make_slice!(T -> &'b mut [T]: self.ptr, self.end)
+impl<'a, T> ops::IndexMut<ops::Range<uint>> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] {
+        self.index_mut(&ops::FullRange).index_mut(index)
     }
-    fn slice_from_or_fail_mut<'b>(&'b mut self, from: &uint) -> &'b mut [T] {
-        use ops::SliceMut;
-        self.as_mut_slice_().slice_from_or_fail_mut(from)
+}
+#[experimental]
+impl<'a, T> ops::IndexMut<ops::RangeTo<uint>> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index_mut(&mut self, index: &ops::RangeTo<uint>) -> &mut [T] {
+        self.index_mut(&ops::FullRange).index_mut(index)
     }
-    fn slice_to_or_fail_mut<'b>(&'b mut self, to: &uint) -> &'b mut [T] {
-        use ops::SliceMut;
-        self.as_mut_slice_().slice_to_or_fail_mut(to)
+}
+#[experimental]
+impl<'a, T> ops::IndexMut<ops::RangeFrom<uint>> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index_mut(&mut self, index: &ops::RangeFrom<uint>) -> &mut [T] {
+        self.index_mut(&ops::FullRange).index_mut(index)
     }
-    fn slice_or_fail_mut<'b>(&'b mut self, from: &uint, to: &uint) -> &'b mut [T] {
-        use ops::SliceMut;
-        self.as_mut_slice_().slice_or_fail_mut(from, to)
+}
+#[experimental]
+impl<'a, T> ops::IndexMut<ops::FullRange> for IterMut<'a, T> {
+    type Output = [T];
+    #[inline]
+    fn index_mut(&mut self, _index: &ops::FullRange) -> &mut [T] {
+        make_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.
     ///
@@ -908,8 +972,8 @@ impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool {
         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.index(&(0..idx)));
+                self.v = self.v.index(&((idx + 1)..));
                 ret
             }
         }
@@ -934,8 +998,8 @@ impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P> where P: FnMut(&T) -> boo
         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.index(&((idx + 1)..)));
+                self.v = self.v.index(&(0..idx));
                 ret
             }
         }
@@ -1131,8 +1195,8 @@ impl<'a, T> Iterator 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.index(&(0..self.size)));
+            self.v = self.v.index(&(1..));
             ret
         }
     }
@@ -1219,7 +1283,7 @@ impl<'a, T> RandomAccessIterator 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.index(&(lo..hi)))
         } else {
             None
         }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index a39787b8207..bc995a2af72 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -26,7 +26,7 @@ use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator};
 use kinds::Sized;
 use mem;
 use num::Int;
-use ops::{Fn, FnMut};
+use ops::{Fn, FnMut, Index};
 use option::Option::{self, None, Some};
 use ptr::PtrExt;
 use raw::{Repr, Slice};
@@ -581,7 +581,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.index(&(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()));
@@ -702,10 +702,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.index(&(0..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.index(&(0..crit_pos)) == needle.index(&(period.. period + crit_pos)) {
             TwoWaySearcher {
                 crit_pos: crit_pos,
                 period: period,
@@ -1119,25 +1119,32 @@ mod traits {
         }
     }
 
-    impl ops::Slice<uint, str> for str {
+    impl ops::Index<ops::Range<uint>> for str {
+        type Output = str;
         #[inline]
-        fn as_slice_<'a>(&'a self) -> &'a str {
-            self
+        fn index(&self, index: &ops::Range<uint>) -> &str {
+            self.slice(index.start, index.end)
         }
-
+    }
+    impl ops::Index<ops::RangeTo<uint>> for str {
+        type Output = str;
         #[inline]
-        fn slice_from_or_fail<'a>(&'a self, from: &uint) -> &'a str {
-            self.slice_from(*from)
+        fn index(&self, index: &ops::RangeTo<uint>) -> &str {
+            self.slice_to(index.end)
         }
-
+    }
+    impl ops::Index<ops::RangeFrom<uint>> for str {
+        type Output = str;
         #[inline]
-        fn slice_to_or_fail<'a>(&'a self, to: &uint) -> &'a str {
-            self.slice_to(*to)
+        fn index(&self, index: &ops::RangeFrom<uint>) -> &str {
+            self.slice_from(index.start)
         }
-
+    }
+    impl ops::Index<ops::FullRange> for str {
+        type Output = str;
         #[inline]
-        fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
-            self.slice(*from, *to)
+        fn index(&self, _index: &ops::FullRange) -> &str {
+            self
         }
     }
 }
@@ -1406,13 +1413,13 @@ impl StrExt for str {
     #[inline]
     fn starts_with(&self, needle: &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().index(&(0..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().index(&((m-n)..))
     }
 
     #[inline]