diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index c7960b3fb49c3..b404bd6f2f1bb 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -41,6 +41,8 @@ pub use core::slice::ArrayChunksMut;
 pub use core::slice::ArrayWindows;
 #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
 pub use core::slice::EscapeAscii;
+#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")]
+pub use core::slice::GetManyMutError;
 #[stable(feature = "slice_get_slice", since = "1.28.0")]
 pub use core::slice::SliceIndex;
 #[stable(feature = "from_ref", since = "1.28.0")]
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 19b7bb44f855a..e252df6d5441e 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -1076,5 +1076,5 @@ impl Error for crate::time::TryFromFloatSecsError {}
 #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
 impl Error for crate::ffi::FromBytesUntilNulError {}
 
-#[unstable(feature = "get_many_mut", issue = "104642")]
+#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")]
 impl<const N: usize> Error for crate::slice::GetManyMutError<N> {}
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 8b502624176b6..abaa8ce28a21c 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -4448,12 +4448,10 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_many_mut)]
-    ///
     /// let x = &mut [1, 2, 4];
     ///
     /// unsafe {
-    ///     let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    ///     let [a, b] = x.get_many_unchecked_mut(&[0, 2]);
     ///     *a *= 10;
     ///     *b *= 100;
     /// }
@@ -4462,11 +4460,11 @@ impl<T> [T] {
     ///
     /// [`get_many_mut`]: slice::get_many_mut
     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
-    #[unstable(feature = "get_many_mut", issue = "104642")]
+    #[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub unsafe fn get_many_unchecked_mut<const N: usize>(
         &mut self,
-        indices: [usize; N],
+        indices: &[usize; N],
     ) -> [&mut T; N] {
         // NB: This implementation is written as it is because any variation of
         // `indices.map(|i| self.get_unchecked_mut(i))` would make miri unhappy,
@@ -4495,22 +4493,20 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_many_mut)]
-    ///
     /// let v = &mut [1, 2, 3];
-    /// if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    /// if let Ok([a, b]) = v.get_many_mut(&[0, 2]) {
     ///     *a = 413;
     ///     *b = 612;
     /// }
     /// assert_eq!(v, &[413, 2, 612]);
     /// ```
-    #[unstable(feature = "get_many_mut", issue = "104642")]
+    #[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub fn get_many_mut<const N: usize>(
         &mut self,
