about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-06-20 14:56:33 +0200
committerGitHub <noreply@github.com>2022-06-20 14:56:33 +0200
commitfd9ca0c25ec90f6ed156e6f0e950763ca5171f8a (patch)
tree3deb4bb4d277c39d6ed4a1a5d2b2677ba78a9804
parent4104596251818f4f588051c7a8172ca9f5a195bf (diff)
parentc867529461427bfb38e5a17461495b6a451ee374 (diff)
downloadrust-fd9ca0c25ec90f6ed156e6f0e950763ca5171f8a.tar.gz
rust-fd9ca0c25ec90f6ed156e6f0e950763ca5171f8a.zip
Rollup merge of #93080 - SkiFire13:itermut-as_mut_slice, r=m-ou-se
Implement `core::slice::IterMut::as_mut_slice` and `impl<T> AsMut<[T]> for IterMut<'_, T>`

As per [the zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/.60std.3A.3Aslice.3A.3AIterMut.3A.3Aas_mut_slice.60), the `AsMut` impl has been commented out, with a comment near the `#[unstable(...)]` to uncomment it when `as_mut_slice` gets stabilized.
-rw-r--r--library/core/src/slice/iter.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 772a9698d84..35d00b9dda6 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -306,6 +306,47 @@ impl<'a, T> IterMut<'a, T> {
     pub fn as_slice(&self) -> &[T] {
         self.make_slice()
     }
+
+    /// Views the underlying data as a mutable subslice of the original data.
+    ///
+    /// To avoid creating `&mut [T]` references that alias, the returned slice
+    /// borrows its lifetime from the iterator the method is applied on.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(slice_iter_mut_as_mut_slice)]
+    ///
+    /// let mut slice: &mut [usize] = &mut [1, 2, 3];
+    ///
+    /// // First, we get the iterator:
+    /// let mut iter = slice.iter_mut();
+    /// // Then, we get a mutable slice from it:
+    /// let mut_slice = iter.as_mut_slice();
+    /// // So if we check what the `as_mut_slice` method returned, we have "[1, 2, 3]":
+    /// assert_eq!(mut_slice, &mut [1, 2, 3]);
+    ///
+    /// // We can use it to mutate the slice:
+    /// mut_slice[0] = 4;
+    /// mut_slice[2] = 5;
+    ///
+    /// // Next, we can move to the second element of the slice, checking that
+    /// // it yields the value we just wrote:
+    /// assert_eq!(iter.next(), Some(&mut 4));
+    /// // Now `as_mut_slice` returns "[2, 5]":
+    /// assert_eq!(iter.as_mut_slice(), &mut [2, 5]);
+    /// ```
+    #[must_use]
+    // FIXME: Uncomment the `AsMut<[T]>` impl when this gets stabilized.
+    #[unstable(feature = "slice_iter_mut_as_mut_slice", issue = "93079")]
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        // SAFETY: the iterator was created from a mutable slice with pointer
+        // `self.ptr` and length `len!(self)`. This guarantees that all the prerequisites
+        // for `from_raw_parts_mut` are fulfilled.
+        unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
+    }
 }
 
 #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
@@ -315,6 +356,13 @@ impl<T> AsRef<[T]> for IterMut<'_, T> {
     }
 }
 
+// #[stable(feature = "slice_iter_mut_as_mut_slice", since = "FIXME")]
+// impl<T> AsMut<[T]> for IterMut<'_, T> {
+//     fn as_mut(&mut self) -> &mut [T] {
+//         self.as_mut_slice()
+//     }
+// }
+
 iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}
 
 /// An internal abstraction over the splitting iterators, so that