Skip to content

Commit

Permalink
Auto merge of rust-lang#124108 - compiler-errors:box-arr-into-iter, r…
Browse files Browse the repository at this point in the history
…=<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.
  • Loading branch information
bors committed Apr 18, 2024
2 parents 9f432d7 + 78d9b1e commit 2e5b773
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
43 changes: 43 additions & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ use core::ops::{
};
use core::pin::Pin;
use core::ptr::{self, addr_of_mut, NonNull, Unique};
use core::slice;
use core::task::{Context, Poll};

#[cfg(not(no_global_oom_handling))]
Expand All @@ -177,6 +178,7 @@ use crate::raw_vec::RawVec;
use crate::str::from_boxed_utf8_unchecked;
#[cfg(not(no_global_oom_handling))]
use crate::string::String;
use crate::vec;
#[cfg(not(no_global_oom_handling))]
use crate::vec::Vec;

Expand Down Expand Up @@ -2080,6 +2082,47 @@ impl<I> FromIterator<I> for Box<[I]> {
}
}

#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
impl<I, const N: usize, A: Allocator> !Iterator for Box<[I; N], A> {}

/// `Box` is fundamental, so coherence needs help understanding these impls are okay.
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a Box<[I; N], A> {}

/// `Box` is fundamental, so coherence needs help understanding these impls are okay.
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
impl<'a, const N: usize, I, A: Allocator> !Iterator for &'a mut Box<[I; N], A> {}

// Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator`
// hides this implementation from explicit `.into_iter()` calls on editions < 2024,
// so those calls will still resolve to the slice implementation, by reference.
#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
impl<I, const N: usize, A: Allocator> IntoIterator for Box<[I; N], A> {
type IntoIter = vec::IntoIter<I, A>;
type Item = I;
fn into_iter(self) -> vec::IntoIter<I, A> {
(self as Box<[I], A>).into_vec().into_iter()
}
}

#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
impl<'a, I, const N: usize, A: Allocator> IntoIterator for &'a Box<[I; N], A> {
type IntoIter = slice::Iter<'a, I>;
type Item = &'a I;
fn into_iter(self) -> slice::Iter<'a, I> {
self.iter()
}
}

#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
impl<'a, I, const N: usize, A: Allocator> IntoIterator for &'a mut Box<[I; N], A> {
type IntoIter = slice::IterMut<'a, I>;
type Item = &'a mut I;
fn into_iter(self) -> slice::IterMut<'a, I> {
self.iter_mut()
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_slice_clone", since = "1.3.0")]
impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ use crate::ptr::{self, without_provenance, without_provenance_mut, NonNull};

use super::{from_raw_parts, from_raw_parts_mut};

#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")]
impl<T, const N: usize> !Iterator for [T; N] {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> IntoIterator for &'a [T] {
type Item = &'a T;
Expand Down

0 comments on commit 2e5b773

Please sign in to comment.