From f2e9b40b8a2cca1c6a4c28eeac0eb5cfdfb1a3f3 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Sun, 16 Oct 2022 20:25:43 -0700 Subject: [PATCH 1/3] Nuke slice_as{,_mut}_ptr methods Signed-off-by: Alex Saveau --- compiler/rustc_serialize/src/opaque.rs | 4 +-- library/core/src/fmt/num.rs | 43 ++++++++++---------------- library/core/src/mem/maybe_uninit.rs | 38 +++++++++++++---------- library/core/src/slice/sort.rs | 4 +-- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 0ffc537eee02a..3461f191b030d 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -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; @@ -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.get_unchecked_mut(buffered).as_mut_ptr(); ptr::copy_nonoverlapping(src, dst, buf_len); } diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 4f42f73ebbaff..6396232fbae18 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -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().into_inner(), buf.len())) }; f.pad_integral(is_nonnegative, Self::PREFIX, buf) } @@ -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::::uninit(); 39]; let mut curr = buf.len(); - let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf); + let buf_ptr = buf.as_mut_ptr().into_inner(); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); // SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we @@ -344,7 +341,7 @@ macro_rules! impl_Exp { // that `curr >= 0`. let mut buf = [MaybeUninit::::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().into_inner(); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); // decode 2 chars at a time @@ -392,20 +389,19 @@ macro_rules! impl_Exp { // stores 'e' (or 'E') and the up to 2-digit exponent let mut exp_buf = [MaybeUninit::::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[1].as_mut_ptr(), 2); } 3 }; - slice::from_raw_parts(exp_ptr, len) + // SAFETY: max(2, 3) <= 3 + unsafe { slice::from_raw_parts(exp_buf.as_mut_ptr().into_inner(), len) } }; let parts = &[ @@ -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(mut n: u64, buf: &mut [MaybeUninit; N], curr: &mut usize) { - let buf_ptr = MaybeUninit::slice_as_mut_ptr(buf); + let buf_ptr = buf.as_mut_ptr().into_inner(); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); assert!(*curr > 19); @@ -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[target].as_mut_ptr(), b'0', curr - target); } curr = target; @@ -622,16 +614,13 @@ 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[target].as_mut_ptr(), b'0', curr - target); } + curr = target - 1; + buf[curr].write((n as u8) + b'0'); } } @@ -639,7 +628,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // 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.get_unchecked_mut(curr).as_mut_ptr(), buf.len() - curr, )) }; diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index d09a24b4b1d5b..2520408f51d81 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -993,22 +993,6 @@ impl MaybeUninit { 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]) -> *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]) -> *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`] @@ -1310,3 +1294,25 @@ impl [MaybeUninit; N] { unsafe { intrinsics::transmute_unchecked(self) } } } + +impl *const MaybeUninit { + /// Converts a MaybeUninit pointer to its underlying type. + /// + /// See [`MaybeUninit::as_ptr`] for caveats. + #[unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] + pub const fn into_inner(self) -> *const T { + self.cast() + } +} + +impl *mut MaybeUninit { + /// Converts mutable a MaybeUninit pointer to its underlying type. + /// + /// See [`MaybeUninit::as_mut_ptr`] for caveats. + #[unstable(feature = "maybe_uninit_slice", issue = "63569")] + #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] + pub const fn into_inner(self) -> *mut T { + self.cast() + } +} diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index db76d26257aac..cfca6ef6f29dc 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -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().into_inner(); end_l = start_l; let mut elem = l; @@ -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().into_inner(); end_r = start_r; let mut elem = r; From cc186940b4bc70d422d8bfd09adeae93b14a1273 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Sat, 17 Jun 2023 12:39:50 -0700 Subject: [PATCH 2/3] Add hacks to work around stacked borrows (revert after tree borrows) Signed-off-by: Alex Saveau --- compiler/rustc_serialize/src/opaque.rs | 2 +- library/core/src/fmt/num.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 3461f191b030d..2c4482d4f2606 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -182,7 +182,7 @@ impl FileEncoder { // room to write the input to the buffer. unsafe { let src = buf.as_ptr(); - let dst = self.buf.get_unchecked_mut(buffered).as_mut_ptr(); + let dst = self.buf.as_mut_ptr().add(buffered).into_inner(); ptr::copy_nonoverlapping(src, dst, buf_len); } diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 6396232fbae18..48a903fbb75d5 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -397,7 +397,7 @@ macro_rules! impl_Exp { } else { let off = exponent << 1; // SAFETY: 1 + 2 <= 3 - unsafe { ptr::copy_nonoverlapping(lut_ptr.add(off), exp_buf[1].as_mut_ptr(), 2); } + unsafe { ptr::copy_nonoverlapping(lut_ptr.add(off), exp_buf.as_mut_ptr().into_inner().add(1), 2); } 3 }; // SAFETY: max(2, 3) <= 3 @@ -605,7 +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(buf[target].as_mut_ptr(), b'0', curr - target); + ptr::write_bytes(buf.as_mut_ptr().add(target), b'0', curr - target); } curr = target; @@ -617,7 +617,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // 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[target].as_mut_ptr(), b'0', curr - target); + ptr::write_bytes(buf.as_mut_ptr().add(target), b'0', curr - target); } curr = target - 1; buf[curr].write((n as u8) + b'0'); @@ -628,7 +628,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // UTF-8 since `DEC_DIGITS_LUT` is let buf_slice = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( - buf.get_unchecked_mut(curr).as_mut_ptr(), + buf.as_mut_ptr().add(curr).into_inner(), buf.len() - curr, )) }; From b602bbf9adae05f27842447ddc24c8d79b72f39d Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Tue, 27 Jun 2023 10:55:28 -0700 Subject: [PATCH 3/3] Remove type safe MaybeUninit ptr conversion Signed-off-by: Alex Saveau --- compiler/rustc_serialize/src/opaque.rs | 2 +- library/core/src/fmt/num.rs | 14 +++++++------- library/core/src/mem/maybe_uninit.rs | 22 ---------------------- library/core/src/slice/sort.rs | 4 ++-- 4 files changed, 10 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 2c4482d4f2606..b93572d49d65c 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -182,7 +182,7 @@ impl FileEncoder { // room to write the input to the buffer. unsafe { let src = buf.as_ptr(); - let dst = self.buf.as_mut_ptr().add(buffered).into_inner(); + let dst = self.buf.as_mut_ptr().add(buffered).cast::(); ptr::copy_nonoverlapping(src, dst, buf_len); } diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 48a903fbb75d5..e4a6d7de67076 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -106,7 +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(buf.as_ptr().into_inner(), buf.len())) + str::from_utf8_unchecked(slice::from_raw_parts(buf.as_ptr().cast::(), buf.len())) }; f.pad_integral(is_nonnegative, Self::PREFIX, buf) } @@ -213,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::::uninit(); 39]; let mut curr = buf.len(); - let buf_ptr = buf.as_mut_ptr().into_inner(); + let buf_ptr = buf.as_mut_ptr().cast::(); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); // SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we @@ -341,7 +341,7 @@ macro_rules! impl_Exp { // that `curr >= 0`. let mut buf = [MaybeUninit::::uninit(); 40]; let mut curr = buf.len(); //index for buf - let buf_ptr = buf.as_mut_ptr().into_inner(); + let buf_ptr = buf.as_mut_ptr().cast::(); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); // decode 2 chars at a time @@ -397,11 +397,11 @@ macro_rules! impl_Exp { } else { let off = exponent << 1; // SAFETY: 1 + 2 <= 3 - unsafe { ptr::copy_nonoverlapping(lut_ptr.add(off), exp_buf.as_mut_ptr().into_inner().add(1), 2); } + unsafe { ptr::copy_nonoverlapping(lut_ptr.add(off), exp_buf.as_mut_ptr().add(1).cast::(), 2); } 3 }; // SAFETY: max(2, 3) <= 3 - unsafe { slice::from_raw_parts(exp_buf.as_mut_ptr().into_inner(), len) } + unsafe { slice::from_raw_parts(exp_buf.as_mut_ptr().cast::(), len) } }; let parts = &[ @@ -481,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(mut n: u64, buf: &mut [MaybeUninit; N], curr: &mut usize) { - let buf_ptr = buf.as_mut_ptr().into_inner(); + let buf_ptr = buf.as_mut_ptr().cast::(); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); assert!(*curr > 19); @@ -628,7 +628,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // UTF-8 since `DEC_DIGITS_LUT` is let buf_slice = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( - buf.as_mut_ptr().add(curr).into_inner(), + buf.as_mut_ptr().add(curr).cast::(), buf.len() - curr, )) }; diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 2520408f51d81..fdd18d0078a0d 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1294,25 +1294,3 @@ impl [MaybeUninit; N] { unsafe { intrinsics::transmute_unchecked(self) } } } - -impl *const MaybeUninit { - /// Converts a MaybeUninit pointer to its underlying type. - /// - /// See [`MaybeUninit::as_ptr`] for caveats. - #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] - pub const fn into_inner(self) -> *const T { - self.cast() - } -} - -impl *mut MaybeUninit { - /// Converts mutable a MaybeUninit pointer to its underlying type. - /// - /// See [`MaybeUninit::as_mut_ptr`] for caveats. - #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] - pub const fn into_inner(self) -> *mut T { - self.cast() - } -} diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index cfca6ef6f29dc..076378cd4a66c 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -376,7 +376,7 @@ where if start_l == end_l { // Trace `block_l` elements from the left side. - start_l = offsets_l.as_mut_ptr().into_inner(); + start_l = offsets_l.as_mut_ptr().cast::(); end_l = start_l; let mut elem = l; @@ -402,7 +402,7 @@ where if start_r == end_r { // Trace `block_r` elements from the right side. - start_r = offsets_r.as_mut_ptr().into_inner(); + start_r = offsets_r.as_mut_ptr().cast::(); end_r = start_r; let mut elem = r;