Skip to content

Commit 293adaf

Browse files
committed
Expand a bit and add index methods to trait
1 parent e6abfff commit 293adaf

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

text/0000-panic-safe-slicing.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ Add "panic-safe" or "total" alternatives to the existing panicking indexing synt
1010
# Motivation
1111

1212
`SliceExt::get` and `SliceExt::get_mut` can be thought as non-panicking versions of the simple
13-
indexing syntax, `a[idx]`. However, there is no such equivalent for `a[start..end]`, `a[start..]`,
14-
or `a[..end]`. This RFC proposes such methods to fill the gap.
13+
indexing syntax, `a[idx]`, and `SliceExt::get_unchecked` and `SliceExt::get_unchecked_mut` can
14+
be thought of as unsafe versions with bounds checks elided. However, there is no such equivalent for
15+
`a[start..end]`, `a[start..]`, or `a[..end]`. This RFC proposes such methods to fill the gap.
1516

1617
# Detailed design
1718

18-
Introduce a `SliceIndex` trait which is implemented by types which can index into a slice:
19+
The `get`, `get_mut`, `get_unchecked`, and `get_unchecked_mut` will be made generic over `usize`
20+
as well as ranges of `usize` like slice's `Index` implementation currently is. This will allow e.g.
21+
`a.get(start..end)` which will behave analagously to `a[start..end]`.
22+
23+
Because methods cannot be overloaded in an ad-hoc manner in the same way that traits may be
24+
implemented, we introduce a `SliceIndex` trait which is implemented by types which can index into a
25+
slice:
1926
```rust
2027
pub trait SliceIndex<T> {
2128
type Output: ?Sized;
@@ -24,6 +31,8 @@ pub trait SliceIndex<T> {
2431
fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output>;
2532
unsafe fn get_unchecked(self, slice: &[T]) -> &Self::Output;
2633
unsafe fn get_mut_unchecked(self, slice: &[T]) -> &mut Self::Output;
34+
fn index(self, slice: &[T]) -> &Self::Output;
35+
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output;
2736
}
2837

2938
impl<T> SliceIndex<T> for usize {
@@ -39,7 +48,7 @@ impl<T, R> SliceIndex<T> for R
3948
}
4049
```
4150

42-
Alter the `Index`, `IndexMut`, `get`, `get_mut`, `get_unchecked`, and `get_mut_unchecked`
51+
And then alter the `Index`, `IndexMut`, `get`, `get_mut`, `get_unchecked`, and `get_mut_unchecked`
4352
implementations to be generic over `SliceIndex`:
4453
```rust
4554
impl<T> [T] {
@@ -74,15 +83,15 @@ impl<T, I> Index<I> for [T]
7483
type Output = I::Output;
7584

7685
fn index(&self, idx: I) -> &I::Output {
77-
self.get(idx).expect("out of bounds slice access")
86+
idx.index(self)
7887
}
7988
}
8089

8190
impl<T, I> IndexMut<I> for [T]
8291
where I: SliceIndex<T>
8392
{
8493
fn index_mut(&self, idx: I) -> &mut I::Output {
85-
self.get_mut(idx).expect("out of bounds slice access")
94+
idx.index_mut(self)
8695
}
8796
}
8897
```

0 commit comments

Comments
 (0)