Skip to content

Commit 1e1bfc7

Browse files
committed
Auto merge of rust-lang#47832 - fintelia:vec-index, r=kennytm
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 9ff5cb5 + 370df40 commit 1e1bfc7

File tree

3 files changed

+19
-134
lines changed

3 files changed

+19
-134
lines changed

src/liballoc/vec.rs

+11-127
Original file line numberDiff line numberDiff line change
@@ -1527,142 +1527,26 @@ impl<T: Hash> Hash for Vec<T> {
15271527

15281528
#[stable(feature = "rust1", since = "1.0.0")]
15291529
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1530-
impl<T> Index<usize> for Vec<T> {
1531-
type Output = T;
1532-
1533-
#[inline]
1534-
fn index(&self, index: usize) -> &T {
1535-
// NB built-in indexing via `&[T]`
1536-
&(**self)[index]
1537-
}
1538-
}
1539-
1540-
#[stable(feature = "rust1", since = "1.0.0")]
1541-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1542-
impl<T> IndexMut<usize> for Vec<T> {
1543-
#[inline]
1544-
fn index_mut(&mut self, index: usize) -> &mut T {
1545-
// NB built-in indexing via `&mut [T]`
1546-
&mut (**self)[index]
1547-
}
1548-
}
1549-
1550-
#[stable(feature = "rust1", since = "1.0.0")]
1551-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1552-
impl<T> ops::Index<ops::Range<usize>> for Vec<T> {
1553-
type Output = [T];
1554-
1555-
#[inline]
1556-
fn index(&self, index: ops::Range<usize>) -> &[T] {
1557-
Index::index(&**self, index)
1558-
}
1559-
}
1560-
1561-
#[stable(feature = "rust1", since = "1.0.0")]
1562-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1563-
impl<T> ops::Index<ops::RangeTo<usize>> for Vec<T> {
1564-
type Output = [T];
1565-
1566-
#[inline]
1567-
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
1568-
Index::index(&**self, index)
1569-
}
1570-
}
1571-
1572-
#[stable(feature = "rust1", since = "1.0.0")]
1573-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1574-
impl<T> ops::Index<ops::RangeFrom<usize>> for Vec<T> {
1575-
type Output = [T];
1576-
1577-
#[inline]
1578-
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
1579-
Index::index(&**self, index)
1580-
}
1581-
}
1582-
1583-
#[stable(feature = "rust1", since = "1.0.0")]
1584-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1585-
impl<T> ops::Index<ops::RangeFull> for Vec<T> {
1586-
type Output = [T];
1587-
1588-
#[inline]
1589-
fn index(&self, _index: ops::RangeFull) -> &[T] {
1590-
self
1591-
}
1592-
}
1593-
1594-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1595-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1596-
impl<T> ops::Index<ops::RangeInclusive<usize>> for Vec<T> {
1597-
type Output = [T];
1598-
1599-
#[inline]
1600-
fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] {
1601-
Index::index(&**self, index)
1602-
}
1603-
}
1604-
1605-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1606-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1607-
impl<T> ops::Index<ops::RangeToInclusive<usize>> for Vec<T> {
1608-
type Output = [T];
1530+
impl<T, I> Index<I> for Vec<T>
1531+
where
1532+
I: ::core::slice::SliceIndex<[T]>,
1533+
{
1534+
type Output = I::Output;
16091535

16101536
#[inline]
1611-
fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] {
1537+
fn index(&self, index: I) -> &Self::Output {
16121538
Index::index(&**self, index)
16131539
}
16141540
}
16151541

16161542
#[stable(feature = "rust1", since = "1.0.0")]
16171543
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1618-
impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
1619-
#[inline]
1620-
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
1621-
IndexMut::index_mut(&mut **self, index)
1622-
}
1623-
}
1624-
1625-
#[stable(feature = "rust1", since = "1.0.0")]
1626-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1627-
impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
1628-
#[inline]
1629-
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
1630-
IndexMut::index_mut(&mut **self, index)
1631-
}
1632-
}
1633-
1634-
#[stable(feature = "rust1", since = "1.0.0")]
1635-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1636-
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
1637-
#[inline]
1638-
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
1639-
IndexMut::index_mut(&mut **self, index)
1640-
}
1641-
}
1642-
1643-
#[stable(feature = "rust1", since = "1.0.0")]
1644-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1645-
impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
1646-
#[inline]
1647-
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] {
1648-
self
1649-
}
1650-
}
1651-
1652-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1653-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1654-
impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for Vec<T> {
1655-
#[inline]
1656-
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] {
1657-
IndexMut::index_mut(&mut **self, index)
1658-
}
1659-
}
1660-
1661-
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
1662-
#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"]
1663-
impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for Vec<T> {
1544+
impl<T, I> IndexMut<I> for Vec<T>
1545+
where
1546+
I: ::core::slice::SliceIndex<[T]>,
1547+
{
16641548
#[inline]
1665-
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] {
1549+
fn index_mut(&mut self, index: I) -> &mut Self::Output {
16661550
IndexMut::index_mut(&mut **self, index)
16671551
}
16681552
}

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
LL | 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 `std::vec::Vec<{integer}>`
89

910
error: aborting due to previous error
1011

0 commit comments

Comments
 (0)