Skip to content

Commit 0b6dbbc

Browse files
committed
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
2 parents 7ebf9bc + 724bf7b commit 0b6dbbc

File tree

12 files changed

+14
-46
lines changed

12 files changed

+14
-46
lines changed

src/libcollections/btree/map.rs

-2
Original file line numberDiff line numberDiff line change
@@ -910,8 +910,6 @@ impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
910910
impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
911911
where Q: BorrowFrom<K> + Ord
912912
{
913-
type Output = V;
914-
915913
fn index_mut(&mut self, key: &Q) -> &mut V {
916914
self.get_mut(key).expect("no entry found for key")
917915
}

src/libcollections/ring_buf.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1591,8 +1591,6 @@ impl<A> Index<usize> for RingBuf<A> {
15911591

15921592
#[stable(feature = "rust1", since = "1.0.0")]
15931593
impl<A> IndexMut<usize> for RingBuf<A> {
1594-
type Output = A;
1595-
15961594
#[inline]
15971595
fn index_mut(&mut self, i: &usize) -> &mut A {
15981596
self.get_mut(*i).expect("Out of bounds access")

src/libcollections/vec.rs

-6
Original file line numberDiff line numberDiff line change
@@ -1286,8 +1286,6 @@ impl<T> Index<usize> for Vec<T> {
12861286

12871287
#[stable(feature = "rust1", since = "1.0.0")]
12881288
impl<T> IndexMut<usize> for Vec<T> {
1289-
type Output = T;
1290-
12911289
#[inline]
12921290
fn index_mut(&mut self, index: &usize) -> &mut T {
12931291
// NB built-in indexing via `&mut [T]`
@@ -1331,31 +1329,27 @@ impl<T> ops::Index<ops::RangeFull> for Vec<T> {
13311329

13321330
#[stable(feature = "rust1", since = "1.0.0")]
13331331
impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
1334-
type Output = [T];
13351332
#[inline]
13361333
fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
13371334
IndexMut::index_mut(&mut **self, index)
13381335
}
13391336
}
13401337
#[stable(feature = "rust1", since = "1.0.0")]
13411338
impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
1342-
type Output = [T];
13431339
#[inline]
13441340
fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
13451341
IndexMut::index_mut(&mut **self, index)
13461342
}
13471343
}
13481344
#[stable(feature = "rust1", since = "1.0.0")]
13491345
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
1350-
type Output = [T];
13511346
#[inline]
13521347
fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
13531348
IndexMut::index_mut(&mut **self, index)
13541349
}
13551350
}
13561351
#[stable(feature = "rust1", since = "1.0.0")]
13571352
impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
1358-
type Output = [T];
13591353
#[inline]
13601354
fn index_mut(&mut self, _index: &ops::RangeFull) -> &mut [T] {
13611355
self.as_mut_slice()

src/libcollections/vec_map.rs

-2
Original file line numberDiff line numberDiff line change
@@ -712,8 +712,6 @@ impl<V> Index<usize> for VecMap<V> {
712712

713713
#[stable(feature = "rust1", since = "1.0.0")]
714714
impl<V> IndexMut<usize> for VecMap<V> {
715-
type Output = V;
716-
717715
#[inline]
718716
fn index_mut<'a>(&'a mut self, i: &usize) -> &'a mut V {
719717
self.get_mut(i).expect("key not present")

src/libcore/ops.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -897,14 +897,14 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
897897
/// }
898898
/// ```
899899
#[lang="index"]
900-
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Index}`"]
900+
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
901901
#[stable(feature = "rust1", since = "1.0.0")]
902-
pub trait Index<Index: ?Sized> {
902+
pub trait Index<Idx: ?Sized> {
903903
type Output: ?Sized;
904904

905905
/// The method for the indexing (`Foo[Bar]`) operation
906906
#[stable(feature = "rust1", since = "1.0.0")]
907-
fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
907+
fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output;
908908
}
909909

910910
/// The `IndexMut` trait is used to specify the functionality of indexing
@@ -916,15 +916,21 @@ pub trait Index<Index: ?Sized> {
916916
/// calling `index_mut`, and therefore, `main` prints `Indexing!`.
917917
///
918918
/// ```
919-
/// use std::ops::IndexMut;
919+
/// use std::ops::{Index, IndexMut};
920920
///
921921
/// #[derive(Copy)]
922922
/// struct Foo;
923923
/// struct Bar;
924924
///
925-
/// impl IndexMut<Bar> for Foo {
925+
/// impl Index<Bar> for Foo {
926926
/// type Output = Foo;
927927
///
928+
/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
929+
/// self
930+
/// }
931+
/// }
932+
///
933+
/// impl IndexMut<Bar> for Foo {
928934
/// fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
929935
/// println!("Indexing!");
930936
/// self
@@ -936,14 +942,12 @@ pub trait Index<Index: ?Sized> {
936942
/// }
937943
/// ```
938944
#[lang="index_mut"]
939-
#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Index}`"]
945+
#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
940946
#[stable(feature = "rust1", since = "1.0.0")]
941-
pub trait IndexMut<Index: ?Sized> {
942-
type Output: ?Sized;
943-
947+
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
944948
/// The method for the indexing (`Foo[Bar]`) operation
945949
#[stable(feature = "rust1", since = "1.0.0")]
946-
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output;
950+
fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output;
947951
}
948952

949953
/// An unbounded range.

src/libcore/slice.rs

-10
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,6 @@ impl<T> ops::Index<uint> for [T] {
502502

503503
#[stable(feature = "rust1", since = "1.0.0")]
504504
impl<T> ops::IndexMut<uint> for [T] {
505-
type Output = T;
506-
507505
fn index_mut(&mut self, &index: &uint) -> &mut T {
508506
assert!(index < self.len());
509507

@@ -553,7 +551,6 @@ impl<T> ops::Index<RangeFull> for [T] {
553551

554552
#[stable(feature = "rust1", since = "1.0.0")]
555553
impl<T> ops::IndexMut<ops::Range<uint>> for [T] {
556-
type Output = [T];
557554
#[inline]
558555
fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] {
559556
assert!(index.start <= index.end);
@@ -568,15 +565,13 @@ impl<T> ops::IndexMut<ops::Range<uint>> for [T] {
568565
}
569566
#[stable(feature = "rust1", since = "1.0.0")]
570567
impl<T> ops::IndexMut<ops::RangeTo<uint>> for [T] {
571-
type Output = [T];
572568
#[inline]
573569
fn index_mut(&mut self, index: &ops::RangeTo<uint>) -> &mut [T] {
574570
self.index_mut(&ops::Range{ start: 0, end: index.end })
575571
}
576572
}
577573
#[stable(feature = "rust1", since = "1.0.0")]
578574
impl<T> ops::IndexMut<ops::RangeFrom<uint>> for [T] {
579-
type Output = [T];
580575
#[inline]
581576
fn index_mut(&mut self, index: &ops::RangeFrom<uint>) -> &mut [T] {
582577
let len = self.len();
@@ -585,7 +580,6 @@ impl<T> ops::IndexMut<ops::RangeFrom<uint>> for [T] {
585580
}
586581
#[stable(feature = "rust1", since = "1.0.0")]
587582
impl<T> ops::IndexMut<RangeFull> for [T] {
588-
type Output = [T];
589583
#[inline]
590584
fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
591585
self
@@ -865,31 +859,27 @@ impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
865859

866860
#[unstable(feature = "core")]
867861
impl<'a, T> ops::IndexMut<ops::Range<uint>> for IterMut<'a, T> {
868-
type Output = [T];
869862
#[inline]
870863
fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] {
871864
self.index_mut(&RangeFull).index_mut(index)
872865
}
873866
}
874867
#[unstable(feature = "core")]
875868
impl<'a, T> ops::IndexMut<ops::RangeTo<uint>> for IterMut<'a, T> {
876-
type Output = [T];
877869
#[inline]
878870
fn index_mut(&mut self, index: &ops::RangeTo<uint>) -> &mut [T] {
879871
self.index_mut(&RangeFull).index_mut(index)
880872
}
881873
}
882874
#[unstable(feature = "core")]
883875
impl<'a, T> ops::IndexMut<ops::RangeFrom<uint>> for IterMut<'a, T> {
884-
type Output = [T];
885876
#[inline]
886877
fn index_mut(&mut self, index: &ops::RangeFrom<uint>) -> &mut [T] {
887878
self.index_mut(&RangeFull).index_mut(index)
888879
}
889880
}
890881
#[unstable(feature = "core")]
891882
impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
892-
type Output = [T];
893883
#[inline]
894884
fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
895885
make_slice!(T => &mut [T]: self.ptr, self.end)

src/libstd/collections/hash/map.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1267,8 +1267,6 @@ impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
12671267
S: HashState<Hasher=H>,
12681268
H: hash::Hasher<Output=u64>
12691269
{
1270-
type Output = V;
1271-
12721270
#[inline]
12731271
fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
12741272
self.get_mut(index).expect("no entry found for key")

src/test/compile-fail/borrowck-overloaded-index-autoderef.rs

-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ impl Index<String> for Foo {
3131
}
3232

3333
impl IndexMut<String> for Foo {
34-
type Output = isize;
35-
3634
fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
3735
if *z == "x" {
3836
&mut self.x

src/test/compile-fail/borrowck-overloaded-index.rs

-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ impl Index<String> for Foo {
2828
}
2929

3030
impl IndexMut<String> for Foo {
31-
type Output = isize;
32-
3331
fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
3432
if *z == "x" {
3533
&mut self.x

src/test/run-pass/overloaded-index-autoderef.rs

-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ impl Index<int> for Foo {
3333
}
3434

3535
impl IndexMut<int> for Foo {
36-
type Output = int;
37-
3836
fn index_mut(&mut self, z: &int) -> &mut int {
3937
if *z == 0 {
4038
&mut self.x

src/test/run-pass/overloaded-index.rs

-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ impl Index<int> for Foo {
2828
}
2929

3030
impl IndexMut<int> for Foo {
31-
type Output = int;
32-
3331
fn index_mut(&mut self, z: &int) -> &mut int {
3432
if *z == 0 {
3533
&mut self.x

src/test/run-pass/slice.rs

-4
Original file line numberDiff line numberDiff line change
@@ -49,28 +49,24 @@ impl Index<RangeFull> for Foo {
4949
}
5050

5151
impl IndexMut<Range<Foo>> for Foo {
52-
type Output = Foo;
5352
fn index_mut(&mut self, index: &Range<Foo>) -> &mut Foo {
5453
unsafe { COUNT += 1; }
5554
self
5655
}
5756
}
5857
impl IndexMut<RangeTo<Foo>> for Foo {
59-
type Output = Foo;
6058
fn index_mut(&mut self, index: &RangeTo<Foo>) -> &mut Foo {
6159
unsafe { COUNT += 1; }
6260
self
6361
}
6462
}
6563
impl IndexMut<RangeFrom<Foo>> for Foo {
66-
type Output = Foo;
6764
fn index_mut(&mut self, index: &RangeFrom<Foo>) -> &mut Foo {
6865
unsafe { COUNT += 1; }
6966
self
7067
}
7168
}
7269
impl IndexMut<RangeFull> for Foo {
73-
type Output = Foo;
7470
fn index_mut(&mut self, _index: &RangeFull) -> &mut Foo {
7571
unsafe { COUNT += 1; }
7672
self

0 commit comments

Comments
 (0)