Skip to content

Commit eb667be

Browse files
committed
Tidy up maybe_uninit_slice API
- Move methods to extensions Signed-off-by: Alex Saveau <[email protected]>
1 parent 8be3ce9 commit eb667be

File tree

17 files changed

+122
-132
lines changed

17 files changed

+122
-132
lines changed

compiler/rustc_arena/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl<T> ArenaChunk<T> {
8585
// Without the branch, dropping TypedArena<u8> takes linear time.
8686
if mem::needs_drop::<T>() {
8787
let slice = &mut *(self.storage.as_mut());
88-
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
88+
ptr::drop_in_place(slice[..len].assume_init_mut());
8989
}
9090
}
9191

compiler/rustc_serialize/src/leb128.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ macro_rules! impl_write_unsigned_leb128 {
3939
}
4040
}
4141

42-
unsafe { ::std::mem::MaybeUninit::slice_assume_init_ref(&out.get_unchecked(..i)) }
42+
unsafe { out.get_unchecked(..i).assume_init_ref() }
4343
}
4444
};
4545
}
@@ -116,7 +116,7 @@ macro_rules! impl_write_signed_leb128 {
116116
}
117117
}
118118

119-
unsafe { ::std::mem::MaybeUninit::slice_assume_init_ref(&out.get_unchecked(..i)) }
119+
unsafe { out.get_unchecked(..i).assume_init_ref() }
120120
}
121121
};
122122
}

compiler/rustc_serialize/src/opaque.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ impl FileEncoder {
275275
}
276276

277277
let mut guard = BufGuard::new(
278-
unsafe { MaybeUninit::slice_assume_init_mut(&mut self.buf[..self.buffered]) },
278+
unsafe { self.buf[..self.buffered].assume_init_mut() },
279279
&mut self.buffered,
280280
&mut self.flushed,
281281
);

library/alloc/src/collections/btree/node.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
380380
/// Borrows a view into the keys stored in the node.
381381
pub fn keys(&self) -> &[K] {
382382
let leaf = self.into_leaf();
383-
unsafe {
384-
MaybeUninit::slice_assume_init_ref(leaf.keys.get_unchecked(..usize::from(leaf.len)))
385-
}
383+
unsafe { leaf.keys.get_unchecked(..usize::from(leaf.len)).assume_init_ref() }
386384
}
387385
}
388386

library/alloc/src/collections/vec_deque/iter.rs

+12-16
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
3333
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
3434
unsafe {
3535
f.debug_tuple("Iter")
36-
.field(&MaybeUninit::slice_assume_init_ref(front))
37-
.field(&MaybeUninit::slice_assume_init_ref(back))
36+
.field(&front.assume_init_ref())
37+
.field(&back.assume_init_ref())
3838
.finish()
3939
}
4040
}
@@ -80,8 +80,8 @@ impl<'a, T> Iterator for Iter<'a, T> {
8080
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
8181
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
8282
unsafe {
83-
accum = MaybeUninit::slice_assume_init_ref(front).iter().fold(accum, &mut f);
84-
MaybeUninit::slice_assume_init_ref(back).iter().fold(accum, &mut f)
83+
accum = front.assume_init_ref().iter().fold(accum, &mut f);
84+
back.assume_init_ref().iter().fold(accum, &mut f)
8585
}
8686
}
8787

@@ -94,18 +94,17 @@ impl<'a, T> Iterator for Iter<'a, T> {
9494
let (mut iter, final_res);
9595
if self.tail <= self.head {
9696
// 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();
97+
iter = unsafe { self.ring[self.tail..self.head].assume_init_ref() }.iter();
9998
final_res = iter.try_fold(init, &mut f);
10099
} else {
101100
// Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
102101
let (front, back) = self.ring.split_at(self.tail);
103102

104-
let mut back_iter = unsafe { MaybeUninit::slice_assume_init_ref(back).iter() };
103+
let mut back_iter = unsafe { back.assume_init_ref().iter() };
105104
let res = back_iter.try_fold(init, &mut f);
106105
let len = self.ring.len();
107106
self.tail = (self.ring.len() - back_iter.len()) & (len - 1);
108-
iter = unsafe { MaybeUninit::slice_assume_init_ref(&front[..self.head]).iter() };
107+
iter = unsafe { front[..self.head].assume_init_ref().iter() };
109108
final_res = iter.try_fold(res?, &mut f);
110109
}
111110
self.tail = self.head - iter.len();
@@ -161,8 +160,8 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
161160
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
162161
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
163162
unsafe {
164-
accum = MaybeUninit::slice_assume_init_ref(back).iter().rfold(accum, &mut f);
165-
MaybeUninit::slice_assume_init_ref(front).iter().rfold(accum, &mut f)
163+
accum = back.assume_init_ref().iter().rfold(accum, &mut f);
164+
front.assume_init_ref().iter().rfold(accum, &mut f)
166165
}
167166
}
168167

