From 56a651ca15ac2d3f74259b8df8ac07bd80dbeaf8 Mon Sep 17 00:00:00 2001 From: kadmin Date: Thu, 6 Aug 2020 23:36:50 +0000 Subject: [PATCH] Add recommend changes to array Switch from indexing to zip, and also use `write` on `MaybeUninit`. Add array_map feature to core/src/lib Attempt to fix issue of no such feature Update w/ pickfire's review This changes a couple of names around, adds another small test of variable size, and hides the rustdoc #![feature(..)]. Fmt doctest Add suggestions from lcnr --- library/core/src/array/mod.rs | 31 ++++++++++++++++--------------- library/core/src/lib.rs | 1 + library/core/tests/array.rs | 4 ++++ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index f85f5efbb9a..16baef137cb 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -372,27 +372,28 @@ impl [T; N] { /// /// # Examples /// ``` - /// let x = [1,2,3]; + /// # #![feature(array_map)] + /// let x = [1, 2, 3]; /// let y = x.map(|v| v + 1); - /// assert_eq!(y, [2,3,4]); + /// assert_eq!(y, [2, 3, 4]); /// ``` #[unstable(feature = "array_map", issue = "77777")] - pub fn map(self, mut f: F) -> [S; N] + pub fn map(self, mut f: F) -> [U; N] where - F: FnMut(T) -> S, + F: FnMut(T) -> U, { use crate::mem::MaybeUninit; struct Guard { dst: *mut T, - curr_init: usize, + initialized: usize, } impl Drop for Guard { fn drop(&mut self) { - debug_assert!(self.curr_init <= N); + debug_assert!(self.initialized <= N); let initialized_part = - crate::ptr::slice_from_raw_parts_mut(self.dst, self.curr_init); + crate::ptr::slice_from_raw_parts_mut(self.dst, self.initialized); // SAFETY: this raw slice will contain only initialized objects // that's why, it is allowed to drop it. unsafe { @@ -401,16 +402,16 @@ impl [T; N] { } } let mut dst = MaybeUninit::uninit_array::(); - let mut guard: Guard = Guard { dst: &mut dst as *mut _ as *mut S, curr_init: 0 }; - for (i, e) in IntoIter::new(self).enumerate() { - dst[i] = MaybeUninit::new(f(e)); - guard.curr_init += 1; + let mut guard: Guard = Guard { dst: &mut dst as *mut _ as *mut U, initialized: 0 }; + for (src, dst) in IntoIter::new(self).zip(&mut dst) { + dst.write(f(src)); + guard.initialized += 1; } - // FIXME convert to crate::mem::transmute when works with generics - // unsafe { crate::mem::transmute::<[MaybeUninit; N], [S; N]>(dst) } + // FIXME: Convert to crate::mem::transmute once it works with generics. + // unsafe { crate::mem::transmute::<[MaybeUninit; N], [U; N]>(dst) } crate::mem::forget(guard); // SAFETY: At this point we've properly initialized the whole array - // and we just need to cast it to the correct type - unsafe { (&mut dst as *mut _ as *mut [S; N]).read() } + // and we just need to cast it to the correct type. + unsafe { (&mut dst as *mut _ as *mut [U; N]).read() } } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index fcf5454308b..763457d485d 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -145,6 +145,7 @@ #![feature(abi_unadjusted)] #![feature(adx_target_feature)] #![feature(maybe_uninit_slice)] +#![feature(maybe_uninit_extra)] #![feature(external_doc)] #![feature(associated_type_bounds)] #![feature(const_caller_location)] diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 5ae622c1182..d4a9b061d85 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -296,4 +296,8 @@ fn array_map() { let a = [1, 2, 3]; let b = a.map(|v| v + 1); assert_eq!(b, [2, 3, 4]); + + let a = [1u8, 2, 3]; + let b = a.map(|v| v as u64); + assert_eq!(b, [1, 2, 3]); }