about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThalia Archibald <thalia@archibald.dev>2025-03-11 17:37:36 -0700
committerThalia Archibald <thalia@archibald.dev>2025-03-11 20:26:10 -0700
commit9d379e11a6e9d8b491ce7143600495ae101e8c69 (patch)
tree2f9075eaf7945fe612cefd08ff20b6d1cfddd2da
parent3a6d0ae0086baf30df19390700560c5a346dbe0e (diff)
downloadrust-9d379e11a6e9d8b491ce7143600495ae101e8c69.tar.gz
rust-9d379e11a6e9d8b491ce7143600495ae101e8c69.zip
Implement SliceIndex for ByteStr
-rw-r--r--library/core/src/bstr/mod.rs7
-rw-r--r--library/core/src/bstr/traits.rs178
-rw-r--r--tests/ui/indexing/index-help.stderr5
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.stderr5
-rw-r--r--tests/ui/integral-indexing.stderr40
-rw-r--r--tests/ui/on-unimplemented/slice-index.stderr6
-rw-r--r--tests/ui/str/str-idx.stderr21
-rw-r--r--tests/ui/str/str-mut-idx.stderr19
-rw-r--r--tests/ui/suggestions/suggest-dereferencing-index.stderr7
9 files changed, 158 insertions, 130 deletions
diff --git a/library/core/src/bstr/mod.rs b/library/core/src/bstr/mod.rs
index c33dd244ad9..c8d0c701ba8 100644
--- a/library/core/src/bstr/mod.rs
+++ b/library/core/src/bstr/mod.rs
@@ -92,6 +92,13 @@ impl ByteStr {
     pub fn as_bytes(&self) -> &[u8] {
         &self.0
     }
+
+    #[doc(hidden)]
+    #[unstable(feature = "bstr_internals", issue = "none")]
+    #[inline]
+    pub fn as_bytes_mut(&mut self) -> &mut [u8] {
+        &mut self.0
+    }
 }
 
 #[unstable(feature = "bstr", issue = "134915")]
diff --git a/library/core/src/bstr/traits.rs b/library/core/src/bstr/traits.rs
index 14b862cbb3c..ff46bb13ba4 100644
--- a/library/core/src/bstr/traits.rs
+++ b/library/core/src/bstr/traits.rs
@@ -2,10 +2,8 @@
 
 use crate::bstr::ByteStr;
 use crate::cmp::Ordering;
