about summary refs log tree commit diff
path: root/src
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
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')
-rw-r--r--src/libcollections/btree/map.rs2
-rw-r--r--src/libcollections/ring_buf.rs2
-rw-r--r--src/libcollections/vec.rs6
-rw-r--r--src/libcollections/vec_map.rs2
-rw-r--r--src/libcore/ops.rs24
-rw-r--r--src/libcore/slice.rs10
-rw-r--r--src/libstd/collections/hash/map.rs2
-rw-r--r--src/test/compile-fail/borrowck-overloaded-index-autoderef.rs2
-rw-r--r--src/test/compile-fail/borrowck-overloaded-index.rs2
-rw-r--r--src/test/run-pass/overloaded-index-autoderef.rs2
-rw-r--r--src/test/run-pass/overloaded-index.rs2
-rw-r--r--src/test/run-pass/slice.rs4
12 files changed, 14 insertions, 46 deletions
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 1b6057d4c72..aec50d53808 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -910,8 +910,6 @@ impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
 impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
     where Q: BorrowFrom<K> + Ord
 {
-    type Output = V;
-
     fn index_mut(&mut self, key: &Q) -> &mut V {
         self.get_mut(key).expect("no entry found for key")
     }
diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs
index f5df7018153..41749303840 100644
--- a/src/libcollections/ring_buf.rs
+++ b/src/libcollections/ring_buf.rs
@@ -1591,8 +1591,6 @@ impl<A> Index<usize> for RingBuf<A> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A> IndexMut<usize> for RingBuf<A> {
-    type Output = A;
-
     #[inline]
     fn index_mut(&mut self, i: &usize) -> &mut A {
         self.get_mut(*i).expect("Out of bounds access")
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 62640e1e250..4a082c3616c 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1286,8 +1286,6 @@ impl<T> Index<usize> for Vec<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IndexMut<usize> for Vec<T> {
-    type Output = T;
-
     #[inline]
     fn index_mut(&mut self, index: &usize) -> &mut T {
         // NB built-in indexing via `&mut [T]`
@@ -1331,7 +1329,6 @@ impl<T> ops::Index<ops::RangeFull> for Vec<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
-    type Output = [T];
     #[inline]
     fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
         IndexMut::index_mut(&mut **self, index)
@@ -1339,7 +1336,6 @@ impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
-    type Output = [T];
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
         IndexMut::index_mut(&mut **self, index)
@@ -1347,7 +1343,6 @@ impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
-    type Output = [T];
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
         IndexMut::index_mut(&mut **self, index)
@@ -1355,7 +1350,6 @@ impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
-    type Output = [T];
     #[inline]
     fn index_mut(&mut self, _index: &ops::RangeFull) -> &mut [T] {
         self.as_mut_slice()
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 65592d138c7..739b8d8ce19 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -712,8 +712,6 @@ impl<V> Index<usize> for VecMap<V> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<V> IndexMut<usize> for VecMap<V> {
-    type Output = V;
-
     #[inline]
     fn index_mut<'a>(&'a mut self, i: &usize) -> &'a mut V {
         self.get_mut(i).expect("key not present")
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)
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index aec9446773f..710f021d912 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1267,8 +1267,6 @@ impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
           S: HashState<Hasher=H>,
           H: hash::Hasher<Output=u64>
 {
-    type Output = V;
-
     #[inline]
     fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
         self.get_mut(index).expect("no entry found for key")
diff --git a/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs b/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
index 977c67b1c7d..99f396ef814 100644
--- a/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
+++ b/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
@@ -31,8 +31,6 @@ impl Index<String> for Foo {
 }
 
 impl IndexMut<String> for Foo {
-    type Output = isize;
-
     fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
         if *z == "x" {
             &mut self.x
diff --git a/src/test/compile-fail/borrowck-overloaded-index.rs b/src/test/compile-fail/borrowck-overloaded-index.rs
index 9e79154eb0c..2d752abe7e3 100644
--- a/src/test/compile-fail/borrowck-overloaded-index.rs
+++ b/src/test/compile-fail/borrowck-overloaded-index.rs
@@ -28,8 +28,6 @@ impl Index<String> for Foo {
 }
 
 impl IndexMut<String> for Foo {
-    type Output = isize;
-
     fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
         if *z == "x" {
             &mut self.x
diff --git a/src/test/run-pass/overloaded-index-autoderef.rs b/src/test/run-pass/overloaded-index-autoderef.rs
index 637d2c94694..d5ccf8cd2be 100644
--- a/src/test/run-pass/overloaded-index-autoderef.rs
+++ b/src/test/run-pass/overloaded-index-autoderef.rs
@@ -33,8 +33,6 @@ impl Index<int> for Foo {
 }
 
 impl IndexMut<int> for Foo {
-    type Output = int;
-
     fn index_mut(&mut self, z: &int) -> &mut int {
         if *z == 0 {
             &mut self.x
diff --git a/src/test/run-pass/overloaded-index.rs b/src/test/run-pass/overloaded-index.rs
index 0afdb24a81c..10ca3804eae 100644
--- a/src/test/run-pass/overloaded-index.rs
+++ b/src/test/run-pass/overloaded-index.rs
@@ -28,8 +28,6 @@ impl Index<int> for Foo {
 }
 
 impl IndexMut<int> for Foo {
-    type Output = int;
-
     fn index_mut(&mut self, z: &int) -> &mut int {
         if *z == 0 {
             &mut self.x
diff --git a/src/test/run-pass/slice.rs b/src/test/run-pass/slice.rs
index 59fb24ffc02..30b53dbb0ad 100644
--- a/src/test/run-pass/slice.rs
+++ b/src/test/run-pass/slice.rs
@@ -49,28 +49,24 @@ impl Index<RangeFull> for Foo {
 }
 
 impl IndexMut<Range<Foo>> for Foo {
-    type Output = Foo;
     fn index_mut(&mut self, index: &Range<Foo>) -> &mut Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl IndexMut<RangeTo<Foo>> for Foo {
-    type Output = Foo;
     fn index_mut(&mut self, index: &RangeTo<Foo>) -> &mut Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl IndexMut<RangeFrom<Foo>> for Foo {
-    type Output = Foo;
     fn index_mut(&mut self, index: &RangeFrom<Foo>) -> &mut Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl IndexMut<RangeFull> for Foo {
-    type Output = Foo;
     fn index_mut(&mut self, _index: &RangeFull) -> &mut Foo {
         unsafe { COUNT += 1; }
         self