Skip to content

Commit a88414e

Browse files
committed
libcore: avoid mem::uninitialized and raw ptr casts
1 parent c11e514 commit a88414e

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

src/libcore/fmt/num.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ops::{Div, Rem, Sub};
66
use str;
77
use slice;
88
use ptr;
9-
use mem;
9+
use mem::MaybeUninit;
1010

1111
#[doc(hidden)]
1212
trait Int: PartialEq + PartialOrd + Div<Output=Self> + Rem<Output=Self> +
@@ -51,7 +51,12 @@ trait GenericRadix {
5151
// characters for a base 2 number.
5252
let zero = T::zero();
5353
let is_nonnegative = x >= zero;
54-
let mut buf: [u8; 128] = unsafe { mem::uninitialized() };
54+
// Creating a `[MaybeUninit; N]` array by first creating a
55+
// `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
56+
// array does not require initialization.
57+
let mut buf: [MaybeUninit<u8>; 128] = unsafe {
58+
MaybeUninit::uninitialized().into_inner()
59+
};
5560
let mut curr = buf.len();
5661
let base = T::from_u8(Self::BASE);
5762
if is_nonnegative {
@@ -60,7 +65,7 @@ trait GenericRadix {
6065
for byte in buf.iter_mut().rev() {
6166
let n = x % base; // Get the current place value.
6267
x = x / base; // Deaccumulate the number.
63-
*byte = Self::digit(n.to_u8()); // Store the digit in the buffer.
68+
byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer.
6469
curr -= 1;
6570
if x == zero {
6671
// No more digits left to accumulate.
@@ -72,15 +77,19 @@ trait GenericRadix {
7277
for byte in buf.iter_mut().rev() {
7378
let n = zero - (x % base); // Get the current place value.
7479
x = x / base; // Deaccumulate the number.
75-
*byte = Self::digit(n.to_u8()); // Store the digit in the buffer.
80+
byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer.
7681
curr -= 1;
7782
if x == zero {
7883
// No more digits left to accumulate.
7984
break
8085
};
8186
}
8287
}
83-
let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) };
88+
let buf = &buf[curr..];
89+
let buf = unsafe { str::from_utf8_unchecked(slice::from_raw_parts(
90+
MaybeUninit::first_ptr(buf),
91+
buf.len()
92+
)) };
8493
f.pad_integral(is_nonnegative, Self::PREFIX, buf)
8594
}
8695
}
@@ -194,9 +203,14 @@ macro_rules! impl_Display {
194203
// convert the negative num to positive by summing 1 to it's 2 complement
195204
(!self.$conv_fn()).wrapping_add(1)
196205
};
197-
let mut buf: [u8; 39] = unsafe { mem::uninitialized() };
206+
// Creating a `[MaybeUninit; N]` array by first creating a
207+
// `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
208+
// array does not require initialization.
209+
let mut buf: [MaybeUninit<u8>; 39] = unsafe {
210+
MaybeUninit::uninitialized().into_inner()
211+
};
198212
let mut curr = buf.len() as isize;
199-
let buf_ptr = buf.as_mut_ptr();
213+
let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf);
200214
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
201215

202216
unsafe {

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
6161

6262
#![no_core]
63+
#![warn(deprecated_in_future)]
6364
#![deny(missing_docs)]
6465
#![deny(intra_doc_link_resolution_failure)]
6566
#![deny(missing_debug_implementations)]

src/libcore/mem.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,4 +1148,18 @@ impl<T> MaybeUninit<T> {
11481148
pub fn as_mut_ptr(&mut self) -> *mut T {
11491149
unsafe { &mut *self.value as *mut T }
11501150
}
1151+
1152+
/// Get a pointer to the first contained values.
1153+
#[unstable(feature = "maybe_uninit", issue = "53491")]
1154+
#[inline(always)]
1155+
pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
1156+
this as *const [MaybeUninit<T>] as *const T
1157+
}
1158+
1159+
/// Get a mutable pointer to the first contained values.
1160+
#[unstable(feature = "maybe_uninit", issue = "53491")]
1161+
#[inline(always)]
1162+
pub fn first_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
1163+
this as *mut [MaybeUninit<T>] as *mut T
1164+
}
11511165
}

src/libcore/slice/sort.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,21 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
216216
let mut block_l = BLOCK;
217217
let mut start_l = ptr::null_mut();
218218
let mut end_l = ptr::null_mut();
219-
let mut offsets_l = MaybeUninit::<[u8; BLOCK]>::uninitialized();
219+
// Creating a `[MaybeUninit; N]` array by first creating a
220+
// `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
221+
// array does not require initialization.
222+
let mut offsets_l: [MaybeUninit<u8>; BLOCK] = unsafe {
223+
MaybeUninit::uninitialized().into_inner()
224+
};
220225

221226
// The current block on the right side (from `r.sub(block_r)` to `r`).
222227
let mut r = unsafe { l.add(v.len()) };
223228
let mut block_r = BLOCK;
224229
let mut start_r = ptr::null_mut();
225230
let mut end_r = ptr::null_mut();
226-
let mut offsets_r = MaybeUninit::<[u8; BLOCK]>::uninitialized();
231+
let mut offsets_r: [MaybeUninit<u8>; BLOCK] = unsafe {
232+
MaybeUninit::uninitialized().into_inner()
233+
};
227234

228235
// FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather
229236
// than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient.
@@ -262,8 +269,8 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
262269

263270
if start_l == end_l {
264271
// Trace `block_l` elements from the left side.
265-
start_l = offsets_l.as_mut_ptr() as *mut u8;
266-
end_l = offsets_l.as_mut_ptr() as *mut u8;
272+
start_l = MaybeUninit::first_mut_ptr(&mut offsets_l);
273+
end_l = MaybeUninit::first_mut_ptr(&mut offsets_l);
267274
let mut elem = l;
268275

269276
for i in 0..block_l {
@@ -278,8 +285,8 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
278285

279286
if start_r == end_r {
280287
// Trace `block_r` elements from the right side.
281-
start_r = offsets_r.as_mut_ptr() as *mut u8;
282-
end_r = offsets_r.as_mut_ptr() as *mut u8;
288+
start_r = MaybeUninit::first_mut_ptr(&mut offsets_r);
289+
end_r = MaybeUninit::first_mut_ptr(&mut offsets_r);
283290
let mut elem = r;
284291

285292
for i in 0..block_r {

0 commit comments

Comments
 (0)