Auto merge of #84147 - cuviper:array-method-dispatch, r=nikomatsakis,m-ou-se

Cautiously add IntoIterator for arrays by value

Add the attribute described in #84133, `#[rustc_skip_array_during_method_dispatch]`, which effectively hides a trait from method dispatch when the receiver type is an array.

Then cherry-pick `IntoIterator for [T; N]` from #65819 and gate it with that attribute. Arrays can now be used as `IntoIterator` normally, but `array.into_iter()` has edition-dependent behavior, returning `slice::Iter` for 2015 and 2018 editions, or `array::IntoIter` for 2021 and later.

r? `@nikomatsakis`
cc `@LukasKalbertodt` `@rust-lang/libs`
This commit is contained in:
bors
2021-04-25 07:26:49 +00:00
18 changed files with 237 additions and 171 deletions

View File

@@ -155,6 +155,28 @@ impl<T: fmt::Debug, const N: usize> fmt::Debug for [T; N] {
}
}
// Note: the `#[rustc_skip_array_during_method_dispatch]` on `trait IntoIterator`
// hides this implementation from explicit `.into_iter()` calls on editions < 2021,
// so those calls will still resolve to the slice implementation, by reference.
#[cfg(not(bootstrap))]
#[stable(feature = "array_into_iter_impl", since = "1.53.0")]
impl<T, const N: usize> IntoIterator for [T; N] {
type Item = T;
type IntoIter = IntoIter<T, N>;
/// 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)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T, const N: usize> IntoIterator for &'a [T; N] {
type Item = &'a T;