Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9d379e1

Browse files
committedMar 12, 2025
Implement SliceIndex for ByteStr
1 parent 3a6d0ae commit 9d379e1

File tree

9 files changed

+158
-130
lines changed

9 files changed

+158
-130
lines changed
 

‎library/core/src/bstr/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ impl ByteStr {
9292
pub fn as_bytes(&self) -> &[u8] {
9393
&self.0
9494
}
95+
96+
#[doc(hidden)]
97+
#[unstable(feature = "bstr_internals", issue = "none")]
98+
#[inline]
99+
pub fn as_bytes_mut(&mut self) -> &mut [u8] {
100+
&mut self.0
101+
}
95102
}
96103

97104
#[unstable(feature = "bstr", issue = "134915")]

‎library/core/src/bstr/traits.rs

+90-88
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
33
use crate::bstr::ByteStr;
44
use crate::cmp::Ordering;
5-
use crate::hash;
6-
use crate::ops::{
7-
Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
8-
};
5+
use crate::slice::SliceIndex;
6+
use crate::{hash, ops, range};
97

108
#[unstable(feature = "bstr", issue = "134915")]
119
impl Ord for ByteStr {
@@ -149,127 +147,131 @@ impl_partial_eq_n!(ByteStr, [u8; N]);
149147
impl_partial_eq_n!(ByteStr, &[u8; N]);
150148

151149
#[unstable(feature = "bstr", issue = "134915")]
152-
impl Index<usize> for ByteStr {
153-
type Output = u8;
150+
impl<I> ops::Index<I> for ByteStr
151+
where
152+
I: SliceIndex<ByteStr>,
153+
{
154+
type Output = I::Output;
154155

155156
#[inline]
156-
fn index(&self, idx: usize) -> &u8 {
157-
&self.0[idx]
157+
fn index(&self, index: I) -> &I::Output {
158+
index.index(self)
158159
}
159160
}
160161

161162
#[unstable(feature = "bstr", issue = "134915")]
162-
impl Index<RangeFull> for ByteStr {
163-
type Output = ByteStr;
164-
163+
impl<I> ops::IndexMut<I> for ByteStr
164+
where
165+
I: SliceIndex<ByteStr>,
166+
{
165167
#[inline]
166-
fn index(&self, _: RangeFull) -> &ByteStr {
167-
self
168+
fn index_mut(&mut self, index: I) -> &mut I::Output {
169+
index.index_mut(self)
168170
}
169171
}
170172

171173
#[unstable(feature = "bstr", issue = "134915")]
172-
impl Index<Range<usize>> for ByteStr {
174+
unsafe impl SliceIndex<ByteStr> for ops::RangeFull {
173175
type Output = ByteStr;
174-
175176
#[inline]
176-
fn index(&self, r: Range<usize>) -> &ByteStr {
177-
ByteStr::from_bytes(&self.0[r])
177+
fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
178+
Some(slice)
178179
}
179-
}
180-
181-
#[unstable(feature = "bstr", issue = "134915")]
182-
impl Index<RangeInclusive<usize>> for ByteStr {
183-
type Output = ByteStr;
184-
185180
#[inline]
186-
fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
187-
ByteStr::from_bytes(&self.0[r])
181+
fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
182+
Some(slice)
188183
}
189-
}
190-
191-
#[unstable(feature = "bstr", issue = "134915")]
192-
impl Index<RangeFrom<usize>> for ByteStr {
193-
type Output = ByteStr;
194-
195184
#[inline]
196-
fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
197-
ByteStr::from_bytes(&self.0[r])
185+
unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
186+
slice
198187
}
199-
}
200-
201-
#[unstable(feature = "bstr", issue = "134915")]
202-
impl Index<RangeTo<usize>> for ByteStr {
203-
type Output = ByteStr;
204-
205188
#[inline]
206-
fn index(&self, r: RangeTo<usize>) -> &ByteStr {
207-
ByteStr::from_bytes(&self.0[r])
189+
unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
190+
slice
208191
}
209-
}
210-
211-
#[unstable(feature = "bstr", issue = "134915")]
212-
impl Index<RangeToInclusive<usize>> for ByteStr {
213-
type Output = ByteStr;
214-
215192
#[inline]
216-
fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
217-
ByteStr::from_bytes(&self.0[r])
193+
fn index(self, slice: &ByteStr) -> &Self::Output {
194+
slice
218195
}
219-
}
220-
221-
#[unstable(feature = "bstr", issue = "134915")]
222-
impl IndexMut<usize> for ByteStr {
223196
#[inline]
224-
fn index_mut(&mut self, idx: usize) -> &mut u8 {
225-
&mut self.0[idx]
197+
fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
198+
slice
226199
}
227200
}
228201

229202
#[unstable(feature = "bstr", issue = "134915")]
230-
impl IndexMut<RangeFull> for ByteStr {
203+
unsafe impl SliceIndex<ByteStr> for usize {
204+
type Output = u8;
231205
#[inline]
232-
fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
233-
self
206+
fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
207+
self.get(slice.as_bytes())
234208
}
235-
}
236-
237-
#[unstable(feature = "bstr", issue = "134915")]
238-
impl IndexMut<Range<usize>> for ByteStr {
239209
#[inline]
240-
fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
241-
ByteStr::from_bytes_mut(&mut self.0[r])
210+
fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
211+
self.get_mut(slice.as_bytes_mut())
242212
}
243-
}
244-
245-
#[unstable(feature = "bstr", issue = "134915")]
246-
impl IndexMut<RangeInclusive<usize>> for ByteStr {
247213
#[inline]
248-
fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
249-
ByteStr::from_bytes_mut(&mut self.0[r])
214+
unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
215+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
216+
unsafe { self.get_unchecked(slice as *const [u8]) }
250217
}
251-
}
252-
253-
#[unstable(feature = "bstr", issue = "134915")]
254-
impl IndexMut<RangeFrom<usize>> for ByteStr {
255218
#[inline]
256-
fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
257-
ByteStr::from_bytes_mut(&mut self.0[r])
219+
unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
220+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
221+
unsafe { self.get_unchecked_mut(slice as *mut [u8]) }
258222
}
259-
}
260-
261-
#[unstable(feature = "bstr", issue = "134915")]
262-
impl IndexMut<RangeTo<usize>> for ByteStr {
263223
#[inline]
264-
fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
265-
ByteStr::from_bytes_mut(&mut self.0[r])
224+
fn index(self, slice: &ByteStr) -> &Self::Output {
225+
self.index(slice.as_bytes())
266226
}
267-
}
268-
269-
#[unstable(feature = "bstr", issue = "134915")]
270-
impl IndexMut<RangeToInclusive<usize>> for ByteStr {
271227
#[inline]
272-
fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
273-
ByteStr::from_bytes_mut(&mut self.0[r])
228+
fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
229+
self.index_mut(slice.as_bytes_mut())
274230
}
275231
}
232+
233+
macro_rules! impl_slice_index {
234+
($index:ty) => {
235+
#[unstable(feature = "bstr", issue = "134915")]
236+
unsafe impl SliceIndex<ByteStr> for $index {
237+
type Output = ByteStr;
238+
#[inline]
239+
fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
240+
self.get(slice.as_bytes()).map(ByteStr::from_bytes)
241+
}
242+
#[inline]
243+
fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
244+
self.get_mut(slice.as_bytes_mut()).map(ByteStr::from_bytes_mut)
245+
}
246+
#[inline]
247+
unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
248+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
249+
unsafe { self.get_unchecked(slice as *const [u8]) as *const ByteStr }
250+
}
251+
#[inline]
252+
unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
253+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
254+
unsafe { self.get_unchecked_mut(slice as *mut [u8]) as *mut ByteStr }
255+
}
256+
#[inline]
257+
fn index(self, slice: &ByteStr) -> &Self::Output {
258+
ByteStr::from_bytes(self.index(slice.as_bytes()))
259+
}
260+
#[inline]
261+
fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
262+
ByteStr::from_bytes_mut(self.index_mut(slice.as_bytes_mut()))
263+
}
264+
}
265+
};
266+
}
267+
268+
impl_slice_index!(ops::IndexRange);
269+
impl_slice_index!(ops::Range<usize>);
270+
impl_slice_index!(range::Range<usize>);
271+
impl_slice_index!(ops::RangeTo<usize>);
272+
impl_slice_index!(ops::RangeFrom<usize>);
273+
impl_slice_index!(range::RangeFrom<usize>);
274+
impl_slice_index!(ops::RangeInclusive<usize>);
275+
impl_slice_index!(range::RangeInclusive<usize>);
276+
impl_slice_index!(ops::RangeToInclusive<usize>);
277+
impl_slice_index!((ops::Bound<usize>, ops::Bound<usize>));

