Skip to content

Commit 2e5b773

Browse files
committed
Auto merge of rust-lang#124108 - compiler-errors:box-arr-into-iter, r=<try>
[crate] Add `Box<[T; N]>: IntoIterator` without any method dispatch hacks **Unlike** `Box<[T]>` (rust-lang#116607 (comment)), there's a much higher chance that this will not conflict with existing usages since it produces an iterator with the same type before/after this change, but let's test that theory with crater. Ideally we have fewer migrations that are tangled up in hacks like `rustc_skip_during_method_dispatch`, so if this crater comes back clean, I'd strongly suggest landing this as-is. As for the rationale for having this impl at all, I agree (as `@clarfonthey` pointed out in rust-lang#124097 (comment)) that it is generally better for any user to not require moving the array *out* of the box just to turn it into an iterator.
2 parents 9f432d7 + 78d9b1e commit 2e5b773

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

library/alloc/src/boxed.rs

+43
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ use core::ops::{
165165
};
166166
use core::pin::Pin;
167167
use core::ptr::{self, addr_of_mut, NonNull, Unique};
168+
use core::slice;
168169
use core::task::{Context, Poll};
169170

170171
#[cfg(not(no_global_oom_handling))]
@@ -177,6 +178,7 @@ use crate::raw_vec::RawVec;
177178
use crate::str::from_boxed_utf8_unchecked;
178179
#[cfg(not(no_global_oom_handling))]
179180
use crate::string::String;
181+
use crate::vec;
180182
#[cfg(not(no_global_oom_handling))]
181183
use crate::vec::Vec;
182184

@@ -2080,6 +2082,47 @@ impl<I> FromIterator<I> for Box<[I]> {
20802082
}
20812083
}
20822084

2085+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2086+
impl<I, const N: usize, A: Allocator> !Iterator for Box<[I; N], A> {}
2087+
2088+
/// `Box` is fundamental, so coherence needs help understanding these impls are okay.
2089+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2090+
impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a Box<[I; N], A> {}
2091+
2092+
/// `Box` is fundamental, so coherence needs help understanding these impls are okay.
2093+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2094+
impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a mut Box<[I; N], A> {}
2095+
2096+
// Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator`
2097+
// hides this implementation from explicit `.into_iter()` calls on editions < 2024,
2098+
// so those calls will still resolve to the slice implementation, by reference.
2099+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2100+
impl<I, const N: usize, A: Allocator> IntoIterator for Box<[I; N], A> {
2101+
type IntoIter = vec::IntoIter<I, A>;
2102+
type Item = I;
2103+
fn into_iter(self) -> vec::IntoIter<I, A> {
2104+
(self as Box<[I], A>).into_vec().into_iter()
2105+
}
2106+
}
2107+
2108+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2109+
impl<'a, I, const N: usize, A: Allocator> IntoIterator for &'a Box<[I; N], A> {
2110+
type IntoIter = slice::Iter<'a, I>;
2111+
type Item = &'a I;
2112+
fn into_iter(self) -> slice::Iter<'a, I> {
2113+
self.iter()
2114+
}
2115+
}
2116+
2117+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2118+
impl<'a, I, const N: usize, A: Allocator> IntoIterator for &'a mut Box<[I; N], A> {
2119+
type IntoIter = slice::IterMut<'a, I>;
2120+
type Item = &'a mut I;
2121+
fn into_iter(self) -> slice::IterMut<'a, I> {
2122+
self.iter_mut()
2123+
}
2124+
}
2125+
20832126
#[cfg(not(no_global_oom_handling))]
20842127
#[stable(feature = "box_slice_clone", since = "1.3.0")]
20852128
impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {

library/core/src/slice/iter.rs

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use crate::ptr::{self, without_provenance, without_provenance_mut, NonNull};
1616

1717
use super::{from_raw_parts, from_raw_parts_mut};
1818

19+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
20+
impl<T, const N: usize> !Iterator for [T; N] {}
21+
1922
#[stable(feature = "rust1", since = "1.0.0")]
2023
impl<'a, T> IntoIterator for &'a [T] {
2124
type Item = &'a T;

0 commit comments

Comments
 (0)