Repository: rust-lang/rust
File: library/core/src/array/mod.rs (Rust)

Code before:
    /// # let f = |x: i32| x + 1;
    /// for x in my_array.into_iter().map(f) {
    ///     // ...
    /// }
    /// ```
    ///
    /// so that the elements are mapped-then-processed one at a time instead.
    ///
    ///
    /// # Examples
    ///
    /// ```
    /// let x = [1, 2, 3];
    /// let y = x.map(|v| v + 1);
    /// assert_eq!(y, [2, 3, 4]);
    ///
    /// let x = [1, 2, 3];
    /// let mut temp = 0;
    /// let y = x.map(|v| { temp += 1; v * temp });
    /// assert_eq!(y, [1, 4, 9]);
    ///
    /// let x = ["Ferris", "Bueller's", "Day", "Off"];
    /// let y = x.map(|v| v.len());
    /// assert_eq!(y, [6, 9, 3, 3]);
    /// ```
    #[stable(feature = "array_map", since = "1.55.0")]
    pub fn map<F, U>(self, f: F) -> [U; N]
    where
        F: FnMut(T) -> U,
    {
        self.try_map(NeverShortCircuit::wrap_mut_1(f)).0
    }

    /// A fallible function `f` applied to each element on array `self` in order to
    /// return an array the same size as `self` or the first error encountered.
    ///
    /// The return type of this function depends on the return type of the closure.
    /// If you return `Result<T, E>` from the closure, you'll get a `Result<[T; N], E>`.
    /// If you return `Option<T>` from the closure, you'll get an `Option<[T; N]>`.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(array_try_map)]
    ///
    /// let a = ["1", "2", "3"];
    /// let b = a.try_map(|v| v.parse::<u32>()).unwrap().map(|v| v + 1);
    /// assert_eq!(b, [2, 3, 4]);
    ///
    /// let a = ["1", "2a", "3"];
    /// let b = a.try_map(|v| v.parse::<u32>());

Review comment (suggestion):
We shouldn't be talking about iterator evaluation order. E.g. `next_chunk` impls may evaluate like array.map and so any iterator method that uses chunking internally might also use that order.

Code after:
    {$n:expr,} => {
        #[stable(since = "1.4.0", feature = "array_default")]
        impl<T> Default for [T; $n] {
            fn default() -> [T; $n] { [] }
        }
    };
}

array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}

impl<T, const N: usize> [T; N] {
    /// Returns an array of the same size as `self`, with function `f` applied to each element
    /// in order.
    ///
    /// If you don't necessarily need a new fixed-size array, consider using
    /// [`Iterator::map`] instead.
    ///
    ///
    /// # Note on performance and stack usage
    ///
    /// Note that this method is *eager*.  It evaluates `f` all `N` times before
    /// returning the new array.
    ///
    /// That means that `arr.map(f).map(g)` is, in general, *not* equivalent to
    /// `array.map(|x| g(f(x)))`, as the former calls `f` 4 times then `g` 4 times,
    /// whereas the latter interleaves the calls (`fgfgfgfg`).
    ///
    /// A consequence of this is that it can have fairly-high stack usage, especially
    /// in debug mode or for long arrays.  The backend may be able to optimize it
    /// away, but especially for complicated mappings it might not be able to.
    ///
    /// If you're doing a one-step `map` and really want an array as the result,
    /// then absolutely use this method.  Its implementation uses a bunch of tricks
    /// to help the optimizer handle it well.  Particularly for simple arrays,
    /// like `[u8; 3]` or `[f32; 4]`, there's nothing to be concerned about.
    ///
    /// However, if you don't actually need an *array* of the results specifically,
    /// just to process them, then you likely want [`Iterator::map`] instead.
    ///
    /// For example, rather than doing an array-to-array map of all the elements
    /// in the array up-front and only iterating after that completes,
    ///
    /// ```
    /// # let my_array = [1, 2, 3];
    /// # let f = |x: i32| x + 1;
    /// for x in my_array.map(f) {
    ///     // ...
    /// }
    /// ```
    ///
    /// It's often better to use an iterator along the lines of