Skip to content

Commit

Permalink
Auto merge of #47832 - fintelia:vec-index, r=<try>
Browse files Browse the repository at this point in the history
Have Vec use slice's implementations of Index<I> and IndexMut<I>

This PR simplifies the implementation of Index and IndexMut on Vec, and in the process enables indexing Vec by any user types that implement SliceIndex.

The stability annotations probably need to be changed, but I wasn't sure of the right way to do that. It also wasn't completely clear to me if this change could break any existing code.
  • Loading branch information
bors committed Feb 1, 2018
2 parents 56733bc + 7f4e9c9 commit 03a61b1
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 134 deletions.
134 changes: 7 additions & 127 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1542,146 +1542,26 @@ impl<T: Hash> Hash for Vec<T> {

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> Index<usize> for Vec<T> {
type Output = T;
impl<T, I> Index<I> for Vec<T> where [T]: Index<I> {
type Output = <[T] as Index<I>>::Output;

#[inline]
fn index(&self, index: usize) -> &T {
// NB built-in indexing via `&[T]`
fn index(&self, index: I) -> &Self::Output {
// NB indexing via implementation on slice
&(**self)[index]
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> IndexMut<usize> for Vec<T> {
impl<T, I> IndexMut<I> for Vec<T> where [T]: IndexMut<I> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut T {
// NB built-in indexing via `&mut [T]`
fn index_mut(&mut self, index: I) -> &mut Self::Output {
// NB indexing via implementation on slice
&mut (**self)[index]
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::Index<ops::Range<usize>> for Vec<T> {
type Output = [T];

#[inline]
fn index(&self, index: ops::Range<usize>) -> &[T] {
Index::index(&**self, index)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::Index<ops::RangeTo<usize>> for Vec<T> {
type Output = [T];

#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
Index::index(&**self, index)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::Index<ops::RangeFrom<usize>> for Vec<T> {
type Output = [T];

#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
Index::index(&**self, index)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::Index<ops::RangeFull> for Vec<T> {
type Output = [T];

#[inline]
fn index(&self, _index: ops::RangeFull) -> &[T] {
self
}
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
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")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
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")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
#[inline]
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
#[inline]
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
#[inline]
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
#[inline]
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] {
self
}
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
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")]
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
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> {
type Target = [T];
Expand Down
8 changes: 4 additions & 4 deletions src/test/compile-fail/integral-indexing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ pub fn main() {
let s: String = "abcdef".to_string();
v[3_usize];
v[3];
v[3u8]; //~ERROR : std::ops::Index<u8>` is not satisfied
v[3i8]; //~ERROR : std::ops::Index<i8>` is not satisfied
v[3u32]; //~ERROR : std::ops::Index<u32>` is not satisfied
v[3i32]; //~ERROR : std::ops::Index<i32>` is not satisfied
v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
s.as_bytes()[3_usize];
s.as_bytes()[3];
s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
Expand Down
7 changes: 4 additions & 3 deletions src/test/ui/index-help.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::ops::Index<i32>` is not satisfied
error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not satisfied
--> $DIR/index-help.rs:13:5
|
13 | x[0i32]; //~ ERROR E0277
| ^^^^^^^ vector indices are of type `usize` or ranges of `usize`
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::ops::Index<i32>` is not implemented for `std::vec::Vec<{integer}>`
= help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[{integer}]`

error: aborting due to previous error

0 comments on commit 03a61b1

Please sign in to comment.