Skip to content

Commit 03a61b1

Browse files
committed
Auto merge of #47832 - fintelia:vec-index, r=<try>
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.
2 parents 56733bc + 7f4e9c9 commit 03a61b1

File tree

3 files changed

+15
-134
lines changed

3 files changed

+15
-134
lines changed

src/liballoc/vec.rs

+7-127
Original file line numberDiff line numberDiff line change
@@ -1542,146 +1542,26 @@ impl<T: Hash> Hash for Vec<T> {
15421542

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

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

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

1565-
#[stable(feature = "rust1", since = "1.0.0")]
1566-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1567-
impl<T> ops::Index<ops::Range<usize>> for Vec<T> {
1568-
type Output = [T];
1569-
1570-
#[inline]
1571-
fn index(&self, index: ops::Range<usize>) -> &[T] {
1572-
Index::index(&**self, index)
1573-
}
1574-
}
1575-
1576-
#[stable(feature = "rust1", since = "1.0.0")]
1577-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1578-
impl<T> ops::Index<ops::RangeTo<usize>> for Vec<T> {
1579-
type Output = [T];
1580-
1581-
#[inline]
1582-
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
1583-
Index::index(&**self, index)
1584-
}
1585-
}
1586-
1587-
#[stable(feature = "rust1", since = "1.0.0")]
1588-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1589-
impl<T> ops::Index<ops::RangeFrom<usize>> for Vec<T> {
1590-
type Output = [T];
1591-
1592-
#[inline]
1593-
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
1594-
Index::index(&**self, index)
1595-
}
1596-
}
1597-
1598-
#[stable(feature = "rust1", since = "1.0.0")]
1599-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1600-
impl<T> ops::Index<ops::RangeFull> for Vec<T> {
1601-
type Output = [T];
1602-
1603-
#[inline]
1604-
fn index(&self, _index: ops::RangeFull) -> &[T] {
1605-
self
1606-
}
1607-
}
1608-
1609-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1610-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1611-
impl<T> ops::Index<ops::RangeInclusive<usize>> for Vec<T> {
1612-
type Output = [T];
1613-
1614-
#[inline]
1615-
fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] {
1616-
Index::index(&**self, index)
1617-
}
1618-
}
1619-
1620-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1621-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1622-
impl<T> ops::Index<ops::RangeToInclusive<usize>> for Vec<T> {
1623-
type Output = [T];
1624-
1625-
#[inline]
1626-
fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] {
1627-
Index::index(&**self, index)
1628-
}
1629-
}
1630-
1631-
#[stable(feature = "rust1", since = "1.0.0")]
1632-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1633-
impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
1634-
#[inline]
1635-
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
1636-
IndexMut::index_mut(&mut **self, index)
1637-
}
1638-
}
1639-
1640-
#[stable(feature = "rust1", since = "1.0.0")]
1641-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1642-
impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
1643-
#[inline]
1644-
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
1645-
IndexMut::index_mut(&mut **self, index)
1646-
}
1647-
}
1648-
1649-
#[stable(feature = "rust1", since = "1.0.0")]
1650-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1651-
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
1652-
#[inline]
1653-
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
1654-
IndexMut::index_mut(&mut **self, index)
1655-
}
1656-
}
1657-
1658-
#[stable(feature = "rust1", since = "1.0.0")]
1659-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1660-
impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
1661-
#[inline]
1662-
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] {
1663-
self
1664-
}
1665-
}
1666-
1667-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1668-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1669-
impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for Vec<T> {
1670-
#[inline]
1671-
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] {
1672-
IndexMut::index_mut(&mut **self, index)
1673-
}
1674-
}
1675-
1676-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1677-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1678-
impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for Vec<T> {
1679-
#[inline]
1680-
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] {
1681-
IndexMut::index_mut(&mut **self, index)
1682-
}
1683-
}
1684-
16851565
#[stable(feature = "rust1", since = "1.0.0")]
16861566
impl<T> ops::Deref for Vec<T> {
16871567
type Target = [T];

src/test/compile-fail/integral-indexing.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ pub fn main() {
1313
let s: String = "abcdef".to_string();
1414
v[3_usize];
1515
v[3];
16-
v[3u8]; //~ERROR : std::ops::Index<u8>` is not satisfied
17-
v[3i8]; //~ERROR : std::ops::Index<i8>` is not satisfied
18-
v[3u32]; //~ERROR : std::ops::Index<u32>` is not satisfied
19-
v[3i32]; //~ERROR : std::ops::Index<i32>` is not satisfied
16+
v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
17+
v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
18+
v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
19+
v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
2020
s.as_bytes()[3_usize];
2121
s.as_bytes()[3];
2222
s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied

src/test/ui/index-help.stderr

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::ops::Index<i32>` is not satisfied
1+
error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not satisfied
22
--> $DIR/index-help.rs:13:5
33
|
44
13 | x[0i32]; //~ ERROR E0277
5-
| ^^^^^^^ vector indices are of type `usize` or ranges of `usize`
5+
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
66
|
7-
= help: the trait `std::ops::Index<i32>` is not implemented for `std::vec::Vec<{integer}>`
7+
= help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32`
8+
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[{integer}]`
89

910
error: aborting due to previous error
1011

0 commit comments

Comments
 (0)