Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuke slice_as{,_mut}_ptr methods of MaybeUninit #103133

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_serialize/src/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl FileEncoder {
// SAFETY: The above check and `flush` ensures that there is enough
// room to write the input to the buffer.
unsafe {
*MaybeUninit::slice_as_mut_ptr(&mut self.buf).add(buffered) = value;
self.buf.get_unchecked_mut(buffered).write(value);
}

self.buffered = buffered + 1;
Expand All @@ -182,7 +182,7 @@ impl FileEncoder {
// room to write the input to the buffer.
unsafe {
let src = buf.as_ptr();
let dst = MaybeUninit::slice_as_mut_ptr(&mut self.buf).add(buffered);
let dst = self.buf.as_mut_ptr().add(buffered).cast::<u8>();
ptr::copy_nonoverlapping(src, dst, buf_len);
}

Expand Down
43 changes: 16 additions & 27 deletions library/core/src/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,7 @@ unsafe trait GenericRadix: Sized {
// SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be
// valid UTF-8
let buf = unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(
MaybeUninit::slice_as_ptr(buf),
buf.len(),
))
str::from_utf8_unchecked(slice::from_raw_parts(buf.as_ptr().cast::<u8>(), buf.len()))
};
f.pad_integral(is_nonnegative, Self::PREFIX, buf)
}
Expand Down Expand Up @@ -216,7 +213,7 @@ macro_rules! impl_Display {
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
let mut curr = buf.len();
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let buf_ptr = buf.as_mut_ptr().cast::<u8>();
let lut_ptr = DEC_DIGITS_LUT.as_ptr();

// SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we
Expand Down Expand Up @@ -344,7 +341,7 @@ macro_rules! impl_Exp {
// that `curr >= 0`.
let mut buf = [MaybeUninit::<u8>::uninit(); 40];
let mut curr = buf.len(); //index for buf
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let buf_ptr = buf.as_mut_ptr().cast::<u8>();
let lut_ptr = DEC_DIGITS_LUT.as_ptr();

// decode 2 chars at a time
Expand Down Expand Up @@ -392,20 +389,19 @@ macro_rules! impl_Exp {

// stores 'e' (or 'E') and the up to 2-digit exponent
let mut exp_buf = [MaybeUninit::<u8>::uninit(); 3];
let exp_ptr = MaybeUninit::slice_as_mut_ptr(&mut exp_buf);
// SAFETY: In either case, `exp_buf` is written within bounds and `exp_ptr[..len]`
// is contained within `exp_buf` since `len <= 3`.
let exp_slice = unsafe {
*exp_ptr.add(0) = if upper { b'E' } else { b'e' };
exp_buf[0].write(if upper { b'E' } else { b'e' });
let exp_slice = {
let len = if exponent < 10 {
*exp_ptr.add(1) = (exponent as u8) + b'0';
exp_buf[1].write((exponent as u8) + b'0');
2
} else {
let off = exponent << 1;
ptr::copy_nonoverlapping(lut_ptr.add(off), exp_ptr.add(1), 2);
// SAFETY: 1 + 2 <= 3
unsafe { ptr::copy_nonoverlapping(lut_ptr.add(off), exp_buf.as_mut_ptr().add(1).cast::<u8>(), 2); }
3
};
slice::from_raw_parts(exp_ptr, len)
// SAFETY: max(2, 3) <= 3
unsafe { slice::from_raw_parts(exp_buf.as_mut_ptr().cast::<u8>(), len) }
};

let parts = &[
Expand Down Expand Up @@ -485,7 +481,7 @@ impl_Exp!(i128, u128 as u128 via to_u128 named exp_u128);

/// Helper function for writing a u64 into `buf` going from last to first, with `curr`.
fn parse_u64_into<const N: usize>(mut n: u64, buf: &mut [MaybeUninit<u8>; N], curr: &mut usize) {
let buf_ptr = MaybeUninit::slice_as_mut_ptr(buf);
let buf_ptr = buf.as_mut_ptr().cast::<u8>();
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
assert!(*curr > 19);

Expand Down Expand Up @@ -609,11 +605,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
// SAFETY: Guaranteed that we wrote at most 19 bytes, and there must be space
// remaining since it has length 39
unsafe {
ptr::write_bytes(
MaybeUninit::slice_as_mut_ptr(&mut buf).add(target),
b'0',
curr - target,
);
ptr::write_bytes(buf.as_mut_ptr().add(target), b'0', curr - target);
}
curr = target;

Expand All @@ -622,24 +614,21 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
// Should this following branch be annotated with unlikely?
if n != 0 {
let target = buf.len() - 38;
// The raw `buf_ptr` pointer is only valid until `buf` is used the next time,
// buf `buf` is not used in this scope so we are good.
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
// SAFETY: At this point we wrote at most 38 bytes, pad up to that point,
// There can only be at most 1 digit remaining.
unsafe {
ptr::write_bytes(buf_ptr.add(target), b'0', curr - target);
curr = target - 1;
*buf_ptr.add(curr) = (n as u8) + b'0';
ptr::write_bytes(buf.as_mut_ptr().add(target), b'0', curr - target);
}
curr = target - 1;
buf[curr].write((n as u8) + b'0');
}
}

// SAFETY: `curr` > 0 (since we made `buf` large enough), and all the chars are valid
// UTF-8 since `DEC_DIGITS_LUT` is
let buf_slice = unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(
MaybeUninit::slice_as_mut_ptr(&mut buf).add(curr),
buf.as_mut_ptr().add(curr).cast::<u8>(),
buf.len() - curr,
))
};
Expand Down
16 changes: 0 additions & 16 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,22 +993,6 @@ impl<T> MaybeUninit<T> {
unsafe { &mut *(slice as *mut [Self] as *mut [T]) }
}

/// Gets a pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub const fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
this.as_ptr() as *const T
}

/// Gets a mutable pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub const fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
this.as_mut_ptr() as *mut T
}

/// Copies the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
///
/// If `T` does not implement `Copy`, use [`write_slice_cloned`]
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/slice/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ where

if start_l == end_l {
// Trace `block_l` elements from the left side.
start_l = MaybeUninit::slice_as_mut_ptr(&mut offsets_l);
start_l = offsets_l.as_mut_ptr().cast::<u8>();
end_l = start_l;
let mut elem = l;

Expand All @@ -402,7 +402,7 @@ where

if start_r == end_r {
// Trace `block_r` elements from the right side.
start_r = MaybeUninit::slice_as_mut_ptr(&mut offsets_r);
start_r = offsets_r.as_mut_ptr().cast::<u8>();
end_r = start_r;
let mut elem = r;

Expand Down