about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-19 18:47:04 +0000
committerbors <bors@rust-lang.org>2024-06-19 18:47:04 +0000
commitd8a38b00024cd7156dea4ce8fd8ae113a2745e7f (patch)
tree65488475893e72510938de6224e4e34dbf88d946
parent5c8459f1eceba84dff8d622768dae556ea7c2495 (diff)
parent0aa3310a9ac22509f138566398c2e65a777f5967 (diff)
downloadrust-d8a38b00024cd7156dea4ce8fd8ae113a2745e7f.tar.gz
rust-d8a38b00024cd7156dea4ce8fd8ae113a2745e7f.zip
Auto merge of #119127 - joboet:array_repeat, r=scottmcm
Implement `array::repeat`

See rust-lang/libs-team#310.

I've decided to make the function use the input value as last element instead of cloning it to every position and dropping it, and to make this part of the API so that callers are not surprised by this behaviour.

TODO: open a tracking issue. I'll wait for the ACP to be accepted, first.

`@rustbot` label +T-libs-api +T-libs
r? libs
-rw-r--r--library/core/src/array/mod.rs29
-rw-r--r--library/core/src/iter/sources/repeat_n.rs4
-rw-r--r--tests/codegen/array-repeat.rs15
3 files changed, 46 insertions, 2 deletions
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 2569ce23707..3e4eadbb7c9 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -10,7 +10,7 @@ use crate::convert::Infallible;
 use crate::error::Error;
 use crate::fmt;
 use crate::hash::{self, Hash};
-use crate::iter::UncheckedIterator;
+use crate::iter::{repeat_n, UncheckedIterator};
 use crate::mem::{self, MaybeUninit};
 use crate::ops::{
     ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try,
@@ -27,6 +27,33 @@ pub(crate) use drain::drain_array_with;
 #[stable(feature = "array_value_iter", since = "1.51.0")]
 pub use iter::IntoIter;
 
+/// Creates an array of type `[T; N]` by repeatedly cloning a value.
+///
+/// This is the same as `[val; N]`, but it also works for types that do not
+/// implement [`Copy`].
+///
+/// The provided value will be used as an element of the resulting array and
+/// will be cloned N - 1 times to fill up the rest. If N is zero, the value
+/// will be dropped.
+///
+/// # Example
+///
+/// Creating muliple copies of a `String`:
+/// ```rust
+/// #![feature(array_repeat)]
+///
+/// use std::array;
+///
+/// let string = "Hello there!".to_string();
+/// let strings = array::repeat(string);
+/// assert_eq!(strings, ["Hello there!", "Hello there!"]);
+/// ```
+#[inline]
+#[unstable(feature = "array_repeat", issue = "126695")]
+pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
+    from_trusted_iterator(repeat_n(val, N))
+}
+
 /// Creates an array of type [T; N], where each element `T` is the returned value from `cb`
 /// using that element's index.
 ///
diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs
index 8224e4b12a0..8390dab8e54 100644
--- a/library/core/src/iter/sources/repeat_n.rs
+++ b/library/core/src/iter/sources/repeat_n.rs
@@ -1,4 +1,4 @@
-use crate::iter::{FusedIterator, TrustedLen};
+use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
 use crate::mem::ManuallyDrop;
 use crate::num::NonZero;
 
@@ -193,3 +193,5 @@ impl<A: Clone> FusedIterator for RepeatN<A> {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
 unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
+#[unstable(feature = "trusted_len_next_unchecked", issue = "37572")]
+impl<A: Clone> UncheckedIterator for RepeatN<A> {}
diff --git a/tests/codegen/array-repeat.rs b/tests/codegen/array-repeat.rs
new file mode 100644
index 00000000000..b6f3b2e83d3
--- /dev/null
+++ b/tests/codegen/array-repeat.rs
@@ -0,0 +1,15 @@
+//@ compile-flags: -O
+
+#![crate_type = "lib"]
+#![feature(array_repeat)]
+
+use std::array::repeat;
+
+// CHECK-LABEL: @byte_repeat
+#[no_mangle]
+fn byte_repeat(b: u8) -> [u8; 1024] {
+    // CHECK-NOT: alloca
+    // CHECK-NOT: store
+    // CHECK: memset
+    repeat(b)
+}