Skip to content

Commit 25f4cb5

Browse files
committed
Remove &[T] from vec_deque::Drain
1 parent 4a6ac3c commit 25f4cb5

File tree

1 file changed

+41
-23
lines changed
  • library/alloc/src/collections/vec_deque

1 file changed

+41
-23
lines changed

Diff for: library/alloc/src/collections/vec_deque/iter.rs

+41-23
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use core::fmt;
22
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
3+
use core::marker::PhantomData;
34
use core::mem::MaybeUninit;
45
use core::ops::Try;
6+
use core::ptr::NonNull;
57

68
use super::{count, wrap_index, RingSlices};
79

@@ -13,38 +15,53 @@ use super::{count, wrap_index, RingSlices};
1315
/// [`iter`]: super::VecDeque::iter
1416
#[stable(feature = "rust1", since = "1.0.0")]
1517
pub struct Iter<'a, T: 'a> {
16-
ring: &'a [MaybeUninit<T>],
18+
ring: NonNull<[T]>,
1719
tail: usize,
1820
head: usize,
21+
_marker: PhantomData<&'a T>,
1922
}
2023

2124
impl<'a, T> Iter<'a, T> {
2225
pub(super) fn new(ring: &'a [MaybeUninit<T>], tail: usize, head: usize) -> Self {
23-
Iter { ring, tail, head }
26+
Iter {
27+
ring: unsafe { NonNull::new_unchecked(ring as *const [MaybeUninit<T>] as *mut _) },
28+
tail,
29+
head,
30+
_marker: PhantomData,
31+
}
32+
}
33+
34+
unsafe fn ring(&self) -> &'a [MaybeUninit<T>] {
35+
unsafe {
36+
core::slice::from_raw_parts(
37+
self.ring.as_ptr() as *const MaybeUninit<T>,
38+
self.ring.len(),
39+
)
40+
}
2441
}
2542
}
2643

44+
#[stable(feature = "rust1", since = "1.0.0")]
45+
unsafe impl<T: Sync> Sync for Iter<'_, T> {}
46+
#[stable(feature = "rust1", since = "1.0.0")]
47+
unsafe impl<T: Sync> Send for Iter<'_, T> {}
48+
2749
#[stable(feature = "collection_debug", since = "1.17.0")]
2850
impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
2951
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30-
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
52+
let (front, back) = unsafe { RingSlices::ring_slices(self.ring(), self.head, self.tail) };
3153
// Safety:
3254
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
3355
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
34-
unsafe {
35-
f.debug_tuple("Iter")
36-
.field(&MaybeUninit::slice_assume_init_ref(front))
37-
.field(&MaybeUninit::slice_assume_init_ref(back))
38-
.finish()
39-
}
56+
f.debug_tuple("Iter").field(&front).field(&back).finish()
4057
}
4158
}
4259

4360
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
4461
#[stable(feature = "rust1", since = "1.0.0")]
4562
impl<T> Clone for Iter<'_, T> {
4663
fn clone(&self) -> Self {
47-
Iter { ring: self.ring, tail: self.tail, head: self.head }
64+
Iter { ring: self.ring, tail: self.tail, head: self.head, _marker: PhantomData }
4865
}
4966
}
5067

@@ -62,7 +79,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
6279
// Safety:
6380
// - `self.tail` in a ring buffer is always a valid index.
6481
// - `self.head` and `self.tail` equality is checked above.
65-
unsafe { Some(self.ring.get_unchecked(tail).assume_init_ref()) }
82+
unsafe { Some(self.ring().get_unchecked(tail).assume_init_ref()) }
6683
}
6784

6885
#[inline]
@@ -75,11 +92,11 @@ impl<'a, T> Iterator for Iter<'a, T> {
7592
where
7693
F: FnMut(Acc, Self::Item) -> Acc,
7794
{
78-
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
7995
// Safety:
8096
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
8197
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
8298
unsafe {
99+
let (front, back) = RingSlices::ring_slices(self.ring(), self.head, self.tail);
83100
accum = MaybeUninit::slice_assume_init_ref(front).iter().fold(accum, &mut f);
84101
MaybeUninit::slice_assume_init_ref(back).iter().fold(accum, &mut f)
85102
}
@@ -94,12 +111,13 @@ impl<'a, T> Iterator for Iter<'a, T> {
94111
let (mut iter, final_res);
95112
if self.tail <= self.head {
96113
// Safety: single slice self.ring[self.tail..self.head] is initialized.
97-
iter = unsafe { MaybeUninit::slice_assume_init_ref(&self.ring[self.tail..self.head]) }
98-
.iter();
114+
iter =
115+
unsafe { MaybeUninit::slice_assume_init_ref(&self.ring()[self.tail..self.head]) }
116+
.iter();
99117
final_res = iter.try_fold(init, &mut f);
100118
} else {
101-
// Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
102-
let (front, back) = self.ring.split_at(self.tail);
119+
// Safety: two slices: self.ring()[self.tail..], self.ring()[..self.head] both are initialized.
120+
let (front, back) = unsafe { self.ring().split_at(self.tail) };
103121

104122
let mut back_iter = unsafe { MaybeUninit::slice_assume_init_ref(back).iter() };
105123
let res = back_iter.try_fold(init, &mut f);
@@ -133,7 +151,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
133151
// that is in bounds.
134152
unsafe {
135153
let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
136-
self.ring.get_unchecked(idx).assume_init_ref()
154+
self.ring().get_unchecked(idx).assume_init_ref()
137155
}
138156
}
139157
}
@@ -149,18 +167,18 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
149167
// Safety:
150168
// - `self.head` in a ring buffer is always a valid index.
151169
// - `self.head` and `self.tail` equality is checked above.
152-
unsafe { Some(self.ring.get_unchecked(self.head).assume_init_ref()) }
170+
unsafe { Some(self.ring().get_unchecked(self.head).assume_init_ref()) }
153171
}
154172

155173
fn rfold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
156174
where
157175
F: FnMut(Acc, Self::Item) -> Acc,
158176
{
159-
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
160177
// Safety:
161178
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
162179
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
163180
unsafe {
181+
let (front, back) = RingSlices::ring_slices(self.ring(), self.head, self.tail);
164182
accum = MaybeUninit::slice_assume_init_ref(back).iter().rfold(accum, &mut f);
165183
MaybeUninit::slice_assume_init_ref(front).iter().rfold(accum, &mut f)
166184
}
@@ -174,14 +192,14 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
174192
{
175193
let (mut iter, final_res);
176194
if self.tail <= self.head {
177-
// Safety: single slice self.ring[self.tail..self.head] is initialized.
195+
// Safety: single slice self.ring()[self.tail..self.head] is initialized.
178196
iter = unsafe {
179-
MaybeUninit::slice_assume_init_ref(&self.ring[self.tail..self.head]).iter()
197+
MaybeUninit::slice_assume_init_ref(&self.ring()[self.tail..self.head]).iter()
180198
};
181199
final_res = iter.try_rfold(init, &mut f);
182200
} else {
183-
// Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
184-
let (front, back) = self.ring.split_at(self.tail);
201+
// Safety: two slices: self.ring()[self.tail..], self.ring()[..self.head] both are initialized.
202+
let (front, back) = unsafe { self.ring().split_at(self.tail) };
185203

186204
let mut front_iter =
187205
unsafe { MaybeUninit::slice_assume_init_ref(&front[..self.head]).iter() };

0 commit comments

Comments
 (0)