@@ -175,19 +174,16 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
175174
let (mut iter, final_res);
176175
if self.tail <= self.head {
177176
// Safety: single slice self.ring[self.tail..self.head] is initialized.
178-
iter = unsafe {
179-
MaybeUninit::slice_assume_init_ref(&self.ring[self.tail..self.head]).iter()
180-
};
177+
iter = unsafe { self.ring[self.tail..self.head].assume_init_ref().iter() };
181178
final_res = iter.try_rfold(init, &mut f);
182179
} else {
183180
// Safety: two slices: self.ring[self.tail..], self.ring[..self.head] both are initialized.
184181
let (front, back) = self.ring.split_at(self.tail);
185182

186-
let mut front_iter =
187-
unsafe { MaybeUninit::slice_assume_init_ref(&front[..self.head]).iter() };
183+
let mut front_iter = unsafe { front[..self.head].assume_init_ref().iter() };
188184
let res = front_iter.try_rfold(init, &mut f);
189185
self.head = front_iter.len();
190-
iter = unsafe { MaybeUninit::slice_assume_init_ref(back).iter() };
186+
iter = unsafe { back.assume_init_ref().iter() };
191187
final_res = iter.try_rfold(res?, &mut f);
192188
}
193189
self.head = self.tail + iter.len();

library/alloc/src/collections/vec_deque/mod.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
11031103
unsafe {
11041104
let buf = self.buffer_as_slice();
11051105
let (front, back) = RingSlices::ring_slices(buf, self.head, self.tail);
1106-
(MaybeUninit::slice_assume_init_ref(front), MaybeUninit::slice_assume_init_ref(back))
1106+
(front.assume_init_ref(), back.assume_init_ref())
11071107
}
11081108
}
11091109

@@ -1143,7 +1143,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
11431143
let tail = self.tail;
11441144
let buf = self.buffer_as_mut_slice();
11451145
let (front, back) = RingSlices::ring_slices(buf, head, tail);
1146-
(MaybeUninit::slice_assume_init_mut(front), MaybeUninit::slice_assume_init_mut(back))
1146+
(front.assume_init_mut(), back.assume_init_mut())
11471147
}
11481148
}
11491149

@@ -2379,9 +2379,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
23792379
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
23802380
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
23812381
return unsafe {
2382-
MaybeUninit::slice_assume_init_mut(
2383-
RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0,
2384-
)
2382+
RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0.assume_init_mut()
23852383
};
23862384
}
23872385

@@ -2472,9 +2470,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
24722470
// - `self.head` and `self.tail` in a ring buffer are always valid indices.
24732471
// - `RingSlices::ring_slices` guarantees that the slices split according to `self.head` and `self.tail` are initialized.
24742472
unsafe {
2475-
MaybeUninit::slice_assume_init_mut(
2476-
RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0,
2477-
)
2473+
RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0.assume_init_mut()
24782474
}
24792475
}
24802476

library/core/src/array/iter.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ impl<T, const N: usize> IntoIter<T, N> {
223223
// SAFETY: We know that all elements within `alive` are properly initialized.
224224
unsafe {
225225
let slice = self.data.get_unchecked(self.alive.clone());
226-
MaybeUninit::slice_assume_init_ref(slice)
226+
slice.assume_init_ref()
227227
}
228228
}
229229

