about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcollections/lib.rs2
-rw-r--r--src/libcollections/string.rs34
-rw-r--r--src/libcollections/vec.rs32
-rw-r--r--src/libcore/slice.rs55
-rw-r--r--src/libcore/str/mod.rs56
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/test/run-pass/range_inclusive.rs18
7 files changed, 192 insertions, 6 deletions
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 9c6fdc217dc..2a81e7dcaf7 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -40,7 +40,7 @@
 #![feature(fmt_internals)]
 #![feature(fmt_radix)]
 #![feature(heap_api)]
-#![feature(iter_arith)]
+#![feature(inclusive_range)]
 #![feature(iter_arith)]
 #![feature(lang_items)]
 #![feature(nonzero)]
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 62ae7938e15..cae6520bdb2 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -59,7 +59,7 @@ use core::fmt;
 use core::hash;
 use core::iter::FromIterator;
 use core::mem;
-use core::ops::{self, Add};
+use core::ops::{self, Add, Index, IndexMut};
 use core::ptr;
 use core::slice;
 use core::str::pattern::Pattern;
@@ -1606,6 +1606,24 @@ impl ops::Index<ops::RangeFull> for String {
         unsafe { str::from_utf8_unchecked(&self.vec) }
     }
 }
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl ops::Index<ops::RangeInclusive<usize>> for String {
+    type Output = str;
+
+    #[inline]
+    fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
+        Index::index(&**self, index)
+    }
+}
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl ops::Index<ops::RangeToInclusive<usize>> for String {
+    type Output = str;
+
+    #[inline]
+    fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
+        Index::index(&**self, index)
+    }
+}
 
 #[stable(feature = "derefmut_for_string", since = "1.2.0")]
 impl ops::IndexMut<ops::Range<usize>> for String {
@@ -1635,6 +1653,20 @@ impl ops::IndexMut<ops::RangeFull> for String {
         unsafe { mem::transmute(&mut *self.vec) }
     }
 }
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl ops::IndexMut<ops::RangeInclusive<usize>> for String {
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
+        IndexMut::index_mut(&mut **self, index)
+    }
+}
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl ops::IndexMut<ops::RangeToInclusive<usize>> for String {
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
+        IndexMut::index_mut(&mut **self, index)
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Deref for String {
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index ae442e155c0..841748f3881 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1225,6 +1225,24 @@ impl<T> ops::Index<ops::RangeFull> for Vec<T> {
         self
     }
 }
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::Index<ops::RangeInclusive<usize>> for Vec<T> {
+    type Output = [T];
+
+    #[inline]
+    fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] {
+        Index::index(&**self, index)
+    }
+}
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::Index<ops::RangeToInclusive<usize>> for Vec<T> {
+    type Output = [T];
+
+    #[inline]
+    fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] {
+        Index::index(&**self, index)
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
@@ -1254,6 +1272,20 @@ impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
         self
     }
 }
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for Vec<T> {
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] {
+        IndexMut::index_mut(&mut **self, index)
+    }
+}
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for Vec<T> {
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] {
+        IndexMut::index_mut(&mut **self, index)
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Deref for Vec<T> {
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 73466a849dc..2293e93eea7 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -560,7 +560,7 @@ impl<T> ops::Index<ops::RangeTo<usize>> for [T] {
 
     #[inline]
     fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
-        self.index(ops::Range{ start: 0, end: index.end })
+        self.index(0 .. index.end)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -569,7 +569,7 @@ impl<T> ops::Index<ops::RangeFrom<usize>> for [T] {
 
     #[inline]
     fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
-        self.index(ops::Range{ start: index.start, end: self.len() })
+        self.index(index.start .. self.len())
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -582,6 +582,32 @@ impl<T> ops::Index<RangeFull> for [T] {
     }
 }
 
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::Index<ops::RangeInclusive<usize>> for [T] {
+    type Output = [T];
+
+    #[inline]
+    fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] {
+        match index {
+            ops::RangeInclusive::Empty { .. } => &[],
+            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
+                panic!("attempted to index slice up to maximum usize"),
+            ops::RangeInclusive::NonEmpty { start, end } =>
+                self.index(start .. end+1)
+        }
+    }
+}
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::Index<ops::RangeToInclusive<usize>> for [T] {
+    type Output = [T];
+
+    #[inline]
+    fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] {
+        // SNAP 3391630 change this to `0...index.end`
+        self.index(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
     #[inline]
@@ -603,7 +629,7 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
 impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] {
     #[inline]
     fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
-        self.index_mut(ops::Range{ start: 0, end: index.end })
+        self.index_mut(0 .. index.end)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -611,7 +637,7 @@ impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] {
     #[inline]
     fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
         let len = self.len();
-        self.index_mut(ops::Range{ start: index.start, end: len })
+        self.index_mut(index.start .. len)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -622,6 +648,27 @@ impl<T> ops::IndexMut<RangeFull> for [T] {
     }
 }
 
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for [T] {
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] {
+        match index {
+            ops::RangeInclusive::Empty { .. } => &mut [],
+            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
+                panic!("attempted to index slice up to maximum usize"),
+            ops::RangeInclusive::NonEmpty { start, end } =>
+                self.index_mut(start .. end+1)
+        }
+    }
+}
+#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
+impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for [T] {
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] {
+        // SNAP 3391630 change this to `0...index.end`
+        self.index_mut(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
+    }
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Common traits
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 4d367cfd432..1c77ea84537 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1462,6 +1462,62 @@ mod traits {
             self
         }
     }
+
+    #[unstable(feature = "inclusive_range",
+               reason = "recently added, follows RFC",
+               issue = "28237")]
+    impl ops::Index<ops::RangeInclusive<usize>> for str {
+        type Output = str;
+
+        #[inline]
+        fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
+            match index {
+                ops::RangeInclusive::Empty { .. } => "",
+                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
+                    panic!("attempted to index slice up to maximum usize"),
+                ops::RangeInclusive::NonEmpty { start, end } =>
+                    self.index(start .. end+1)
+            }
+        }
+    }
+    #[unstable(feature = "inclusive_range",
+               reason = "recently added, follows RFC",
+               issue = "28237")]
+    impl ops::Index<ops::RangeToInclusive<usize>> for str {
+        type Output = str;
+
+        #[inline]
+        fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
+            // SNAP 3391630 change this to `0...index.end`
+            self.index(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
+        }
+    }
+
+    #[unstable(feature = "inclusive_range",
+               reason = "recently added, follows RFC",
+               issue = "28237")]
+    impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
+        #[inline]
+        fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
+            match index {
+                ops::RangeInclusive::Empty { .. } => &mut self[0..0], // `&mut ""` doesn't work
+                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
+                    panic!("attempted to index str up to maximum usize"),
+                    ops::RangeInclusive::NonEmpty { start, end } =>
+                        self.index_mut(start .. end+1)
+            }
+        }
+    }
+    #[unstable(feature = "inclusive_range",
+               reason = "recently added, follows RFC",
+               issue = "28237")]
+    impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
+        #[inline]
+        fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
+            // SNAP 3391630 change this to `0...index.end`
+            self.index_mut(ops::RangeInclusive::NonEmpty { start: 0, end: index.end })
+        }
+    }
 }
 
 /// Methods for string slices
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index dd84cba370c..6ecf5c32bdb 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -233,6 +233,7 @@
 #![feature(fnbox)]
 #![feature(heap_api)]
 #![feature(hashmap_hasher)]