‎tests/ui/indexing/index-help.stderr

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ LL | x[0i32];
55
| ^^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
8-
but it is implemented for `usize`
9-
= help: for that trait implementation, expected `usize`, found `i32`
8+
= help: the following other types implement trait `SliceIndex<T>`:
9+
`usize` implements `SliceIndex<ByteStr>`
10+
`usize` implements `SliceIndex<[T]>`
1011
= note: required for `Vec<{integer}>` to implement `Index<i32>`
1112

1213
error: aborting due to 1 previous error

‎tests/ui/indexing/indexing-requires-a-uint.stderr

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ LL | [0][0u8];
55
| ^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
8-
but it is implemented for `usize`
9-
= help: for that trait implementation, expected `usize`, found `u8`
8+
= help: the following other types implement trait `SliceIndex<T>`:
9+
`usize` implements `SliceIndex<ByteStr>`
10+
`usize` implements `SliceIndex<[T]>`
1011
= note: required for `[{integer}]` to implement `Index<u8>`
1112
= note: 1 redundant requirement hidden
1213
= note: required for `[{integer}; 1]` to implement `Index<u8>`

‎tests/ui/integral-indexing.stderr

+24-16
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ LL | v[3u8];
55
| ^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
8-
but it is implemented for `usize`
9-
= help: for that trait implementation, expected `usize`, found `u8`
8+
= help: the following other types implement trait `SliceIndex<T>`:
9+
`usize` implements `SliceIndex<ByteStr>`
10+
`usize` implements `SliceIndex<[T]>`
1011
= note: required for `Vec<isize>` to implement `Index<u8>`
1112

