From 967c0ad5879f95c3663a1a0c7f02b2038f7eadb9 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Wed, 19 Jan 2022 16:44:13 +0100 Subject: [PATCH 1/2] Implement `IterMut::as_mut_slice` --- library/core/src/slice/iter.rs | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index ad1d6b8b846..2821109cd89 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -304,6 +304,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")] @@ -313,6 +354,13 @@ impl AsRef<[T]> for IterMut<'_, T> { } } +// #[stable(feature = "slice_iter_mut_as_mut_slice", since = "FIXME")] +// impl 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 From c867529461427bfb38e5a17461495b6a451ee374 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 20 Jun 2022 10:00:55 +0200 Subject: [PATCH 2/2] Show #![feature] in example. --- library/core/src/slice/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 2821109cd89..7f9f3ab2708 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -315,7 +315,7 @@ impl<'a, T> IterMut<'a, T> { /// Basic usage: /// /// ``` - /// # #![feature(slice_iter_mut_as_mut_slice)] + /// #![feature(slice_iter_mut_as_mut_slice)] /// /// let mut slice: &mut [usize] = &mut [1, 2, 3]; ///