+#![feature(inclusive_range)]
 #![feature(int_error_internals)]
 #![feature(into_cow)]
 #![feature(lang_items)]
diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs
index c1bc6adf7b8..52c8353d00e 100644
--- a/src/test/run-pass/range_inclusive.rs
+++ b/src/test/run-pass/range_inclusive.rs
@@ -55,6 +55,24 @@ pub fn main() {
         let _ = x...&y;
     }
 
+    // test collection indexing
+    let vec = (0...10).collect::<Vec<_>>();
+    let slice: &[_] = &*vec;
+    let string = String::from("hello world");
+    let stir = "hello world";
+
+    assert_eq!(&vec[3...6], &[3, 4, 5, 6]);
+    assert_eq!(&vec[ ...6], &[0, 1, 2, 3, 4, 5, 6]);
+
+    assert_eq!(&slice[3...6], &[3, 4, 5, 6]);
+    assert_eq!(&slice[ ...6], &[0, 1, 2, 3, 4, 5, 6]);
+
+    assert_eq!(&string[3...6], "lo w");
+    assert_eq!(&string[ ...6], "hello w");
+
+    assert_eq!(&stir[3...6], "lo w");
+    assert_eq!(&stir[ ...6], "hello w");
+
     // test the size hints and emptying
     let mut long = 0...255u8;
     let mut short = 42...42;