diff --git a/core/src/array/mod.rs b/core/src/array/mod.rs index 2569ce237077e..fdb707bf51d39 100644 --- a/core/src/array/mod.rs +++ b/core/src/array/mod.rs @@ -10,6 +10,7 @@ use crate::convert::Infallible; use crate::error::Error; use crate::fmt; use crate::hash::{self, Hash}; +use crate::intrinsics::transmute_unchecked; use crate::iter::UncheckedIterator; use crate::mem::{self, MaybeUninit}; use crate::ops::{ @@ -27,6 +28,41 @@ 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. +/// +/// The value will be used as the last element of the resulting array, so it +/// will be cloned N - 1 times. 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 = "none")] +pub fn repeat(val: T) -> [T; N] { + match N { + // SAFETY: we know N to be 0 at this point. + 0 => unsafe { transmute_unchecked::<[T; 0], [T; N]>([]) }, + // SAFETY: we know N to be 1 at this point. + 1 => unsafe { transmute_unchecked::<[T; 1], [T; N]>([val]) }, + _ => { + let mut array = MaybeUninit::uninit_array::(); + try_from_fn_erased(&mut array[..N - 1], NeverShortCircuit::wrap_mut_1(|_| val.clone())); + array[N - 1].write(val); + // SAFETY: all elements were initialized. + unsafe { MaybeUninit::array_assume_init(array) } + } + } +} + /// Creates an array of type [T; N], where each element `T` is the returned value from `cb` /// using that element's index. ///