Skip to content

Commit 472230d

Browse files
Remove array_zip
`[T; N]::zip` is "eager" but most zips are mapped. This causes poor optimization in generated code. This is a fundamental design issue and "zip" is "prime real estate" in terms of function names, so let's free it up again.
1 parent 165cdda commit 472230d

File tree

3 files changed

+0
-45
lines changed

3 files changed

+0
-45
lines changed

library/core/src/array/mod.rs

-23
Original file line numberDiff line numberDiff line change
@@ -538,29 +538,6 @@ impl<T, const N: usize> [T; N] {
538538
drain_array_with(self, |iter| try_from_trusted_iterator(iter.map(f)))
539539
}
540540

541-
/// 'Zips up' two arrays into a single array of pairs.
542-
///
543-
/// `zip()` returns a new array where every element is a tuple where the
544-
/// first element comes from the first array, and the second element comes
545-
/// from the second array. In other words, it zips two arrays together,
546-
/// into a single one.
547-
///
548-
/// # Examples
549-
///
550-
/// ```
551-
/// #![feature(array_zip)]
552-
/// let x = [1, 2, 3];
553-
/// let y = [4, 5, 6];
554-
/// let z = x.zip(y);
555-
/// assert_eq!(z, [(1, 4), (2, 5), (3, 6)]);
556-
/// ```
557-
#[unstable(feature = "array_zip", issue = "80094")]
558-
pub fn zip<U>(self, rhs: [U; N]) -> [(T, U); N] {
559-
drain_array_with(self, |lhs| {
560-
drain_array_with(rhs, |rhs| from_trusted_iterator(crate::iter::zip(lhs, rhs)))
561-
})
562-
}
563-
564541
/// Returns a slice containing the entire array. Equivalent to `&s[..]`.
565542
#[stable(feature = "array_as_slice", since = "1.57.0")]
566543
#[rustc_const_stable(feature = "array_as_slice", since = "1.57.0")]

tests/codegen/array-map.rs

-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// ignore-debug (the extra assertions get in the way)
55

66
#![crate_type = "lib"]
7-
#![feature(array_zip)]
87

98
// CHECK-LABEL: @short_integer_map
109
#[no_mangle]
@@ -16,16 +15,6 @@ pub fn short_integer_map(x: [u32; 8]) -> [u32; 8] {
1615
x.map(|x| 2 * x + 1)
1716
}
1817

19-
// CHECK-LABEL: @short_integer_zip_map
20-
#[no_mangle]
21-
pub fn short_integer_zip_map(x: [u32; 8], y: [u32; 8]) -> [u32; 8] {
22-
// CHECK: %[[A:.+]] = load <8 x i32>
23-
// CHECK: %[[B:.+]] = load <8 x i32>
24-
// CHECK: sub <8 x i32> %[[B]], %[[A]]
25-
// CHECK: store <8 x i32>
26-
x.zip(y).map(|(x, y)| x - y)
27-
}
28-
2918
// This test is checking that LLVM can SRoA away a bunch of the overhead,
3019
// like fully moving the iterators to registers. Notably, previous implementations
3120
// of `map` ended up `alloca`ing the whole `array::IntoIterator`, meaning both a

tests/codegen/autovectorize-f32x4.rs

-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// compile-flags: -C opt-level=3 -Z merge-functions=disabled
22
// only-x86_64
33
#![crate_type = "lib"]
4-
#![feature(array_zip)]
54

65
// CHECK-LABEL: @auto_vectorize_direct
76
#[no_mangle]
@@ -31,13 +30,3 @@ pub fn auto_vectorize_loop(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
3130
}
3231
c
3332
}
34-
35-
// CHECK-LABEL: @auto_vectorize_array_zip_map
36-
#[no_mangle]
37-
pub fn auto_vectorize_array_zip_map(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
38-
// CHECK: load <4 x float>
39-
// CHECK: load <4 x float>
40-
// CHECK: fadd <4 x float>
41-
// CHECK: store <4 x float>
42-
a.zip(b).map(|(a, b)| a + b)
43-
}

0 commit comments

Comments
 (0)