From b4d4daf007753dfb04d87b1ffe1c2ad2d8811d5a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 21 Mar 2015 19:33:27 -0400 Subject: [PATCH] Adjust Index/IndexMut impls. For generic collections, we take references. For collections whose keys are integers, we take both references and by-value. --- src/libcollections/btree/map.rs | 15 +++ src/libcollections/string.rs | 32 +++++ src/libcollections/vec.rs | 82 ++++++++++++ src/libcollections/vec_deque.rs | 14 ++ src/libcollections/vec_map.rs | 42 +++++- src/libcore/ops.rs | 6 +- src/libcore/slice.rs | 201 +++++++++++++++++++++++++++++ src/libcore/str/mod.rs | 78 +++++++++++ src/libserialize/json.rs | 23 ++++ src/libstd/collections/hash/map.rs | 24 +++- src/libstd/ffi/os_str.rs | 12 ++ src/libstd/sys/common/wtf8.rs | 79 ++++++++++++ 12 files changed, 600 insertions(+), 8 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index a9e1ce8d7ce..0a72f24b437 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -914,12 +914,27 @@ impl Debug for BTreeMap { } } +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl Index for BTreeMap where K: Borrow, Q: Ord { type Output = V; + #[inline] + fn index(&self, key: &Q) -> &V { + self.get(key).expect("no entry found for key") + } +} + +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap + where K: Borrow, Q: Ord +{ + type Output = V; + + #[inline] fn index(&self, key: &Q) -> &V { self.get(key).expect("no entry found for key") } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index cd6f27bf65f..3f869d0b8ae 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -870,34 +870,66 @@ impl<'a> Add<&'a str> for String { #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for String { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range) -> &str { &self[..][*index] } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range) -> &str { + &self[..][index] + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for String { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo) -> &str { &self[..][*index] } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo) -> &str { + &self[..][index] + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for String { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom) -> &str { &self[..][*index] } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom) -> &str { + &self[..][index] + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for String { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &ops::RangeFull) -> &str { unsafe { mem::transmute(&*self.vec) } } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: ops::RangeFull) -> &str { + unsafe { mem::transmute(&*self.vec) } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index b0e8dc7d0b6..3e46ebfc446 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1323,83 +1323,165 @@ impl Hash for Vec { impl Index for Vec { type Output = T; + + #[cfg(stage0)] #[inline] fn index(&self, index: &usize) -> &T { // NB built-in indexing via `&[T]` &(**self)[*index] } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: usize) -> &T { + // NB built-in indexing via `&[T]` + &(**self)[index] + } } #[stable(feature = "rust1", since = "1.0.0")] impl IndexMut for Vec { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &usize) -> &mut T { // NB built-in indexing via `&mut [T]` &mut (**self)[*index] } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: usize) -> &mut T { + // NB built-in indexing via `&mut [T]` + &mut (**self)[index] + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for Vec { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range) -> &[T] { Index::index(&**self, index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range) -> &[T] { + Index::index(&**self, index) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for Vec { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo) -> &[T] { Index::index(&**self, index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo) -> &[T] { + Index::index(&**self, index) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for Vec { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom) -> &[T] { Index::index(&**self, index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom) -> &[T] { + Index::index(&**self, index) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for Vec { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &ops::RangeFull) -> &[T] { self.as_slice() } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: ops::RangeFull) -> &[T] { + self.as_slice() + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for Vec { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::Range) -> &mut [T] { IndexMut::index_mut(&mut **self, index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::Range) -> &mut [T] { + IndexMut::index_mut(&mut **self, index) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for Vec { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeTo) -> &mut [T] { IndexMut::index_mut(&mut **self, index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeTo) -> &mut [T] { + IndexMut::index_mut(&mut **self, index) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for Vec { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeFrom) -> &mut [T] { IndexMut::index_mut(&mut **self, index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom) -> &mut [T] { + IndexMut::index_mut(&mut **self, index) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut for Vec { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, _index: &ops::RangeFull) -> &mut [T] { self.as_mut_slice() } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] { + self.as_mut_slice() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index 56ca74dab1f..591ad48f579 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -1689,18 +1689,32 @@ impl Hash for VecDeque { impl Index for VecDeque { type Output = A; + #[cfg(stage0)] #[inline] fn index(&self, i: &usize) -> &A { self.get(*i).expect("Out of bounds access") } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, i: usize) -> &A { + self.get(i).expect("Out of bounds access") + } } #[stable(feature = "rust1", since = "1.0.0")] impl IndexMut for VecDeque { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, i: &usize) -> &mut A { self.get_mut(*i).expect("Out of bounds access") } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, i: usize) -> &mut A { + self.get_mut(i).expect("Out of bounds access") + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 6e67d876327..05693ec5275 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -798,6 +798,7 @@ impl Extend<(usize, V)> for VecMap { } } +#[cfg(stage0)] impl Index for VecMap { type Output = V; @@ -807,10 +808,49 @@ impl Index for VecMap { } } +#[cfg(not(stage0))] +impl Index for VecMap { + type Output = V; + + #[inline] + fn index<'a>(&'a self, i: usize) -> &'a V { + self.get(&i).expect("key not present") + } +} + +#[cfg(not(stage0))] +impl<'a,V> Index<&'a usize> for VecMap { + type Output = V; + + #[inline] + fn index(&self, i: &usize) -> &V { + self.get(i).expect("key not present") + } +} + +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl IndexMut for VecMap { #[inline] - fn index_mut<'a>(&'a mut self, i: &usize) -> &'a mut V { + fn index_mut(&mut self, i: &usize) -> &mut V { + self.get_mut(&i).expect("key not present") + } +} + +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl IndexMut for VecMap { + #[inline] + fn index_mut(&mut self, i: usize) -> &mut V { + self.get_mut(&i).expect("key not present") + } +} + +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, V> IndexMut<&'a usize> for VecMap { + #[inline] + fn index_mut(&mut self, i: &usize) -> &mut V { self.get_mut(i).expect("key not present") } } diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index e1e352b5b64..6e6f97a7af7 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -898,7 +898,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } /// impl Index for Foo { /// type Output = Foo; /// -/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo { +/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { /// println!("Indexing!"); /// self /// } @@ -945,13 +945,13 @@ pub trait Index { /// impl Index for Foo { /// type Output = Foo; /// -/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo { +/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { /// self /// } /// } /// /// impl IndexMut for Foo { -/// fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo { +/// fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo { /// println!("Indexing!"); /// self /// } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 907b2eba80c..04b425416f3 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -263,6 +263,7 @@ impl SliceExt for [T] { #[inline] fn as_mut_slice(&mut self) -> &mut [T] { self } + #[cfg(stage0)] #[inline] fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { unsafe { @@ -273,6 +274,17 @@ impl SliceExt for [T] { } } + #[cfg(not(stage0))] + #[inline] + fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { + unsafe { + let self2: &mut [T] = mem::transmute_copy(&self); + + (ops::IndexMut::index_mut(self, ops::RangeTo { end: mid } ), + ops::IndexMut::index_mut(self2, ops::RangeFrom { start: mid } )) + } + } + #[inline] fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { unsafe { @@ -495,25 +507,45 @@ impl SliceExt for [T] { impl ops::Index for [T] { type Output = T; + #[cfg(stage0)] fn index(&self, &index: &usize) -> &T { assert!(index < self.len()); unsafe { mem::transmute(self.repr().data.offset(index as isize)) } } + + #[cfg(not(stage0))] + fn index(&self, index: usize) -> &T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as isize)) } + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut for [T] { + #[cfg(stage0)] + #[inline] fn index_mut(&mut self, &index: &usize) -> &mut T { assert!(index < self.len()); unsafe { mem::transmute(self.repr().data.offset(index as isize)) } } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: usize) -> &mut T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as isize)) } + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range) -> &[T] { assert!(index.start <= index.end); @@ -525,34 +557,72 @@ impl ops::Index> for [T] { ) } } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range) -> &[T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); + unsafe { + from_raw_parts ( + self.as_ptr().offset(index.start as isize), + index.end - index.start + ) + } + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo) -> &[T] { self.index(&ops::Range{ start: 0, end: index.end }) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo) -> &[T] { + self.index(ops::Range{ start: 0, end: index.end }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom) -> &[T] { self.index(&ops::Range{ start: index.start, end: self.len() }) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom) -> &[T] { + self.index(ops::Range{ start: index.start, end: self.len() }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &RangeFull) -> &[T] { self } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: RangeFull) -> &[T] { + self + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for [T] { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::Range) -> &mut [T] { assert!(index.start <= index.end); @@ -564,28 +634,64 @@ impl ops::IndexMut> for [T] { ) } } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::Range) -> &mut [T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); + unsafe { + from_raw_parts_mut( + self.as_mut_ptr().offset(index.start as isize), + index.end - index.start + ) + } + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for [T] { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeTo) -> &mut [T] { self.index_mut(&ops::Range{ start: 0, end: index.end }) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeTo) -> &mut [T] { + self.index_mut(ops::Range{ start: 0, end: index.end }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut> for [T] { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeFrom) -> &mut [T] { let len = self.len(); self.index_mut(&ops::Range{ start: index.start, end: len }) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom) -> &mut [T] { + let len = self.len(); + self.index_mut(ops::Range{ start: index.start, end: len }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut for [T] { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] { self } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, _index: RangeFull) -> &mut [T] { + self + } } @@ -763,37 +869,69 @@ unsafe impl<'a, T: Sync> Send for Iter<'a, T> {} #[unstable(feature = "core")] impl<'a, T> ops::Index> for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range) -> &[T] { self.as_slice().index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range) -> &[T] { + self.as_slice().index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index> for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo) -> &[T] { self.as_slice().index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo) -> &[T] { + self.as_slice().index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index> for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom) -> &[T] { self.as_slice().index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom) -> &[T] { + self.as_slice().index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &RangeFull) -> &[T] { self.as_slice() } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: RangeFull) -> &[T] { + self.as_slice() + } } impl<'a, T> Iter<'a, T> { @@ -856,63 +994,126 @@ unsafe impl<'a, T: Send> Send for IterMut<'a, T> {} #[unstable(feature = "core")] impl<'a, T> ops::Index> for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range) -> &[T] { self.index(&RangeFull).index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range) -> &[T] { + self.index(RangeFull).index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index> for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo) -> &[T] { self.index(&RangeFull).index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo) -> &[T] { + self.index(RangeFull).index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index> for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom) -> &[T] { self.index(&RangeFull).index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom) -> &[T] { + self.index(RangeFull).index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &RangeFull) -> &[T] { make_slice!(T => &[T]: self.ptr, self.end) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: RangeFull) -> &[T] { + make_slice!(T => &[T]: self.ptr, self.end) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut> for IterMut<'a, T> { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::Range) -> &mut [T] { self.index_mut(&RangeFull).index_mut(index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::Range) -> &mut [T] { + self.index_mut(RangeFull).index_mut(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut> for IterMut<'a, T> { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeTo) -> &mut [T] { self.index_mut(&RangeFull).index_mut(index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeTo) -> &mut [T] { + self.index_mut(RangeFull).index_mut(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut> for IterMut<'a, T> { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeFrom) -> &mut [T] { self.index_mut(&RangeFull).index_mut(index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom) -> &mut [T] { + self.index_mut(RangeFull).index_mut(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut for IterMut<'a, T> { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] { make_mut_slice!(T => &mut [T]: self.ptr, self.end) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, _index: RangeFull) -> &mut [T] { + make_mut_slice!(T => &mut [T]: self.ptr, self.end) + } } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index e8181395b5c..b9a655c6d4e 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1203,6 +1203,7 @@ mod traits { /// // byte 100 is outside the string /// // &s[3 .. 100]; /// ``` + #[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for str { type Output = str; @@ -1219,6 +1220,49 @@ mod traits { } } + /// Returns a slice of the given string from the byte range + /// [`begin`..`end`). + /// + /// This operation is `O(1)`. + /// + /// Panics when `begin` and `end` do not point to valid characters + /// or point beyond the last character of the string. + /// + /// # Examples + /// + /// ``` + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(&s[0 .. 1], "L"); + /// + /// assert_eq!(&s[1 .. 9], "öwe 老"); + /// + /// // these will panic: + /// // byte 2 lies within `ö`: + /// // &s[2 ..3]; + /// + /// // byte 8 lies within `老` + /// // &s[1 .. 8]; + /// + /// // byte 100 is outside the string + /// // &s[3 .. 100]; + /// ``` + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + impl ops::Index> for str { + type Output = str; + #[inline] + fn index(&self, index: ops::Range) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if index.start <= index.end && + self.is_char_boundary(index.start) && + self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(index.start, index.end) } + } else { + super::slice_error_fail(self, index.start, index.end) + } + } + } + /// Returns a slice of the string from the beginning to byte /// `end`. /// @@ -1229,6 +1273,8 @@ mod traits { #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for str { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo) -> &str { // is_char_boundary checks that the index is in [0, .len()] @@ -1238,6 +1284,17 @@ mod traits { super::slice_error_fail(self, 0, index.end) } } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(0, index.end) } + } else { + super::slice_error_fail(self, 0, index.end) + } + } } /// Returns a slice of the string from `begin` to its end. @@ -1249,6 +1306,8 @@ mod traits { #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index> for str { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom) -> &str { // is_char_boundary checks that the index is in [0, .len()] @@ -1258,15 +1317,34 @@ mod traits { super::slice_error_fail(self, index.start, self.len()) } } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.start) { + unsafe { self.slice_unchecked(index.start, self.len()) } + } else { + super::slice_error_fail(self, index.start, self.len()) + } + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for str { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &ops::RangeFull) -> &str { self } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: ops::RangeFull) -> &str { + self + } } } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 096c72e6af2..abbfc82319f 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -1218,6 +1218,7 @@ impl Json { } } +#[cfg(stage0)] impl<'a> Index<&'a str> for Json { type Output = Json; @@ -1226,6 +1227,16 @@ impl<'a> Index<&'a str> for Json { } } +#[cfg(not(stage0))] +impl<'a> Index<&'a str> for Json { + type Output = Json; + + fn index(&self, idx: &'a str) -> &Json { + self.find(idx).unwrap() + } +} + +#[cfg(stage0)] impl Index for Json { type Output = Json; @@ -1237,6 +1248,18 @@ impl Index for Json { } } +#[cfg(not(stage0))] +impl Index for Json { + type Output = Json; + + fn index<'a>(&'a self, idx: uint) -> &'a Json { + match self { + &Json::Array(ref v) => &v[idx], + _ => panic!("can only index Json with uint if it is an array") + } + } +} + /// The output of the streaming parser. #[derive(PartialEq, Clone, Debug)] pub enum JsonEvent { diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 9139e182ce4..86664d7eb0c 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1088,7 +1088,7 @@ impl HashMap /// Some(x) => *x = "b", /// None => (), /// } - /// assert_eq!(map[1], "b"); + /// assert_eq!(map[&1], "b"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> @@ -1111,7 +1111,7 @@ impl HashMap /// /// map.insert(37, "b"); /// assert_eq!(map.insert(37, "c"), Some("b")); - /// assert_eq!(map[37], "c"); + /// assert_eq!(map[&37], "c"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, k: K, v: V) -> Option { @@ -1244,6 +1244,7 @@ impl Default for HashMap } } +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl Index for HashMap where K: Eq + Hash + Borrow, @@ -1258,6 +1259,21 @@ impl Index for HashMap } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap + where K: Eq + Hash + Borrow, + Q: Eq + Hash, + S: HashState, +{ + type Output = V; + + #[inline] + fn index(&self, index: &Q) -> &V { + self.get(index).expect("no entry found for key") + } +} + /// HashMap iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, K: 'a, V: 'a> { @@ -2185,7 +2201,7 @@ mod test_map { map.insert(2, 1); map.insert(3, 4); - assert_eq!(map[2], 1); + assert_eq!(map[&2], 1); } #[test] @@ -2197,7 +2213,7 @@ mod test_map { map.insert(2, 1); map.insert(3, 4); - map[4]; + map[&4]; } #[test] diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index feacbf1e98b..290c48b1310 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -103,6 +103,7 @@ impl OsString { } } +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for OsString { type Output = OsStr; @@ -113,6 +114,17 @@ impl ops::Index for OsString { } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl ops::Index for OsString { + type Output = OsStr; + + #[inline] + fn index(&self, _index: ops::RangeFull) -> &OsStr { + unsafe { mem::transmute(self.inner.as_slice()) } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for OsString { type Target = OsStr; diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 3cc91bf54b4..9f3dae34c7a 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -634,6 +634,7 @@ impl Wtf8 { /// /// Panics when `begin` and `end` do not point to code point boundaries, /// or point beyond the end of the string. +#[cfg(stage0)] impl ops::Index> for Wtf8 { type Output = Wtf8; @@ -650,12 +651,36 @@ impl ops::Index> for Wtf8 { } } +/// Return a slice of the given string for the byte range [`begin`..`end`). +/// +/// # Panics +/// +/// Panics when `begin` and `end` do not point to code point boundaries, +/// or point beyond the end of the string. +#[cfg(not(stage0))] +impl ops::Index> for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, range: ops::Range) -> &Wtf8 { + // is_code_point_boundary checks that the index is in [0, .len()] + if range.start <= range.end && + is_code_point_boundary(self, range.start) && + is_code_point_boundary(self, range.end) { + unsafe { slice_unchecked(self, range.start, range.end) } + } else { + slice_error_fail(self, range.start, range.end) + } + } +} + /// Return a slice of the given string from byte `begin` to its end. /// /// # Panics /// /// Panics when `begin` is not at a code point boundary, /// or is beyond the end of the string. +#[cfg(stage0)] impl ops::Index> for Wtf8 { type Output = Wtf8; @@ -670,12 +695,34 @@ impl ops::Index> for Wtf8 { } } +/// Return a slice of the given string from byte `begin` to its end. +/// +/// # Panics +/// +/// Panics when `begin` is not at a code point boundary, +/// or is beyond the end of the string. +#[cfg(not(stage0))] +impl ops::Index> for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, range: ops::RangeFrom) -> &Wtf8 { + // is_code_point_boundary checks that the index is in [0, .len()] + if is_code_point_boundary(self, range.start) { + unsafe { slice_unchecked(self, range.start, self.len()) } + } else { + slice_error_fail(self, range.start, self.len()) + } + } +} + /// Return a slice of the given string from its beginning to byte `end`. /// /// # Panics /// /// Panics when `end` is not at a code point boundary, /// or is beyond the end of the string. +#[cfg(stage0)] impl ops::Index> for Wtf8 { type Output = Wtf8; @@ -690,6 +737,28 @@ impl ops::Index> for Wtf8 { } } +/// Return a slice of the given string from its beginning to byte `end`. +/// +/// # Panics +/// +/// Panics when `end` is not at a code point boundary, +/// or is beyond the end of the string. +#[cfg(not(stage0))] +impl ops::Index> for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, range: ops::RangeTo) -> &Wtf8 { + // is_code_point_boundary checks that the index is in [0, .len()] + if is_code_point_boundary(self, range.end) { + unsafe { slice_unchecked(self, 0, range.end) } + } else { + slice_error_fail(self, 0, range.end) + } + } +} + +#[cfg(stage0)] impl ops::Index for Wtf8 { type Output = Wtf8; @@ -699,6 +768,16 @@ impl ops::Index for Wtf8 { } } +#[cfg(not(stage0))] +impl ops::Index for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, _range: ops::RangeFull) -> &Wtf8 { + self + } +} + #[inline] fn decode_surrogate(second_byte: u8, third_byte: u8) -> u16 { // The first byte is assumed to be 0xED