about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-07 04:14:22 +0000
committerbors <bors@rust-lang.org>2015-02-07 04:14:22 +0000
commit0b6dbbc9cfb747df1db646bba16561c022704056 (patch)
tree1b6bf9780361f2cd8bce65f44a1a5727676d1c6b /src/libcore
parent7ebf9bc5c22155d622537ded42b4ebf94238b296 (diff)
parent724bf7bce2b35ac5731cf7e217c0e87916517b69 (diff)
downloadrust-0b6dbbc9cfb747df1db646bba16561c022704056.tar.gz
rust-0b6dbbc9cfb747df1db646bba16561c022704056.zip
Auto merge of #21949 - japaric:index, r=nikomatsakis
closes #21630

Overloaded indexing (`&[mut] foo[bar]`) only works when `<Self as Index>::Output` is the same as `<Self as IndexMut>::Output` (see issue above). To restrict implementations of `IndexMut` that doesn't work, this PR makes `IndexMut` a supertrait over `Index`, i.e. `trait IndexMut<I>: Index<I>`, just like in the `trait DerefMut: Deref` case.

This breaks all downstream implementations of `IndexMut`, in most cases this simply means removing the `type Output = ..` bit, which is now redundant, from `IndexMut` implementations:

``` diff
 impl Index<Foo> for Bar {
     type Output = Baz;
     ..
 }

 impl IndexMut<Foo> for Bar {
-    type Output = Baz;
     ..
 }
```

[breaking-change]

---

r? @nikomatsakis 
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/ops.rs24
-rw-r--r--src/libcore/slice.rs10
2 files changed, 14 insertions, 20 deletions
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 7af94c73f32..782483a34fc 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -897,14 +897,14 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// }
 /// ```
 #[lang="index"]
-#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Index}`"]
+#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait Index<Index: ?Sized> {
+pub trait Index<Idx: ?Sized> {
     type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
+    fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output;
 }
 
 /// The `IndexMut` trait is used to specify the functionality of indexing
@@ -916,15 +916,21 @@ pub trait Index<Index: ?Sized> {
 /// calling `index_mut`, and therefore, `main` prints `Indexing!`.
 ///
 /// ```
-/// use std::ops::IndexMut;
+/// use std::ops::{Index, IndexMut};
 ///
 /// #[derive(Copy)]
 /// struct Foo;
 /// struct Bar;
 ///
-/// impl IndexMut<Bar> for Foo {
+/// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
+///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///         self
+///     }
+/// }
+///
+/// impl IndexMut<Bar> for Foo {
 ///     fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
 ///         println!("Indexing!");
 ///         self
@@ -936,14 +942,12 @@ pub trait Index<Index: ?Sized> {
 /// }
 /// ```
 #[lang="index_mut"]
-#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Index}`"]
+#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait IndexMut<Index: ?Sized> {
-    type Output: ?Sized;
-
+pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
     /// The method for the indexing (`Foo[Bar]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output;
+    fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output;
 }
 
 /// An unbounded range.
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index c622baa0cc2..fc51920ec6b 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -502,8 +502,6 @@ impl<T> ops::Index<uint> for [T] {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<uint> for [T] {
-    type Output = T;
-
     fn index_mut(&mut self, &index: &uint) -> &mut T {
         assert!(index < self.len());
 
@@ -553,7 +551,6 @@ impl<T> ops::Index<RangeFull> for [T] {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<uint>> for [T] {
-    type Output = [T];
     #[inline]
     fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] {
         assert!(index.start <= index.end);
@@ -568,7 +565,6 @@ impl<T> ops::IndexMut<ops::Range<uint>> for [T] {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 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 })
@@ -576,7 +572,6 @@ impl<T> ops::IndexMut<ops::RangeTo<uint>> for [T] {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 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();
@@ -585,7 +580,6 @@ impl<T> ops::IndexMut<ops::RangeFrom<uint>> for [T] {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<RangeFull> for [T] {
-    type Output = [T];
     #[inline]
     fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
         self
@@ -865,7 +859,6 @@ impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
 
 #[unstable(feature = "core")]
 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(&RangeFull).index_mut(index)
@@ -873,7 +866,6 @@ impl<'a, T> ops::IndexMut<ops::Range<uint>> for IterMut<'a, T> {
 }
 #[unstable(feature = "core")]
 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(&RangeFull).index_mut(index)
@@ -881,7 +873,6 @@ impl<'a, T> ops::IndexMut<ops::RangeTo<uint>> for IterMut<'a, T> {
 }
 #[unstable(feature = "core")]
 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(&RangeFull).index_mut(index)
@@ -889,7 +880,6 @@ impl<'a, T> ops::IndexMut<ops::RangeFrom<uint>> for IterMut<'a, T> {
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
-    type Output = [T];
     #[inline]
     fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
         make_slice!(T => &mut [T]: self.ptr, self.end)