@@ -233,7 +233,7 @@ impl<T, const N: usize> IntoIter<T, N> {
233233
// SAFETY: We know that all elements within `alive` are properly initialized.
234234
unsafe {
235235
let slice = self.data.get_unchecked_mut(self.alive.clone());
236-
MaybeUninit::slice_assume_init_mut(slice)
236+
slice.assume_init_mut()
237237
}
238238
}
239239
}
@@ -295,7 +295,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
295295
// SAFETY: These elements are currently initialized, so it's fine to drop them.
296296
unsafe {
297297
let slice = self.data.get_unchecked_mut(range_to_drop);
298-
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
298+
ptr::drop_in_place(slice.assume_init_mut());
299299
}
300300

301301
if n > original_len { Err(original_len) } else { Ok(()) }
@@ -345,7 +345,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
345345
// SAFETY: These elements are currently initialized, so it's fine to drop them.
346346
unsafe {
347347
let slice = self.data.get_unchecked_mut(range_to_drop);
348-
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
348+
ptr::drop_in_place(slice.assume_init_mut());
349349
}
350350

351351
if n > original_len { Err(original_len) } else { Ok(()) }

library/core/src/array/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -872,9 +872,9 @@ where
872872

873873
// SAFETY: this slice will contain only initialized objects.
874874
unsafe {
875-
crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
876-
&mut self.array_mut.get_unchecked_mut(..self.initialized),
877-
));
875+
crate::ptr::drop_in_place(
876+
self.array_mut.get_unchecked_mut(..self.initialized).assume_init_mut(),
877+
);
878878
}
879879
}
880880
}

library/core/src/mem/maybe_uninit.rs

+51-49
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ impl<T> MaybeUninit<T> {
337337
/// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] {
338338
/// unsafe {
339339
/// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len());
340-
/// MaybeUninit::slice_assume_init_ref(&buf[..len])
340+
/// buf[..len].assume_init_ref()
341341
/// }
342342
/// }
343343
///
@@ -956,48 +956,6 @@ impl<T> MaybeUninit<T> {
956956
ret
957957
}
958958

959-
/// Assuming all the elements are initialized, get a slice to them.
960-
///
961-
/// # Safety
962-
///
963-
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
964-
/// really are in an initialized state.
965-
/// Calling this when the content is not yet fully initialized causes undefined behavior.
966-
///
967-
/// See [`assume_init_ref`] for more details and examples.
968-
///
969-
/// [`assume_init_ref`]: MaybeUninit::assume_init_ref
970-
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
971-
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
972-
#[inline(always)]
973-
pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
974-
// SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
975-
// `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`.
976-
// The pointer obtained is valid since it refers to memory owned by `slice` which is a
977-
// reference and thus guaranteed to be valid for reads.
978-
unsafe { &*(slice as *const [Self] as *const [T]) }
979-
}
980-
981-
/// Assuming all the elements are initialized, get a mutable slice to them.
982-
///
983-
/// # Safety
984-
///
985-
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
986-
/// really are in an initialized state.
987-
/// Calling this when the content is not yet fully initialized causes undefined behavior.
988-
///
989-
/// See [`assume_init_mut`] for more details and examples.
990-
///
991-
/// [`assume_init_mut`]: MaybeUninit::assume_init_mut
992-
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
993-
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
994-
#[inline(always)]
995-
pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
996-
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
997-
// mutable reference which is also guaranteed to be valid for writes.
998-
unsafe { &mut *(slice as *mut [Self] as *mut [T]) }
999-
}
1000-
1001959
/// Gets a pointer to the first element of the array.
1002960
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1003961
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
@@ -1068,7 +1026,7 @@ impl<T> MaybeUninit<T> {
10681026
this.copy_from_slice(uninit_src);
10691027

10701028
// SAFETY: Valid elements have just been copied into `this` so it is initialized
1071-
unsafe { MaybeUninit::slice_assume_init_mut(this) }
1029+
unsafe { this.assume_init_mut() }
10721030
}
10731031

10741032
/// Clones the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
@@ -1136,7 +1094,7 @@ impl<T> MaybeUninit<T> {
11361094
// SAFETY: this raw slice will contain only initialized objects
11371095
// that's why, it is allowed to drop it.
11381096
unsafe {
1139-
crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(initialized_part));
1097+
crate::ptr::drop_in_place(initialized_part.assume_init_mut());
11401098
}
11411099
}
11421100
}
@@ -1159,7 +1117,7 @@ impl<T> MaybeUninit<T> {
11591117
super::forget(guard);
11601118

11611119
// SAFETY: Valid elements have just been written into `this` so it is initialized
1162-
unsafe { MaybeUninit::slice_assume_init_mut(this) }
1120+
unsafe { this.assume_init_mut() }
11631121
}
11641122