-        indices: [usize; N],
+        indices: &[usize; N],
     ) -> Result<[&mut T; N], GetManyMutError<N>> {
-        if !get_many_check_valid(&indices, self.len()) {
+        if !get_many_check_valid(indices, self.len()) {
             return Err(GetManyMutError { _private: () });
         }
         // SAFETY: The `get_many_check_valid()` call checked that all indices
@@ -4851,20 +4847,30 @@ impl<T, const N: usize> SlicePattern for [T; N] {
 }
 
 /// This checks every index against each other, and against `len`.
-///
-/// This will do `binomial(N + 1, 2) = N * (N + 1) / 2 = 0, 1, 3, 6, 10, ..`
-/// comparison operations.
 fn get_many_check_valid<const N: usize>(indices: &[usize; N], len: usize) -> bool {
-    // NB: The optimizer should inline the loops into a sequence
-    // of instructions without additional branching.
-    let mut valid = true;
-    for (i, &idx) in indices.iter().enumerate() {
-        valid &= idx < len;
-        for &idx2 in &indices[..i] {
-            valid &= idx != idx2;
+    // Based on benchmarks, it is faster to sort starting with 9 indices.
+    if N >= 9 {
+        let mut sorted_indices = *indices;
+        sorted_indices.sort_unstable();
+        for &[i, j] in sorted_indices.array_windows() {
+            if i == j {
+                return false;
+            }
         }
+        let biggest_index = *sorted_indices.last().expect("indices array should not be empty");
+        biggest_index < len
+    } else {
+        // NB: The optimizer should inline the loops into a sequence
+        // of instructions without additional branching.
+        let mut valid = true;
+        for (i, &idx) in indices.iter().enumerate() {
+            valid &= idx < len;
+            for &idx2 in &indices[..i] {
+                valid &= idx != idx2;
+            }
+        }
+        valid
     }
-    valid
 }
 
 /// The error type returned by [`get_many_mut<N>`][`slice::get_many_mut`].
@@ -4876,27 +4882,25 @@ fn get_many_check_valid<const N: usize>(indices: &[usize; N], len: usize) -> boo
 /// # Examples
 ///
 /// ```
-/// #![feature(get_many_mut)]
-///
 /// let v = &mut [1, 2, 3];
-/// assert!(v.get_many_mut([0, 999]).is_err());
-/// assert!(v.get_many_mut([1, 1]).is_err());
+/// assert!(v.get_many_mut(&[0, 999]).is_err());
+/// assert!(v.get_many_mut(&[1, 1]).is_err());
 /// ```
-#[unstable(feature = "get_many_mut", issue = "104642")]
-// NB: The N here is there to be forward-compatible with adding more details
-// to the error type at a later point
+#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")]
+// NB: The N and the private field here is there to be forward-compatible with
+// adding more details to the error type at a later point
 pub struct GetManyMutError<const N: usize> {
     _private: (),
 }
 
-#[unstable(feature = "get_many_mut", issue = "104642")]
+#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")]
 impl<const N: usize> fmt::Debug for GetManyMutError<N> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("GetManyMutError").finish_non_exhaustive()
     }
 }
 
-#[unstable(feature = "get_many_mut", issue = "104642")]
+#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")]
 impl<const N: usize> fmt::Display for GetManyMutError<N> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt("an index is out of bounds or appeared multiple times in the array", f)
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 51d57c9e37d7c..e16c7740e38b1 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -110,7 +110,6 @@
 #![feature(error_generic_member_access)]
 #![feature(trait_upcasting)]
 #![feature(is_ascii_octdigit)]
-#![feature(get_many_mut)]
 #![feature(iter_map_windows)]
 #![allow(internal_features)]
 #![deny(unsafe_op_in_unsafe_fn)]
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 4cbbabb672ba0..f3e7d27dc77af 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2599,7 +2599,7 @@ fn test_flatten_mut_size_overflow() {
 #[test]
 fn test_get_many_mut_normal_2() {
     let mut v = vec![1, 2, 3, 4, 5];
-    let [a, b] = v.get_many_mut([3, 0]).unwrap();
+    let [a, b] = v.get_many_mut(&[3, 0]).unwrap();
     *a += 10;
     *b += 100;
     assert_eq!(v, vec![101, 2, 3, 14, 5]);
@@ -2608,7 +2608,7 @@ fn test_get_many_mut_normal_2() {
 #[test]
 fn test_get_many_mut_normal_3() {
     let mut v = vec![1, 2, 3, 4, 5];
-    let [a, b, c] = v.get_many_mut([0, 4, 2]).unwrap();
+    let [a, b, c] = v.get_many_mut(&[0, 4, 2]).unwrap();
     *a += 10;
     *b += 100;
     *c += 1000;
@@ -2618,14 +2618,14 @@ fn test_get_many_mut_normal_3() {
 #[test]
 fn test_get_many_mut_empty() {
     let mut v = vec![1, 2, 3, 4, 5];
-    let [] = v.get_many_mut([]).unwrap();
+    let [] = v.get_many_mut(&[]).unwrap();
     assert_eq!(v, vec![1, 2, 3, 4, 5]);
 }
 
 #[test]
 fn test_get_many_mut_single_first() {
     let mut v = vec![1, 2, 3, 4, 5];
-    let [a] = v.get_many_mut([0]).unwrap();
+    let [a] = v.get_many_mut(&[0]).unwrap();
     *a += 10;
     assert_eq!(v, vec![11, 2, 3, 4, 5]);
 }
@@ -2633,7 +2633,7 @@ fn test_get_many_mut_single_first() {
 #[test]
 fn test_get_many_mut_single_last() {
     let mut v = vec![1, 2, 3, 4, 5];
-    let [a] = v.get_many_mut([4]).unwrap();
+    let [a] = v.get_many_mut(&[4]).unwrap();
     *a += 10;
     assert_eq!(v, vec![1, 2, 3, 4, 15]);
 }
@@ -2641,19 +2641,19 @@ fn test_get_many_mut_single_last() {
 #[test]
 fn test_get_many_mut_oob_nonempty() {
     let mut v = vec![1, 2, 3, 4, 5];
-    assert!(v.get_many_mut([5]).is_err());
+    assert!(v.get_many_mut(&[5]).is_err());
 }
 
 #[test]
 fn test_get_many_mut_oob_empty() {
     let mut v: Vec<i32> = vec![];
-    assert!(v.get_many_mut([0]).is_err());
+    assert!(v.get_many_mut(&[0]).is_err());
 }
 
 #[test]
 fn test_get_many_mut_duplicate() {
     let mut v = vec![1, 2, 3, 4, 5];
-    assert!(v.get_many_mut([1, 3, 3, 4]).is_err());
+    assert!(v.get_many_mut(&[1, 3, 3, 4]).is_err());
 }
 
 #[test]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 9fba657d116de..0e6443c676ac8 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -392,7 +392,6 @@
 #![feature(custom_test_frameworks)]
 #![feature(edition_panic)]
 #![feature(format_args_nl)]
-#![feature(get_many_mut)]
 #![feature(log_syntax)]
 #![feature(test)]
 #![feature(trace_macros)]