1213
error[E0277]: the type `[isize]` cannot be indexed by `i8`
@@ -16,8 +17,9 @@ LL | v[3i8];
1617
| ^^^ slice indices are of type `usize` or ranges of `usize`
1718
|
1819
= help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
19-
but it is implemented for `usize`
20-
= help: for that trait implementation, expected `usize`, found `i8`
20+
= help: the following other types implement trait `SliceIndex<T>`:
21+
`usize` implements `SliceIndex<ByteStr>`
22+
`usize` implements `SliceIndex<[T]>`
2123
= note: required for `Vec<isize>` to implement `Index<i8>`
2224

2325
error[E0277]: the type `[isize]` cannot be indexed by `u32`
@@ -27,8 +29,9 @@ LL | v[3u32];
2729
| ^^^^ slice indices are of type `usize` or ranges of `usize`
2830
|
2931
= help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
30-
but it is implemented for `usize`
31-
= help: for that trait implementation, expected `usize`, found `u32`
32+
= help: the following other types implement trait `SliceIndex<T>`:
33+
`usize` implements `SliceIndex<ByteStr>`
34+
`usize` implements `SliceIndex<[T]>`
3235
= note: required for `Vec<isize>` to implement `Index<u32>`
3336

3437
error[E0277]: the type `[isize]` cannot be indexed by `i32`
@@ -38,8 +41,9 @@ LL | v[3i32];
3841
| ^^^^ slice indices are of type `usize` or ranges of `usize`
3942
|
4043
= help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
41-
but it is implemented for `usize`
42-
= help: for that trait implementation, expected `usize`, found `i32`
44+
= help: the following other types implement trait `SliceIndex<T>`:
45+
`usize` implements `SliceIndex<ByteStr>`
46+
`usize` implements `SliceIndex<[T]>`
4347
= note: required for `Vec<isize>` to implement `Index<i32>`
4448

