Rollup merge of #151613 - cuviper:array-windows-parity, r=Amanieu

Align `ArrayWindows` trait impls with `Windows`

With `slice::ArrayWindows` getting ready to stabilize in 1.94, I noticed that it currently has some differences in trait implementations compared to `slice::Windows`, and I think we should align these.

- Remove `derive(Copy)` -- we generally don't want `Copy` for iterators at all, as this is seen as a footgun (e.g. rust-lang/rust#21809). This is obviously a breaking change though, so we should only remove this if we also backport the removal before it's stable. Otherwise, it should at least be replaced by a manual impl without requiring `T: Copy`.
- Manually `impl Clone`, simply to avoid requiring `T: Clone`.
- `impl FusedIterator`, because it is trivially so. The `since = "1.94.0"` assumes we'll backport this, otherwise we should change that to the "current" placeholder.
- `impl TrustedLen`, because we can trust our implementation.
- `impl TrustedRandomAccess`, because the required `__iterator_get_unchecked` method is straightforward.

r? libs-api

@rustbot label beta-nominated
(at least for the `Copy` removal, but we could be more selective about the rest).
This commit is contained in:
Matthias Krüger 2026-02-09 18:39:39 +01:00 committed by GitHub
commit 144b77aad2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2175,7 +2175,7 @@ unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
///
/// [`array_windows`]: slice::array_windows
/// [slices]: slice
#[derive(Debug, Clone, Copy)]
#[derive(Debug)]
#[stable(feature = "array_windows", since = "1.94.0")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ArrayWindows<'a, T: 'a, const N: usize> {
@ -2189,6 +2189,14 @@ impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
}
}
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[stable(feature = "array_windows", since = "1.94.0")]
impl<T, const N: usize> Clone for ArrayWindows<'_, T, N> {
fn clone(&self) -> Self {
Self { v: self.v }
}
}
#[stable(feature = "array_windows", since = "1.94.0")]
impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
type Item = &'a [T; N];
@ -2224,6 +2232,14 @@ impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
fn last(self) -> Option<Self::Item> {
self.v.last_chunk()
}
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
// SAFETY: since the caller guarantees that `idx` is in bounds,
// which means that `idx` cannot overflow an `isize`, and the
// "slice" created by `cast_array` is a subslice of `self.v`
// thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
unsafe { &*self.v.as_ptr().add(idx).cast_array() }
}
}
#[stable(feature = "array_windows", since = "1.94.0")]
@ -2252,6 +2268,22 @@ impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
}
}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T, const N: usize> TrustedLen for ArrayWindows<'_, T, N> {}
#[stable(feature = "array_windows", since = "1.94.0")]
impl<T, const N: usize> FusedIterator for ArrayWindows<'_, T, N> {}
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<T, const N: usize> TrustedRandomAccess for ArrayWindows<'_, T, N> {}
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<T, const N: usize> TrustedRandomAccessNoCoerce for ArrayWindows<'_, T, N> {
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
/// time), starting at the end of the slice.
///