diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-10 13:00:45 -0800 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-15 22:17:57 -0800 |
| commit | c18718c9c28cc4c700312775c2b7f87cd79d3063 (patch) | |
| tree | 7a2b8e3faab3a4a953a2f6af19c7afe6d27f2397 /library/core/src | |
| parent | 5cd16b7f2bc3624f2d658aa87151279878d2652a (diff) | |
| download | rust-c18718c9c28cc4c700312775c2b7f87cd79d3063.tar.gz rust-c18718c9c28cc4c700312775c2b7f87cd79d3063.zip | |
Less unsafe in `dangling`/`without_provenance`
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/ptr/alignment.rs | 12 | ||||
| -rw-r--r-- | library/core/src/ptr/mod.rs | 11 | ||||
| -rw-r--r-- | library/core/src/ptr/non_null.rs | 16 |
3 files changed, 19 insertions, 20 deletions
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 74a1d40f4e7..2da94e72566 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -42,9 +42,10 @@ impl Alignment { /// but in an `Alignment` instead of a `usize`. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[must_use] pub const fn of<T>() -> Self { - // SAFETY: rustc ensures that type alignment is always a power of two. - unsafe { Alignment::new_unchecked(mem::align_of::<T>()) } + // This can't actually panic since type alignment is always a power of two. + const { Alignment::new(mem::align_of::<T>()).unwrap() } } /// Creates an `Alignment` from a `usize`, or returns `None` if it's @@ -95,8 +96,13 @@ impl Alignment { #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] pub const fn as_nonzero(self) -> NonZero<usize> { + // This transmutes directly to avoid the UbCheck in `NonZero::new_unchecked` + // since there's no way for the user to trip that check anyway -- the + // validity invariant of the type would have to have been broken earlier -- + // and emitting it in an otherwise simple method is bad for compile time. + // SAFETY: All the discriminants are non-zero. - unsafe { NonZero::new_unchecked(self.as_usize()) } + unsafe { mem::transmute::<Alignment, NonZero<usize>>(self) } } /// Returns the base-2 logarithm of the alignment. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index f58c0e12411..e1348552b65 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -596,12 +596,7 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T { #[stable(feature = "strict_provenance", since = "1.84.0")] #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn without_provenance<T>(addr: usize) -> *const T { - // An int-to-pointer transmute currently has exactly the intended semantics: it creates a - // pointer without provenance. Note that this is *not* a stable guarantee about transmute - // semantics, it relies on sysroot crates having special status. - // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that - // pointer). - unsafe { mem::transmute(addr) } + without_provenance_mut(addr) } /// Creates a new pointer that is dangling, but non-null and well-aligned. @@ -618,7 +613,7 @@ pub const fn without_provenance<T>(addr: usize) -> *const T { #[stable(feature = "strict_provenance", since = "1.84.0")] #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn dangling<T>() -> *const T { - without_provenance(mem::align_of::<T>()) + dangling_mut() } /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance]. @@ -661,7 +656,7 @@ pub const fn without_provenance_mut<T>(addr: usize) -> *mut T { #[stable(feature = "strict_provenance", since = "1.84.0")] #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")] pub const fn dangling_mut<T>() -> *mut T { - without_provenance_mut(mem::align_of::<T>()) + NonNull::dangling().as_ptr() } /// Converts an address back to a pointer, picking up some previously 'exposed' diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 2c9131254f7..d93069d384e 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -91,12 +91,12 @@ impl<T: Sized> NonNull<T> { /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. #[unstable(feature = "nonnull_provenance", issue = "135243")] + #[must_use] + #[inline] pub const fn without_provenance(addr: NonZero<usize>) -> Self { + let pointer = crate::ptr::without_provenance(addr.get()); // SAFETY: we know `addr` is non-zero. - unsafe { - let ptr = crate::ptr::without_provenance_mut(addr.get()); - NonNull::new_unchecked(ptr) - } + unsafe { NonNull { pointer } } } /// Creates a new `NonNull` that is dangling, but well-aligned. @@ -123,11 +123,8 @@ impl<T: Sized> NonNull<T> { #[must_use] #[inline] pub const fn dangling() -> Self { - // SAFETY: ptr::dangling_mut() returns a non-null well-aligned pointer. - unsafe { - let ptr = crate::ptr::dangling_mut::<T>(); - NonNull::new_unchecked(ptr) - } + let align = crate::ptr::Alignment::of::<T>(); + NonNull::without_provenance(align.as_nonzero()) } /// Converts an address back to a mutable pointer, picking up some previously 'exposed' @@ -137,6 +134,7 @@ impl<T: Sized> NonNull<T> { /// /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. #[unstable(feature = "nonnull_provenance", issue = "135243")] + #[inline] pub fn with_exposed_provenance(addr: NonZero<usize>) -> Self { // SAFETY: we know `addr` is non-zero. unsafe { |