11651123
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
@@ -1176,7 +1134,7 @@ impl<T> MaybeUninit<T> {
11761134
/// let val = 0x12345678i32;
11771135
/// let uninit = MaybeUninit::new(val);
11781136
/// let uninit_bytes = uninit.as_bytes();
1179-
/// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) };
1137+
/// let bytes = unsafe { uninit_bytes.assume_init_ref() };
11801138
/// assert_eq!(bytes, val.to_ne_bytes());
11811139
/// ```
11821140
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
@@ -1235,7 +1193,7 @@ impl<T> MaybeUninit<T> {
12351193
///
12361194
/// let uninit = [MaybeUninit::new(0x1234u16), MaybeUninit::new(0x5678u16)];
12371195
/// let uninit_bytes = MaybeUninit::slice_as_bytes(&uninit);
1238-
/// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(&uninit_bytes) };
1196+
/// let bytes = unsafe { uninit_bytes.assume_init_ref() };
12391197
/// let val1 = u16::from_ne_bytes(bytes[0..2].try_into().unwrap());
12401198
/// let val2 = u16::from_ne_bytes(bytes[2..4].try_into().unwrap());
12411199
/// assert_eq!(&[val1, val2], &[0x1234u16, 0x5678u16]);
@@ -1266,7 +1224,7 @@ impl<T> MaybeUninit<T> {
12661224
/// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()];
12671225
/// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit);
12681226
/// MaybeUninit::write_slice(uninit_bytes, &[0x12, 0x34, 0x56, 0x78]);
1269-
/// let vals = unsafe { MaybeUninit::slice_assume_init_ref(&uninit) };
1227+
/// let vals = unsafe { uninit.assume_init_ref() };
12701228
/// if cfg!(target_endian = "little") {
12711229
/// assert_eq!(vals, &[0x3412u16, 0x7856u16]);
12721230
/// } else {
@@ -1321,3 +1279,47 @@ impl<T, const N: usize> [MaybeUninit<T>; N] {
13211279
unsafe { super::transmute_copy(&ManuallyDrop::new(self)) }
13221280
}
13231281
}
1282+
1283+
impl<T> [MaybeUninit<T>] {
1284+
/// Assuming all the elements are initialized, get a slice to them.
1285+
///
1286+
/// # Safety
1287+
///
1288+
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
1289+
/// really are in an initialized state.
1290+
/// Calling this when the content is not yet fully initialized causes undefined behavior.
1291+
///
1292+
/// See [`assume_init_ref`] for more details and examples.
1293+
///
1294+
/// [`assume_init_ref`]: MaybeUninit::assume_init_ref
1295+
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1296+
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
1297+
#[inline(always)]
1298+
pub const unsafe fn assume_init_ref(&self) -> &[T] {
1299+
// SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
1300+
// `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`.
1301+
// The pointer obtained is valid since it refers to memory owned by `slice` which is a
1302+
// reference and thus guaranteed to be valid for reads.
1303+
unsafe { &*(self as *const [MaybeUninit<T>] as *const [T]) }
1304+
}
1305+
1306+
/// Assuming all the elements are initialized, get a mutable slice to them.
1307+
///
1308+
/// # Safety
1309+
///
1310+
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
1311+
/// really are in an initialized state.
1312+
/// Calling this when the content is not yet fully initialized causes undefined behavior.
1313+
///
1314+
/// See [`assume_init_mut`] for more details and examples.
1315+
///
1316+
/// [`assume_init_mut`]: MaybeUninit::assume_init_mut
1317+
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
1318+
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
1319+
#[inline(always)]
1320+
pub const unsafe fn assume_init_mut(&mut self) -> &mut [T] {
1321+
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
1322+
// mutable reference which is also guaranteed to be valid for writes.
1323+
unsafe { &mut *(self as *mut [MaybeUninit<T>] as *mut [T]) }
1324+
}
1325+
}

0 commit comments

Comments
 (0)