From 3b8617b9b6718f04d412ffae52337053e79c3c6b Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Thu, 26 Nov 2020 23:22:36 +0100 Subject: [PATCH 1/5] Added [T; N]::zip() --- library/core/src/array/mod.rs | 28 ++++++++++++++++++++++++++++ library/core/tests/array.rs | 8 ++++++++ library/core/tests/lib.rs | 1 + 3 files changed, 37 insertions(+) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index a7cb1023229bb..02b771863e92b 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -463,6 +463,34 @@ impl [T; N] { unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) } } + /// 'Zips up' two arrays into a single array of pairs. + /// `zip()` returns a new array where every element is a tuple where the first element comes from the first array, and the second element comes from the second array. + /// In other words, it zips two arrays together, into a single one. + /// + /// # Examples + /// + /// ``` + /// #![feature(array_zip)] + /// let x = [1, 2, 3]; + /// let y = [4, 5, 6]; + /// let z = x.zip(y); + /// assert_eq!(z, [(1, 4), (2, 5), (3, 6)]); + /// ``` + #[unstable(feature = "array_zip", issue = "none")] + pub fn zip(self, rhs: [U; N]) -> [(T, U); N] { + use crate::mem::MaybeUninit; + + let mut dst = MaybeUninit::uninit_array::(); + for ((lhs, rhs), dst) in IntoIter::new(self).zip(IntoIter::new(rhs)).zip(&mut dst) { + dst.write((lhs, rhs)); + } + // FIXME: Convert to crate::mem::transmute once it works with generics. + // unsafe { crate::mem::transmute::<[MaybeUninit; N], [U; N]>(dst) } + // SAFETY: At this point we've properly initialized the whole array + // and we just need to cast it to the correct type. + unsafe { crate::mem::transmute_copy::<_, [(T, U); N]>(&dst) } + } + /// Returns a slice containing the entire array. Equivalent to `&s[..]`. #[unstable(feature = "array_methods", issue = "76118")] pub fn as_slice(&self) -> &[T] { diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 89c2a969c28bb..9005e3d8f43e3 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -317,6 +317,14 @@ fn array_map() { assert_eq!(b, [1, 2, 3]); } +#[test] +fn array_zip() { + let a = [1, 2, 3]; + let b = [4, 5, 6]; + let c = a.zip(b); + assert_eq!(c, [(1, 4), (2, 5), (3, 6)]); +} + // See note on above test for why `should_panic` is used. #[test] #[should_panic(expected = "test succeeded")] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 1efb3b7411898..2daf2650b5822 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -3,6 +3,7 @@ #![feature(array_from_ref)] #![feature(array_methods)] #![feature(array_map)] +#![feature(array_zip)] #![feature(array_windows)] #![feature(bool_to_option)] #![feature(bound_cloned)] From 2f35fb1e116d5da9e851c1a298390078ea7089ed Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Fri, 27 Nov 2020 11:46:49 +0100 Subject: [PATCH 2/5] Remove redundant tests --- library/core/tests/array.rs | 8 -------- library/core/tests/lib.rs | 1 - 2 files changed, 9 deletions(-) diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 9005e3d8f43e3..89c2a969c28bb 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -317,14 +317,6 @@ fn array_map() { assert_eq!(b, [1, 2, 3]); } -#[test] -fn array_zip() { - let a = [1, 2, 3]; - let b = [4, 5, 6]; - let c = a.zip(b); - assert_eq!(c, [(1, 4), (2, 5), (3, 6)]); -} - // See note on above test for why `should_panic` is used. #[test] #[should_panic(expected = "test succeeded")] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 2daf2650b5822..1efb3b7411898 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -3,7 +3,6 @@ #![feature(array_from_ref)] #![feature(array_methods)] #![feature(array_map)] -#![feature(array_zip)] #![feature(array_windows)] #![feature(bool_to_option)] #![feature(bound_cloned)] From be2c8f2d436d777cbdac73f6dd238ea135048ff5 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Wed, 16 Dec 2020 18:32:29 +0100 Subject: [PATCH 3/5] Update zip for better codegen, see discussion --- library/core/src/array/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 02b771863e92b..9de87922f54f2 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -481,8 +481,8 @@ impl [T; N] { use crate::mem::MaybeUninit; let mut dst = MaybeUninit::uninit_array::(); - for ((lhs, rhs), dst) in IntoIter::new(self).zip(IntoIter::new(rhs)).zip(&mut dst) { - dst.write((lhs, rhs)); + for (i, (lhs, rhs)) in IntoIter::new(self).zip(IntoIter::new(rhs)).enumerate() { + dst[i].write((lhs, rhs)); } // FIXME: Convert to crate::mem::transmute once it works with generics. // unsafe { crate::mem::transmute::<[MaybeUninit; N], [U; N]>(dst) } From baa5e47106cd3544f4eb06317eea1a174d6e2341 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Wed, 16 Dec 2020 21:12:10 +0100 Subject: [PATCH 4/5] Update doc comment Co-authored-by: Mara Bos --- library/core/src/array/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 9de87922f54f2..6791f0e744427 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -464,8 +464,11 @@ impl [T; N] { } /// 'Zips up' two arrays into a single array of pairs. - /// `zip()` returns a new array where every element is a tuple where the first element comes from the first array, and the second element comes from the second array. - /// In other words, it zips two arrays together, into a single one. + /// + /// `zip()` returns a new array where every element is a tuple where the + /// first element comes from the first array, and the second element comes + /// from the second array. In other words, it zips two arrays together, + /// into a single one. /// /// # Examples /// From 8b3725973a696f8dd77e17127863ec56512322cb Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Thu, 17 Dec 2020 00:27:21 +0100 Subject: [PATCH 5/5] Added reference to tracking issue --- library/core/src/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 6791f0e744427..71548bec7aaee 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -479,7 +479,7 @@ impl [T; N] { /// let z = x.zip(y); /// assert_eq!(z, [(1, 4), (2, 5), (3, 6)]); /// ``` - #[unstable(feature = "array_zip", issue = "none")] + #[unstable(feature = "array_zip", issue = "80094")] pub fn zip(self, rhs: [U; N]) -> [(T, U); N] { use crate::mem::MaybeUninit;