From c020367b820b982a3c0ac86cedc5be6ed732b2fe Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 14 Apr 2021 12:05:56 -0700 Subject: [PATCH] Document the edition behavior for array.into_iter() --- library/core/src/array/mod.rs | 8 +++++ library/std/src/primitive_docs.rs | 50 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index ddbdc6a4acf..d4e71f4ef75 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -164,6 +164,14 @@ impl IntoIterator for [T; N] { type Item = T; type IntoIter = IntoIter; + /// Creates a consuming iterator, that is, one that moves each value out of + /// the array (from start to end). The array cannot be used after calling + /// this unless `T` implements `Copy`, so the whole array is copied. + /// + /// Arrays have special behavior when calling `.into_iter()` prior to the + /// 2021 edition -- see the [array] Editions section for more information. + /// + /// [array]: prim@array fn into_iter(self) -> Self::IntoIter { IntoIter::new(self) } diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index ad4737ec2f6..65113bd71d9 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -549,6 +549,56 @@ mod prim_pointer {} /// move_away(roa); /// ``` /// +/// # Editions +/// +/// Prior to Rust 1.53, arrays did not implement `IntoIterator` by value, so the method call +/// `array.into_iter()` auto-referenced into a slice iterator. That behavior is preserved in the +/// 2015 and 2018 editions of Rust for compatability, ignoring `IntoIterator` by value. +/// +/// ```rust,edition2018 +/// # #![allow(array_into_iter)] // override our `deny(warnings)` +/// let array: [i32; 3] = [0; 3]; +/// +/// // This creates a slice iterator, producing references to each value. +/// for item in array.into_iter().enumerate() { +/// let (i, x): (usize, &i32) = item; +/// println!("array[{}] = {}", i, x); +/// } +/// +/// // The `array_into_iter` lint suggests this change for future compatibility: +/// for item in array.iter().enumerate() { +/// let (i, x): (usize, &i32) = item; +/// println!("array[{}] = {}", i, x); +/// } +/// +/// // You can explicitly iterate an array by value using +/// // `IntoIterator::into_iter` or `std::array::IntoIter::new`: +/// for item in IntoIterator::into_iter(array).enumerate() { +/// let (i, x): (usize, i32) = item; +/// println!("array[{}] = {}", i, x); +/// } +/// ``` +/// +/// Starting in the 2021 edition, `array.into_iter()` will use `IntoIterator` normally to iterate +/// by value, and `iter()` should be used to iterate by reference like previous editions. +/// +/// ```rust,edition2021,ignore +/// # // FIXME: ignored because 2021 testing is still unstable +/// let array: [i32; 3] = [0; 3]; +/// +/// // This iterates by reference: +/// for item in array.iter().enumerate() { +/// let (i, x): (usize, &i32) = item; +/// println!("array[{}] = {}", i, x); +/// } +/// +/// // This iterates by value: +/// for item in array.into_iter().enumerate() { +/// let (i, x): (usize, i32) = item; +/// println!("array[{}] = {}", i, x); +/// } +/// ``` +/// /// [slice]: prim@slice /// [`Debug`]: fmt::Debug /// [`Hash`]: hash::Hash