From 1abc85356209580bba5688ea1dadeb9fa8a90719 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 22 Dec 2024 01:57:28 +0300 Subject: [PATCH] Stabilize `get_many_mut` as `get_disjoint_mut` * Renames the methods: * `get_many_mut` -> `get_disjoint_mut` * `get_many_unchecked_mut` -> `get_disjoint_unchecked_mut` * Does not rename the feature flag: `get_many_mut` * Marks the feature as stable * Renames some helper stuff: * `GetManyMutError` -> `GetDisjointMutError` * `GetManyMutIndex` -> `GetDisjointMutIndex` * `get_many_mut_helpers` -> `get_disjoint_mut_helpers` * `get_many_check_valid` -> `get_disjoint_check_valid` This only touches slice methods. HashMap's methods and feature gates are not renamed here (nor are they stabilized). --- library/alloc/src/slice.rs | 4 +- library/core/src/error.rs | 4 +- library/core/src/slice/mod.rs | 115 +++++++++++++++---------------- library/coretests/tests/lib.rs | 1 - library/coretests/tests/slice.rs | 76 ++++++++++---------- library/std/src/lib.rs | 1 - 6 files changed, 98 insertions(+), 103 deletions(-) diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index edc8d99f2f990..891db4f5ca60b 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -27,8 +27,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; -#[unstable(feature = "get_many_mut", issue = "104642")] -pub use core::slice::GetManyMutError; +#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] +pub use core::slice::GetDisjointMutError; #[stable(feature = "slice_get_slice", since = "1.28.0")] pub use core::slice::SliceIndex; #[cfg(not(no_global_oom_handling))] diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 9dbea57fa1f86..33cf2af30b954 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -1075,5 +1075,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")] -impl Error for crate::slice::GetManyMutError {} +#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] +impl Error for crate::slice::GetDisjointMutError {} diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 1993a7491e108..555a786a7ed6e 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4530,7 +4530,7 @@ impl [T] { /// to single elements, while if passed an array of ranges it gives back an array of /// mutable references to slices. /// - /// For a safe alternative see [`get_many_mut`]. + /// For a safe alternative see [`get_disjoint_mut`]. /// /// # Safety /// @@ -4540,19 +4540,17 @@ impl [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_disjoint_unchecked_mut([0, 2]); /// *a *= 10; /// *b *= 100; /// } /// assert_eq!(x, &[10, 2, 400]); /// /// unsafe { - /// let [a, b] = x.get_many_unchecked_mut([0..1, 1..3]); + /// let [a, b] = x.get_disjoint_unchecked_mut([0..1, 1..3]); /// a[0] = 8; /// b[0] = 88; /// b[1] = 888; @@ -4560,7 +4558,7 @@ impl [T] { /// assert_eq!(x, &[8, 88, 888]); /// /// unsafe { - /// let [a, b] = x.get_many_unchecked_mut([1..=2, 0..=0]); + /// let [a, b] = x.get_disjoint_unchecked_mut([1..=2, 0..=0]); /// a[0] = 11; /// a[1] = 111; /// b[0] = 1; @@ -4568,16 +4566,16 @@ impl [T] { /// assert_eq!(x, &[1, 11, 111]); /// ``` /// - /// [`get_many_mut`]: slice::get_many_mut + /// [`get_disjoint_mut`]: slice::get_disjoint_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( + pub unsafe fn get_disjoint_unchecked_mut( &mut self, indices: [I; N], ) -> [&mut I::Output; N] where - I: GetManyMutIndex + SliceIndex, + I: GetDisjointMutIndex + SliceIndex, { // NB: This implementation is written as it is because any variation of // `indices.map(|i| self.get_unchecked_mut(i))` would make miri unhappy, @@ -4616,42 +4614,40 @@ impl [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_disjoint_mut([0, 2]) { /// *a = 413; /// *b = 612; /// } /// assert_eq!(v, &[413, 2, 612]); /// - /// if let Ok([a, b]) = v.get_many_mut([0..1, 1..3]) { + /// if let Ok([a, b]) = v.get_disjoint_mut([0..1, 1..3]) { /// a[0] = 8; /// b[0] = 88; /// b[1] = 888; /// } /// assert_eq!(v, &[8, 88, 888]); /// - /// if let Ok([a, b]) = v.get_many_mut([1..=2, 0..=0]) { + /// if let Ok([a, b]) = v.get_disjoint_mut([1..=2, 0..=0]) { /// a[0] = 11; /// a[1] = 111; /// b[0] = 1; /// } /// assert_eq!(v, &[1, 11, 111]); /// ``` - #[unstable(feature = "get_many_mut", issue = "104642")] + #[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] #[inline] - pub fn get_many_mut( + pub fn get_disjoint_mut( &mut self, indices: [I; N], - ) -> Result<[&mut I::Output; N], GetManyMutError> + ) -> Result<[&mut I::Output; N], GetDisjointMutError> where - I: GetManyMutIndex + SliceIndex, + I: GetDisjointMutIndex + SliceIndex, { - get_many_check_valid(&indices, self.len())?; - // SAFETY: The `get_many_check_valid()` call checked that all indices + get_disjoint_check_valid(&indices, self.len())?; + // SAFETY: The `get_disjoint_check_valid()` call checked that all indices // are disjunct and in bounds. - unsafe { Ok(self.get_many_unchecked_mut(indices)) } + unsafe { Ok(self.get_disjoint_unchecked_mut(indices)) } } /// Returns the index that an element reference points to. @@ -4993,26 +4989,26 @@ impl SlicePattern for [T; N] { /// This will do `binomial(N + 1, 2) = N * (N + 1) / 2 = 0, 1, 3, 6, 10, ..` /// comparison operations. #[inline] -fn get_many_check_valid( +fn get_disjoint_check_valid( indices: &[I; N], len: usize, -) -> Result<(), GetManyMutError> { +) -> Result<(), GetDisjointMutError> { // NB: The optimizer should inline the loops into a sequence // of instructions without additional branching. for (i, idx) in indices.iter().enumerate() { if !idx.is_in_bounds(len) { - return Err(GetManyMutError::IndexOutOfBounds); + return Err(GetDisjointMutError::IndexOutOfBounds); } for idx2 in &indices[..i] { if idx.is_overlapping(idx2) { - return Err(GetManyMutError::OverlappingIndices); + return Err(GetDisjointMutError::OverlappingIndices); } } } Ok(()) } -/// The error type returned by [`get_many_mut`][`slice::get_many_mut`]. +/// The error type returned by [`get_disjoint_mut`][`slice::get_disjoint_mut`]. /// /// It indicates one of two possible errors: /// - An index is out-of-bounds. @@ -5022,74 +5018,75 @@ fn get_many_check_valid( /// # Examples /// /// ``` -/// #![feature(get_many_mut)] -/// use std::slice::GetManyMutError; +/// use std::slice::GetDisjointMutError; /// /// let v = &mut [1, 2, 3]; -/// assert_eq!(v.get_many_mut([0, 999]), Err(GetManyMutError::IndexOutOfBounds)); -/// assert_eq!(v.get_many_mut([1, 1]), Err(GetManyMutError::OverlappingIndices)); +/// assert_eq!(v.get_disjoint_mut([0, 999]), Err(GetDisjointMutError::IndexOutOfBounds)); +/// assert_eq!(v.get_disjoint_mut([1, 1]), Err(GetDisjointMutError::OverlappingIndices)); /// ``` -#[unstable(feature = "get_many_mut", issue = "104642")] +#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug, Clone, PartialEq, Eq)] -pub enum GetManyMutError { +pub enum GetDisjointMutError { /// An index provided was out-of-bounds for the slice. IndexOutOfBounds, /// Two indices provided were overlapping. OverlappingIndices, } -#[unstable(feature = "get_many_mut", issue = "104642")] -impl fmt::Display for GetManyMutError { +#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] +impl fmt::Display for GetDisjointMutError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let msg = match self { - GetManyMutError::IndexOutOfBounds => "an index is out of bounds", - GetManyMutError::OverlappingIndices => "there were overlapping indices", + GetDisjointMutError::IndexOutOfBounds => "an index is out of bounds", + GetDisjointMutError::OverlappingIndices => "there were overlapping indices", }; fmt::Display::fmt(msg, f) } } -mod private_get_many_mut_index { +mod private_get_disjoint_mut_index { use super::{Range, RangeInclusive, range}; - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] pub trait Sealed {} - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] impl Sealed for usize {} - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] impl Sealed for Range {} - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] impl Sealed for RangeInclusive {} - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] impl Sealed for range::Range {} - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] impl Sealed for range::RangeInclusive {} } -/// A helper trait for `<[T]>::get_many_mut()`. +/// A helper trait for `<[T]>::get_disjoint_mut()`. /// /// # Safety /// /// If `is_in_bounds()` returns `true` and `is_overlapping()` returns `false`, /// it must be safe to index the slice with the indices. -#[unstable(feature = "get_many_mut_helpers", issue = "none")] -pub unsafe trait GetManyMutIndex: Clone + private_get_many_mut_index::Sealed { +#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] +pub unsafe trait GetDisjointMutIndex: + Clone + private_get_disjoint_mut_index::Sealed +{ /// Returns `true` if `self` is in bounds for `len` slice elements. - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] fn is_in_bounds(&self, len: usize) -> bool; /// Returns `true` if `self` overlaps with `other`. /// /// Note that we don't consider zero-length ranges to overlap at the beginning or the end, /// but do consider them to overlap in the middle. - #[unstable(feature = "get_many_mut_helpers", issue = "none")] + #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] fn is_overlapping(&self, other: &Self) -> bool; } -#[unstable(feature = "get_many_mut_helpers", issue = "none")] +#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] // SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. -unsafe impl GetManyMutIndex for usize { +unsafe impl GetDisjointMutIndex for usize { #[inline] fn is_in_bounds(&self, len: usize) -> bool { *self < len @@ -5101,9 +5098,9 @@ unsafe impl GetManyMutIndex for usize { } } -#[unstable(feature = "get_many_mut_helpers", issue = "none")] +#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] // SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. -unsafe impl GetManyMutIndex for Range { +unsafe impl GetDisjointMutIndex for Range { #[inline] fn is_in_bounds(&self, len: usize) -> bool { (self.start <= self.end) & (self.end <= len) @@ -5115,9 +5112,9 @@ unsafe impl GetManyMutIndex for Range { } } -#[unstable(feature = "get_many_mut_helpers", issue = "none")] +#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] // SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. -unsafe impl GetManyMutIndex for RangeInclusive { +unsafe impl GetDisjointMutIndex for RangeInclusive { #[inline] fn is_in_bounds(&self, len: usize) -> bool { (self.start <= self.end) & (self.end < len) @@ -5129,9 +5126,9 @@ unsafe impl GetManyMutIndex for RangeInclusive { } } -#[unstable(feature = "get_many_mut_helpers", issue = "none")] +#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] // SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. -unsafe impl GetManyMutIndex for range::Range { +unsafe impl GetDisjointMutIndex for range::Range { #[inline] fn is_in_bounds(&self, len: usize) -> bool { Range::from(*self).is_in_bounds(len) @@ -5143,9 +5140,9 @@ unsafe impl GetManyMutIndex for range::Range { } } -#[unstable(feature = "get_many_mut_helpers", issue = "none")] +#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")] // SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly. -unsafe impl GetManyMutIndex for range::RangeInclusive { +unsafe impl GetDisjointMutIndex for range::RangeInclusive { #[inline] fn is_in_bounds(&self, len: usize) -> bool { RangeInclusive::from(*self).is_in_bounds(len) diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 0607d508a48e5..5494e487d085f 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -36,7 +36,6 @@ #![feature(freeze)] #![feature(future_join)] #![feature(generic_assert_internals)] -#![feature(get_many_mut)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] #![feature(inline_const_pat)] diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs index 510dd4967c961..491a50c3aa836 100644 --- a/library/coretests/tests/slice.rs +++ b/library/coretests/tests/slice.rs @@ -2548,14 +2548,14 @@ fn test_flatten_mut_size_overflow() { } #[test] -fn test_get_many_mut_normal_2() { +fn test_get_disjoint_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_disjoint_mut([3, 0]).unwrap(); *a += 10; *b += 100; assert_eq!(v, vec![101, 2, 3, 14, 5]); - let [a, b] = v.get_many_mut([0..=1, 2..=2]).unwrap(); + let [a, b] = v.get_disjoint_mut([0..=1, 2..=2]).unwrap(); assert_eq!(a, &mut [101, 2][..]); assert_eq!(b, &mut [3][..]); a[0] += 10; @@ -2565,15 +2565,15 @@ fn test_get_many_mut_normal_2() { } #[test] -fn test_get_many_mut_normal_3() { +fn test_get_disjoint_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_disjoint_mut([0, 4, 2]).unwrap(); *a += 10; *b += 100; *c += 1000; assert_eq!(v, vec![11, 2, 1003, 4, 105]); - let [a, b, c] = v.get_many_mut([0..1, 4..5, 1..4]).unwrap(); + let [a, b, c] = v.get_disjoint_mut([0..1, 4..5, 1..4]).unwrap(); assert_eq!(a, &mut [11][..]); assert_eq!(b, &mut [105][..]); assert_eq!(c, &mut [2, 1003, 4][..]); @@ -2584,80 +2584,80 @@ fn test_get_many_mut_normal_3() { } #[test] -fn test_get_many_mut_empty() { +fn test_get_disjoint_mut_empty() { let mut v = vec![1, 2, 3, 4, 5]; - let [] = v.get_many_mut::([]).unwrap(); - let [] = v.get_many_mut::, 0>([]).unwrap(); - let [] = v.get_many_mut::, 0>([]).unwrap(); + let [] = v.get_disjoint_mut::([]).unwrap(); + let [] = v.get_disjoint_mut::, 0>([]).unwrap(); + let [] = v.get_disjoint_mut::, 0>([]).unwrap(); assert_eq!(v, vec![1, 2, 3, 4, 5]); } #[test] -fn test_get_many_mut_single_first() { +fn test_get_disjoint_mut_single_first() { let mut v = vec![1, 2, 3, 4, 5]; - let [a] = v.get_many_mut([0]).unwrap(); + let [a] = v.get_disjoint_mut([0]).unwrap(); *a += 10; assert_eq!(v, vec![11, 2, 3, 4, 5]); } #[test] -fn test_get_many_mut_single_last() { +fn test_get_disjoint_mut_single_last() { let mut v = vec![1, 2, 3, 4, 5]; - let [a] = v.get_many_mut([4]).unwrap(); + let [a] = v.get_disjoint_mut([4]).unwrap(); *a += 10; assert_eq!(v, vec![1, 2, 3, 4, 15]); } #[test] -fn test_get_many_mut_oob_nonempty() { +fn test_get_disjoint_mut_oob_nonempty() { let mut v = vec![1, 2, 3, 4, 5]; - assert!(v.get_many_mut([5]).is_err()); + assert!(v.get_disjoint_mut([5]).is_err()); } #[test] -fn test_get_many_mut_oob_empty() { +fn test_get_disjoint_mut_oob_empty() { let mut v: Vec = vec![]; - assert!(v.get_many_mut([0]).is_err()); + assert!(v.get_disjoint_mut([0]).is_err()); } #[test] -fn test_get_many_mut_duplicate() { +fn test_get_disjoint_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_disjoint_mut([1, 3, 3, 4]).is_err()); } #[test] -fn test_get_many_mut_range_oob() { +fn test_get_disjoint_mut_range_oob() { let mut v = vec![1, 2, 3, 4, 5]; - assert!(v.get_many_mut([0..6]).is_err()); - assert!(v.get_many_mut([5..6]).is_err()); - assert!(v.get_many_mut([6..6]).is_err()); - assert!(v.get_many_mut([0..=5]).is_err()); - assert!(v.get_many_mut([0..=6]).is_err()); - assert!(v.get_many_mut([5..=5]).is_err()); + assert!(v.get_disjoint_mut([0..6]).is_err()); + assert!(v.get_disjoint_mut([5..6]).is_err()); + assert!(v.get_disjoint_mut([6..6]).is_err()); + assert!(v.get_disjoint_mut([0..=5]).is_err()); + assert!(v.get_disjoint_mut([0..=6]).is_err()); + assert!(v.get_disjoint_mut([5..=5]).is_err()); } #[test] -fn test_get_many_mut_range_overlapping() { +fn test_get_disjoint_mut_range_overlapping() { let mut v = vec![1, 2, 3, 4, 5]; - assert!(v.get_many_mut([0..1, 0..2]).is_err()); - assert!(v.get_many_mut([0..1, 1..2, 0..1]).is_err()); - assert!(v.get_many_mut([0..3, 1..1]).is_err()); - assert!(v.get_many_mut([0..3, 1..2]).is_err()); - assert!(v.get_many_mut([0..=0, 2..=2, 0..=1]).is_err()); - assert!(v.get_many_mut([0..=4, 0..=0]).is_err()); - assert!(v.get_many_mut([4..=4, 0..=0, 3..=4]).is_err()); + assert!(v.get_disjoint_mut([0..1, 0..2]).is_err()); + assert!(v.get_disjoint_mut([0..1, 1..2, 0..1]).is_err()); + assert!(v.get_disjoint_mut([0..3, 1..1]).is_err()); + assert!(v.get_disjoint_mut([0..3, 1..2]).is_err()); + assert!(v.get_disjoint_mut([0..=0, 2..=2, 0..=1]).is_err()); + assert!(v.get_disjoint_mut([0..=4, 0..=0]).is_err()); + assert!(v.get_disjoint_mut([4..=4, 0..=0, 3..=4]).is_err()); } #[test] -fn test_get_many_mut_range_empty_at_edge() { +fn test_get_disjoint_mut_range_empty_at_edge() { let mut v = vec![1, 2, 3, 4, 5]; assert_eq!( - v.get_many_mut([0..0, 0..5, 5..5]), + v.get_disjoint_mut([0..0, 0..5, 5..5]), Ok([&mut [][..], &mut [1, 2, 3, 4, 5], &mut []]), ); assert_eq!( - v.get_many_mut([0..0, 0..1, 1..1, 1..2, 2..2, 2..3, 3..3, 3..4, 4..4, 4..5, 5..5]), + v.get_disjoint_mut([0..0, 0..1, 1..1, 1..2, 2..2, 2..3, 3..3, 3..4, 4..4, 4..5, 5..5]), Ok([ &mut [][..], &mut [1], diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index acb3a0578e505..456dcba3ba9a3 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -401,7 +401,6 @@ #![feature(custom_test_frameworks)] #![feature(edition_panic)] #![feature(format_args_nl)] -#![feature(get_many_mut)] #![feature(log_syntax)] #![feature(test)] #![feature(trace_macros)]