Skip to content

Commit 8909bbf

Browse files
orlpjswrenn
authored andcommitted
Address some review comments.
1 parent 81d085b commit 8909bbf

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

src/next_array.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,45 @@
1-
use core::mem::MaybeUninit;
1+
use core::mem::{self, MaybeUninit};
22
use core::ptr;
33

4-
/// Helper struct to build up an array element by element.
4+
/// An array of at most `N` elements.
55
struct ArrayBuilder<T, const N: usize> {
6-
arr: [MaybeUninit<T>; N], // Invariant: arr[..len] is initialized.
6+
arr: [MaybeUninit<T>; N], // Invariant: arr[..len] is valid.
77
len: usize, // Invariant: len <= N.
88
}
99

1010
impl<T, const N: usize> ArrayBuilder<T, N> {
11+
/// Initializes a new, empty `ArrayBuilder`.
1112
pub fn new() -> Self {
13+
// SAFETY: the validity invariant trivially hold for a zero-length array.
1214
Self {
1315
arr: [(); N].map(|_| MaybeUninit::uninit()),
1416
len: 0,
1517
}
1618
}
1719

20+
/// Pushes `value` onto the end of the array.
21+
///
22+
/// # Panics
23+
///
24+
/// This panics if `self.len() >= N`.
1825
pub fn push(&mut self, value: T) {
19-
// We maintain the invariant here that arr[..len] is initialized.
26+
// SAFETY: we maintain the invariant here that arr[..len] is valid.
2027
// Indexing with self.len also ensures self.len < N, and thus <= N after
2128
// the increment.
2229
self.arr[self.len] = MaybeUninit::new(value);
2330
self.len += 1;
2431
}
2532

33+
/// Consumes the elements in the `ArrayBuilder` and returns them as an array `[T; N]`.
34+
///
35+
/// If `self.len() < N`, this returns `None`.
2636
pub fn take(&mut self) -> Option<[T; N]> {
2737
if self.len == N {
28-
// Take the array, resetting the length back to zero.
29-
let arr = core::mem::replace(&mut self.arr, [(); N].map(|_| MaybeUninit::uninit()));
38+
// Take the array, resetting our length back to zero.
3039
self.len = 0;
40+
let arr = mem::replace(&mut self.arr, [(); N].map(|_| MaybeUninit::uninit()));
3141

32-
// SAFETY: we had len == N, so all elements in arr are initialized.
42+
// SAFETY: we had len == N, so all elements in arr are valid.
3343
Some(unsafe { arr.map(|v| v.assume_init()) })
3444
} else {
3545
None
@@ -40,10 +50,10 @@ impl<T, const N: usize> ArrayBuilder<T, N> {
4050
impl<T, const N: usize> Drop for ArrayBuilder<T, N> {
4151
fn drop(&mut self) {
4252
unsafe {
43-
// SAFETY: arr[..len] is initialized, so must be dropped.
44-
// First we create a pointer to this initialized slice, then drop
45-
// that slice in-place. The cast from *mut MaybeUninit<T> to *mut T
46-
// is always sound by the layout guarantees of MaybeUninit.
53+
// SAFETY: arr[..len] is valid, so must be dropped. First we create
54+
// a pointer to this valid slice, then drop that slice in-place.
55+
// The cast from *mut MaybeUninit<T> to *mut T is always sound by
56+
// the layout guarantees of MaybeUninit.
4757
let ptr_to_first: *mut MaybeUninit<T> = self.arr.as_mut_ptr();
4858
let ptr_to_slice = ptr::slice_from_raw_parts_mut(ptr_to_first.cast::<T>(), self.len);
4959
ptr::drop_in_place(ptr_to_slice);

tests/test_core.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,4 +396,4 @@ fn collect_array() {
396396
let v = [1, 2, 3];
397397
let iter = v.iter().cloned();
398398
assert_eq!(iter.collect_array::<_, 2>(), None);
399-
}
399+
}

0 commit comments

Comments
 (0)