Skip to content

Commit df0bf5e

Browse files
Add Box<[T; N]>: IntoIterator
1 parent d6d3b34 commit df0bf5e

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

library/alloc/src/boxed.rs

+47
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,51 @@ impl<I> FromIterator<I> for Box<[I]> {
20802082
}
20812083
}
20822084

2085+
/// This implementation is required to make sure that the `Box<[I; N]>: IntoIterator`
2086+
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
2087+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2088+
impl<I, const N: usize, A: Allocator> !Iterator for Box<[I; N], A> {}
2089+
2090+
/// This implementation is required to make sure that the `&Box<[I; N]>: IntoIterator`
2091+
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
2092+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2093+
impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a Box<[I; N], A> {}
2094+
2095+
/// This implementation is required to make sure that the `&mut Box<[I; N]>: IntoIterator`
2096+
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
2097+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2098+
impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a mut Box<[I; N], A> {}
2099+
2100+
// Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator`
2101+
// hides this implementation from explicit `.into_iter()` calls on editions < 2024,
2102+
// so those calls will still resolve to the slice implementation, by reference.
2103+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2104+
impl<I, const N: usize, A: Allocator> IntoIterator for Box<[I; N], A> {
2105+
type IntoIter = vec::IntoIter<I, A>;
2106+
type Item = I;
2107+
fn into_iter(self) -> vec::IntoIter<I, A> {
2108+
(self as Box<[I], A>).into_vec().into_iter()
2109+
}
2110+
}
2111+
2112+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2113+
impl<'a, I, const N: usize, A: Allocator> IntoIterator for &'a Box<[I; N], A> {
2114+
type IntoIter = slice::Iter<'a, I>;
2115+
type Item = &'a I;
2116+
fn into_iter(self) -> slice::Iter<'a, I> {
2117+
self.iter()
2118+
}
2119+
}
2120+
2121+
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
2122+
impl<'a, I, const N: usize, A: Allocator> IntoIterator for &'a mut Box<[I; N], A> {
2123+
type IntoIter = slice::IterMut<'a, I>;
2124+
type Item = &'a mut I;
2125+
fn into_iter(self) -> slice::IterMut<'a, I> {
2126+
self.iter_mut()
2127+
}
2128+
}
2129+
20832130
#[cfg(not(no_global_oom_handling))]
20842131
#[stable(feature = "box_slice_clone", since = "1.3.0")]
20852132
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)