4549
error[E0277]: the type `[u8]` cannot be indexed by `u8`
@@ -49,8 +53,9 @@ LL | s.as_bytes()[3u8];
4953
| ^^^ slice indices are of type `usize` or ranges of `usize`
5054
|
5155
= help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
52-
but it is implemented for `usize`
53-
= help: for that trait implementation, expected `usize`, found `u8`
56+
= help: the following other types implement trait `SliceIndex<T>`:
57+
`usize` implements `SliceIndex<ByteStr>`
58+
`usize` implements `SliceIndex<[T]>`
5459
= note: required for `[u8]` to implement `Index<u8>`
5560

5661
error[E0277]: the type `[u8]` cannot be indexed by `i8`
@@ -60,8 +65,9 @@ LL | s.as_bytes()[3i8];
6065
| ^^^ slice indices are of type `usize` or ranges of `usize`
6166
|
6267
= help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
63-
but it is implemented for `usize`
64-
= help: for that trait implementation, expected `usize`, found `i8`
68+
= help: the following other types implement trait `SliceIndex<T>`:
69+
`usize` implements `SliceIndex<ByteStr>`
70+
`usize` implements `SliceIndex<[T]>`
6571
= note: required for `[u8]` to implement `Index<i8>`
6672

6773
error[E0277]: the type `[u8]` cannot be indexed by `u32`
@@ -71,8 +77,9 @@ LL | s.as_bytes()[3u32];
7177
| ^^^^ slice indices are of type `usize` or ranges of `usize`
7278
|
7379
= help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
74-
but it is implemented for `usize`
75-
= help: for that trait implementation, expected `usize`, found `u32`
80+
= help: the following other types implement trait `SliceIndex<T>`:
81+
`usize` implements `SliceIndex<ByteStr>`
82+
`usize` implements `SliceIndex<[T]>`
7683
= note: required for `[u8]` to implement `Index<u32>`
7784

7885
error[E0277]: the type `[u8]` cannot be indexed by `i32`
@@ -82,8 +89,9 @@ LL | s.as_bytes()[3i32];
8289
| ^^^^ slice indices are of type `usize` or ranges of `usize`
8390
|
8491
= help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
85-
but it is implemented for `usize`
86-
= help: for that trait implementation, expected `usize`, found `i32`
92+
= help: the following other types implement trait `SliceIndex<T>`:
93+
`usize` implements `SliceIndex<ByteStr>`
94+
`usize` implements `SliceIndex<[T]>`
8795
= note: required for `[u8]` to implement `Index<i32>`
8896

8997
error: aborting due to 8 previous errors

‎tests/ui/on-unimplemented/slice-index.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ LL | x[1i32];
55
| ^^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
8-
but it is implemented for `usize`
9-
= help: for that trait implementation, expected `usize`, found `i32`
8+
= help: the following other types implement trait `SliceIndex<T>`:
9+
`usize` implements `SliceIndex<ByteStr>`
10+
`usize` implements `SliceIndex<[T]>`
1011
= note: required for `[i32]` to implement `Index<i32>`
1112

1213
error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
@@ -17,6 +18,7 @@ LL | x[..1i32];
1718
|
1819
= help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>`
1920
= help: the following other types implement trait `SliceIndex<T>`:
21+
`RangeTo<usize>` implements `SliceIndex<ByteStr>`
2022
`RangeTo<usize>` implements `SliceIndex<[T]>`
2123
`RangeTo<usize>` implements `SliceIndex<str>`
2224
= note: required for `[i32]` to implement `Index<RangeTo<i32>>`
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.