From 538a0963ff4a55da47fcf2a1e14c62edab5af48d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 4 Mar 2019 15:12:45 -0800 Subject: [PATCH 1/4] Add as_slice() to slice::IterMut and vec::Drain In bluss/indexmap#88, we found that there was no easy way to implement `Debug` for our `IterMut` and `Drain` iterators. Those are built on `slice::IterMut` and `vec::Drain`, which implement `Debug` themselves, but have no other way to access their data. With a new `as_slice()` method, we can read the data and customize its presentation. --- src/liballoc/vec.rs | 19 +++++++++++++++++++ src/libcore/slice/mod.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 947ce354ae7..7c3cab77bfb 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2468,6 +2468,25 @@ impl fmt::Debug for Drain<'_, T> { } } +impl<'a, T> Drain<'a, T> { + /// Returns the remaining items of this iterator as a slice. + /// + /// # Examples + /// + /// ``` + /// # #![feature(vec_drain_as_slice)] + /// let mut vec = vec!['a', 'b', 'c']; + /// let mut drain = vec.drain(..); + /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']); + /// let _ = drain.next().unwrap(); + /// assert_eq!(drain.as_slice(), &['b', 'c']); + /// ``` + #[unstable(feature = "vec_drain_as_slice", reason = "recently added", issue = "0")] + pub fn as_slice(&self) -> &[T] { + self.iter.as_slice() + } +} + #[stable(feature = "drain", since = "1.6.0")] unsafe impl Sync for Drain<'_, T> {} #[stable(feature = "drain", since = "1.6.0")] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 2063f8ffaf6..b48101c23da 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3288,6 +3288,38 @@ impl<'a, T> IterMut<'a, T> { pub fn into_slice(self) -> &'a mut [T] { unsafe { from_raw_parts_mut(self.ptr, len!(self)) } } + + /// Views the underlying data as a subslice of the original data. + /// + /// To avoid creating `&mut` references that alias, this has a + /// borrowed lifetime from the iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # #![feature(slice_iter_mut_as_slice)] + /// // First, we declare a type which has `iter_mut` method to get the `IterMut` + /// // struct (&[usize here]): + /// let mut slice = &mut [1, 2, 3]; + /// + /// // Then, we get the iterator: + /// let mut iter = slice.iter_mut(); + /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]": + /// println!("{:?}", iter.as_slice()); + /// assert_eq!(iter.as_slice(), &[1, 2, 3]); + /// + /// // Next, we move to the second element of the slice: + /// iter.next(); + /// // Now `as_slice` returns "[2, 3]": + /// println!("{:?}", iter.as_slice()); + /// assert_eq!(iter.as_slice(), &[2, 3]); + /// ``` + #[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "0")] + pub fn as_slice(&self) -> &[T] { + self.make_slice() + } } iterator!{struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}} From 5384a11fcaa71d74d93f7e4ea4a2662ae28698fe Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 5 Mar 2019 16:17:50 -0800 Subject: [PATCH 2/4] Apply suggestions from code review Co-Authored-By: cuviper --- src/libcore/slice/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index b48101c23da..4bccd44f503 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3291,8 +3291,8 @@ impl<'a, T> IterMut<'a, T> { /// Views the underlying data as a subslice of the original data. /// - /// To avoid creating `&mut` references that alias, this has a - /// borrowed lifetime from the iterator. + /// To avoid creating `&mut [T]` references that alias, the returned slice + /// borrows its lifetime from the iterator the method is applied on. /// /// # Examples /// @@ -3302,11 +3302,11 @@ impl<'a, T> IterMut<'a, T> { /// # #![feature(slice_iter_mut_as_slice)] /// // First, we declare a type which has `iter_mut` method to get the `IterMut` /// // struct (&[usize here]): - /// let mut slice = &mut [1, 2, 3]; + /// let mut slice: &mut [usize] = &mut [1, 2, 3]; /// /// // Then, we get the iterator: /// let mut iter = slice.iter_mut(); - /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]": + /// // So if we print what the `as_slice` method returns here, we have "[1, 2, 3]": /// println!("{:?}", iter.as_slice()); /// assert_eq!(iter.as_slice(), &[1, 2, 3]); /// From 51e0d1c2990619ed55e0a387ae4fab71992069df Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 5 Mar 2019 16:20:50 -0800 Subject: [PATCH 3/4] Clean up the example on slice::IterMut::as_slice() --- src/libcore/slice/mod.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 4bccd44f503..5af6b9e8fe6 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3300,20 +3300,16 @@ impl<'a, T> IterMut<'a, T> { /// /// ``` /// # #![feature(slice_iter_mut_as_slice)] - /// // First, we declare a type which has `iter_mut` method to get the `IterMut` - /// // struct (&[usize here]): /// let mut slice: &mut [usize] = &mut [1, 2, 3]; /// - /// // Then, we get the iterator: + /// // First, we get the iterator: /// let mut iter = slice.iter_mut(); - /// // So if we print what the `as_slice` method returns here, we have "[1, 2, 3]": - /// println!("{:?}", iter.as_slice()); + /// // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]": /// assert_eq!(iter.as_slice(), &[1, 2, 3]); /// /// // Next, we move to the second element of the slice: /// iter.next(); /// // Now `as_slice` returns "[2, 3]": - /// println!("{:?}", iter.as_slice()); /// assert_eq!(iter.as_slice(), &[2, 3]); /// ``` #[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "0")] From e478cadbbe51e335b7248018141877b88770fe68 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 5 Mar 2019 16:28:32 -0800 Subject: [PATCH 4/4] Add a tracking issue for new as_slice methods --- src/liballoc/vec.rs | 2 +- src/libcore/slice/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 7c3cab77bfb..adcd3d84f48 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2481,7 +2481,7 @@ impl<'a, T> Drain<'a, T> { /// let _ = drain.next().unwrap(); /// assert_eq!(drain.as_slice(), &['b', 'c']); /// ``` - #[unstable(feature = "vec_drain_as_slice", reason = "recently added", issue = "0")] + #[unstable(feature = "vec_drain_as_slice", reason = "recently added", issue = "58957")] pub fn as_slice(&self) -> &[T] { self.iter.as_slice() } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 5af6b9e8fe6..b3594f8a385 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3312,7 +3312,7 @@ impl<'a, T> IterMut<'a, T> { /// // Now `as_slice` returns "[2, 3]": /// assert_eq!(iter.as_slice(), &[2, 3]); /// ``` - #[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "0")] + #[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "58957")] pub fn as_slice(&self) -> &[T] { self.make_slice() }