-use crate::hash;
-use crate::ops::{
-    Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
-};
+use crate::slice::SliceIndex;
+use crate::{hash, ops, range};
 
 #[unstable(feature = "bstr", issue = "134915")]
 impl Ord for ByteStr {
@@ -149,127 +147,131 @@ impl_partial_eq_n!(ByteStr, [u8; N]);
 impl_partial_eq_n!(ByteStr, &[u8; N]);
 
 #[unstable(feature = "bstr", issue = "134915")]
-impl Index<usize> for ByteStr {
-    type Output = u8;
+impl<I> ops::Index<I> for ByteStr
+where
+    I: SliceIndex<ByteStr>,
+{
+    type Output = I::Output;
 
     #[inline]
-    fn index(&self, idx: usize) -> &u8 {
-        &self.0[idx]
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
     }
 }
 
 #[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeFull> for ByteStr {
-    type Output = ByteStr;
-
+impl<I> ops::IndexMut<I> for ByteStr
+where
+    I: SliceIndex<ByteStr>,
+{
     #[inline]
-    fn index(&self, _: RangeFull) -> &ByteStr {
-        self
+    fn index_mut(&mut self, index: I) -> &mut I::Output {
+        index.index_mut(self)
     }
 }
 
 #[unstable(feature = "bstr", issue = "134915")]
-impl Index<Range<usize>> for ByteStr {
+unsafe impl SliceIndex<ByteStr> for ops::RangeFull {
     type Output = ByteStr;
-
     #[inline]
-    fn index(&self, r: Range<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
+    fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
+        Some(slice)
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeInclusive<usize>> for ByteStr {
-    type Output = ByteStr;
-
     #[inline]
-    fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
+    fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
+        Some(slice)
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeFrom<usize>> for ByteStr {
-    type Output = ByteStr;
-
     #[inline]
-    fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
+    unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
+        slice
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeTo<usize>> for ByteStr {
-    type Output = ByteStr;
-
     #[inline]
-    fn index(&self, r: RangeTo<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
+    unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
+        slice
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl Index<RangeToInclusive<usize>> for ByteStr {
-    type Output = ByteStr;
-
     #[inline]
-    fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
-        ByteStr::from_bytes(&self.0[r])
+    fn index(self, slice: &ByteStr) -> &Self::Output {
+        slice
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<usize> for ByteStr {
     #[inline]
-    fn index_mut(&mut self, idx: usize) -> &mut u8 {
-        &mut self.0[idx]
+    fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
+        slice
     }
 }
 
 #[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeFull> for ByteStr {
+unsafe impl SliceIndex<ByteStr> for usize {
+    type Output = u8;
     #[inline]
-    fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
-        self
+    fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
+        self.get(slice.as_bytes())
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<Range<usize>> for ByteStr {
     #[inline]
-    fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
+    fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
+        self.get_mut(slice.as_bytes_mut())
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeInclusive<usize>> for ByteStr {
     #[inline]
-    fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
+    unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { self.get_unchecked(slice as *const [u8]) }
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeFrom<usize>> for ByteStr {
     #[inline]
-    fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
+    unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { self.get_unchecked_mut(slice as *mut [u8]) }
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeTo<usize>> for ByteStr {
     #[inline]
-    fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
+    fn index(self, slice: &ByteStr) -> &Self::Output {
+        self.index(slice.as_bytes())
     }
-}
-
-#[unstable(feature = "bstr", issue = "134915")]
-impl IndexMut<RangeToInclusive<usize>> for ByteStr {
     #[inline]
-    fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
-        ByteStr::from_bytes_mut(&mut self.0[r])
+    fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
+        self.index_mut(slice.as_bytes_mut())
     }
 }
+
+macro_rules! impl_slice_index {
+    ($index:ty) => {
+        #[unstable(feature = "bstr", issue = "134915")]
+        unsafe impl SliceIndex<ByteStr> for $index {
+            type Output = ByteStr;
+            #[inline]
+            fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
+                self.get(slice.as_bytes()).map(ByteStr::from_bytes)
+            }
+            #[inline]
+            fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
+                self.get_mut(slice.as_bytes_mut()).map(ByteStr::from_bytes_mut)
+            }
+            #[inline]
+            unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
+                // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+                unsafe { self.get_unchecked(slice as *const [u8]) as *const ByteStr }
+            }
+            #[inline]
+            unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
+                // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+                unsafe { self.get_unchecked_mut(slice as *mut [u8]) as *mut ByteStr }
+            }
+            #[inline]
+            fn index(self, slice: &ByteStr) -> &Self::Output {
+                ByteStr::from_bytes(self.index(slice.as_bytes()))
+            }
+            #[inline]
+            fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
+                ByteStr::from_bytes_mut(self.index_mut(slice.as_bytes_mut()))
+            }
+        }
+    };
+}
+
+impl_slice_index!(ops::IndexRange);
+impl_slice_index!(ops::Range<usize>);
+impl_slice_index!(range::Range<usize>);
+impl_slice_index!(ops::RangeTo<usize>);
+impl_slice_index!(ops::RangeFrom<usize>);
+impl_slice_index!(range::RangeFrom<usize>);
+impl_slice_index!(ops::RangeInclusive<usize>);
+impl_slice_index!(range::RangeInclusive<usize>);
+impl_slice_index!(ops::RangeToInclusive<usize>);
+impl_slice_index!((ops::Bound<usize>, ops::Bound<usize>));
diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr
index 1974e13eabc..ac79e3f12bd 100644
--- a/tests/ui/indexing/index-help.stderr
+++ b/tests/ui/indexing/index-help.stderr
@@ -5,8 +5,9 @@ LL |     x[0i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<{integer}>` to implement `Index<i32>`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr
index 5c60a30946d..62a1ca3d057 100644
--- a/tests/ui/indexing/indexing-requires-a-uint.stderr
+++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
@@ -5,8 +5,9 @@ LL |     [0][0u8];
    |         ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[{integer}]` to implement `Index<u8>`
    = note: 1 redundant requirement hidden
    = note: required for `[{integer}; 1]` to implement `Index<u8>`
diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr
index e7a45c2c88d..26253e078cb 100644
--- a/tests/ui/integral-indexing.stderr
+++ b/tests/ui/integral-indexing.stderr
@@ -5,8 +5,9 @@ LL |     v[3u8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<u8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i8`
@@ -16,8 +17,9 @@ LL |     v[3i8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<i8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `u32`
@@ -27,8 +29,9 @@ LL |     v[3u32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<u32>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i32`
@@ -38,8 +41,9 @@ LL |     v[3i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `Vec<isize>` to implement `Index<i32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u8`
@@ -49,8 +53,9 @@ LL |     s.as_bytes()[3u8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<u8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i8`
@@ -60,8 +65,9 @@ LL |     s.as_bytes()[3i8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i8`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<i8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u32`
@@ -71,8 +77,9 @@ LL |     s.as_bytes()[3u32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `u32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<u32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i32`
@@ -82,8 +89,9 @@ LL |     s.as_bytes()[3i32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[u8]` to implement `Index<i32>`
 
 error: aborting due to 8 previous errors
diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr
index 0a9ebe3f088..e011826bc8f 100644
--- a/tests/ui/on-unimplemented/slice-index.stderr
+++ b/tests/ui/on-unimplemented/slice-index.stderr
@@ -5,8 +5,9 @@ LL |     x[1i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
-           but it is implemented for `usize`
-   = help: for that trait implementation, expected `usize`, found `i32`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[i32]` to implement `Index<i32>`
 
 error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
@@ -17,6 +18,7 @@ LL |     x[..1i32];
    |
    = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>`
    = help: the following other types implement trait `SliceIndex<T>`:
+             `RangeTo<usize>` implements `SliceIndex<ByteStr>`
              `RangeTo<usize>` implements `SliceIndex<[T]>`
              `RangeTo<usize>` implements `SliceIndex<str>`
    = note: required for `[i32]` to implement `Index<RangeTo<i32>>`
diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr
index bedbbd9cb50..60cae7e84e3 100644
--- a/tests/ui/str/str-idx.stderr
+++ b/tests/ui/str/str-idx.stderr
@@ -4,11 +4,12 @@ error[E0277]: the type `str` cannot be indexed by `{integer}`
 LL |     let _: u8 = s[4];
    |                   ^ string indices are ranges of `usize`
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `str` to implement `Index<{integer}>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -19,11 +20,12 @@ LL |     let _ = s.get(4);
    |               |
    |               required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
@@ -35,11 +37,12 @@ LL |     let _ = s.get_unchecked(4);
    |               |
    |               required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get_unchecked`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr
index f09a4c329e5..4e3fe126ed8 100644
--- a/tests/ui/str/str-mut-idx.stderr
+++ b/tests/ui/str/str-mut-idx.stderr
@@ -31,8 +31,9 @@ LL |     s[1usize] = bot();
    |       ^^^^^^ string indices are ranges of `usize`
    |
    = help: the trait `SliceIndex<str>` is not implemented for `usize`
-           but trait `SliceIndex<[_]>` is implemented for it
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `str` to implement `Index<usize>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -43,11 +44,12 @@ LL |     s.get_mut(1);
    |       |
    |       required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get_mut`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
@@ -59,11 +61,12 @@ LL |     s.get_unchecked_mut(1);
    |       |
    |       required by a bound introduced by this call
    |
+   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
-           but trait `SliceIndex<[_]>` is implemented for `usize`
-   = help: for that trait implementation, expected `[_]`, found `str`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
 note: required by a bound in `core::str::<impl str>::get_unchecked_mut`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr
index 0335d8eafde..937f32677a6 100644
--- a/tests/ui/suggestions/suggest-dereferencing-index.stderr
+++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr
@@ -4,9 +4,10 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `&usize`
 LL |     let one_item_please: i32 = [1, 2, 3][i];
    |                                          ^ slice indices are of type `usize` or ranges of `usize`
    |
-   = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&_`
-           but it is implemented for `_`
-   = help: for that trait implementation, expected `usize`, found `&usize`
+   = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
+   = help: the following other types implement trait `SliceIndex<T>`:
+             `usize` implements `SliceIndex<ByteStr>`
+             `usize` implements `SliceIndex<[T]>`
    = note: required for `[{integer}]` to implement `Index<&usize>`
    = note: 1 redundant requirement hidden
    = note: required for `[{integer}; 3]` to implement `Index<&usize>`