Skip to content

Commit

Permalink
Rollup merge of #74989 - pubfnbar:impl-array-indexing, r=KodrAus
Browse files Browse the repository at this point in the history
Implement `Index` and `IndexMut` for arrays

Adds implementations of `Index` and `IndexMut` for arrays that simply forward to the slice indexing implementation in order to fix the following problem:

If you implement `Index<MyIndexType>` for an array, you lose all the other indexing functionality that used to be available to the array via its implicit coercion to a slice. An example of what I'm talking about:
```rust
use std::ops::Index;

pub enum MyIndexType {
    _0, _1, _2, _3, _4, _5, _6, _7,
}

impl<T> Index<MyIndexType> for [T; 8] {
    type Output = T;

    fn index(&self, index: MyIndexType) -> &T {
        unsafe { self.get_unchecked(index as usize) }
    }
}

fn main() {
    let array = [11u8; 8];

    println!("{:?}", array[MyIndexType::_0]); // OK

    println!("{:?}", array[0usize]); // error[E0277]
    //               ^^^^^^^^^^^^^ `[u8; 8]` cannot be indexed by `usize`
}
```
  • Loading branch information
m-ou-se authored Nov 16, 2020
2 parents f5230fb + c03dfa6 commit 4cdd220
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::convert::{Infallible, TryFrom};
use crate::fmt;
use crate::hash::{self, Hash};
use crate::marker::Unsize;
use crate::ops::{Index, IndexMut};
use crate::slice::{Iter, IterMut};

mod iter;
Expand Down Expand Up @@ -208,6 +209,30 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] {
}
}

#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
impl<T, I, const N: usize> Index<I> for [T; N]
where
[T]: Index<I>,
{
type Output = <[T] as Index<I>>::Output;

#[inline]
fn index(&self, index: I) -> &Self::Output {
Index::index(self as &[T], index)
}
}

#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
impl<T, I, const N: usize> IndexMut<I> for [T; N]
where
[T]: IndexMut<I>,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(self as &mut [T], index)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N]
where
Expand Down

0 comments on commit 4cdd220

Please sign in to comment.