Skip to content

Commit 2a91eea

Browse files
committed
Implement core::ptr::Unique on top of NonNull
Removes the use `rustc_layout_scalar_valid_range_start` and some `unsafe` blocks.
1 parent e7575f9 commit 2a91eea

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

library/core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,14 @@
119119
#![feature(const_likely)]
120120
#![feature(const_maybe_uninit_as_mut_ptr)]
121121
#![feature(const_maybe_uninit_assume_init)]
122+
#![feature(const_nonnull_new)]
122123
#![feature(const_num_from_num)]
123124
#![feature(const_ops)]
124125
#![feature(const_option)]
125126
#![feature(const_option_ext)]
126127
#![feature(const_pin)]
127128
#![feature(const_replace)]
129+
#![feature(const_ptr_as_ref)]
128130
#![feature(const_ptr_is_null)]
129131
#![feature(const_ptr_offset_from)]
130132
#![feature(const_ptr_read)]

library/core/src/ptr/unique.rs

+22-19
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::convert::From;
22
use crate::fmt;
33
use crate::marker::{PhantomData, Unsize};
4-
use crate::mem;
54
use crate::ops::{CoerceUnsized, DispatchFromDyn};
5+
use crate::ptr::NonNull;
66

77
/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
88
/// of this wrapper owns the referent. Useful for building abstractions like
@@ -32,9 +32,8 @@ use crate::ops::{CoerceUnsized, DispatchFromDyn};
3232
)]
3333
#[doc(hidden)]
3434
#[repr(transparent)]
35-
#[rustc_layout_scalar_valid_range_start(1)]
3635
pub struct Unique<T: ?Sized> {
37-
pointer: *const T,
36+
pointer: NonNull<T>,
3837
// NOTE: this marker has no consequences for variance, but is necessary
3938
// for dropck to understand that we logically own a `T`.
4039
//
@@ -71,9 +70,7 @@ impl<T: Sized> Unique<T> {
7170
#[must_use]
7271
#[inline]
7372
pub const fn dangling() -> Self {
74-
// SAFETY: mem::align_of() returns a valid, non-null pointer. The
75-
// conditions to call new_unchecked() are thus respected.
76-
unsafe { Unique::new_unchecked(crate::ptr::invalid_mut::<T>(mem::align_of::<T>())) }
73+
Self::from(NonNull::dangling())
7774
}
7875
}
7976

@@ -87,15 +84,14 @@ impl<T: ?Sized> Unique<T> {
8784
#[inline]
8885
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
8986
// SAFETY: the caller must guarantee that `ptr` is non-null.
90-
unsafe { Unique { pointer: ptr as _, _marker: PhantomData } }
87+
unsafe { Unique { pointer: NonNull::new_unchecked(ptr), _marker: PhantomData } }
9188
}
9289

9390
/// Creates a new `Unique` if `ptr` is non-null.
9491
#[inline]
9592
pub const fn new(ptr: *mut T) -> Option<Self> {
96-
if !ptr.is_null() {
97-
// SAFETY: The pointer has already been checked and is not null.
98-
Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
93+
if let Some(pointer) = NonNull::new(ptr) {
94+
Some(Unique { pointer, _marker: PhantomData })
9995
} else {
10096
None
10197
}
@@ -105,7 +101,7 @@ impl<T: ?Sized> Unique<T> {
105101
#[must_use = "`self` will be dropped if the result is not used"]
106102
#[inline]
107103
pub const fn as_ptr(self) -> *mut T {
108-
self.pointer as *mut T
104+
self.pointer.as_ptr()
109105
}
110106

111107
/// Dereferences the content.
@@ -118,7 +114,7 @@ impl<T: ?Sized> Unique<T> {
118114
pub const unsafe fn as_ref(&self) -> &T {
119115
// SAFETY: the caller must guarantee that `self` meets all the
120116
// requirements for a reference.
121-
unsafe { &*self.as_ptr() }
117+
unsafe { self.pointer.as_ref() }
122118
}
123119

124120
/// Mutably dereferences the content.
@@ -131,17 +127,14 @@ impl<T: ?Sized> Unique<T> {
131127
pub const unsafe fn as_mut(&mut self) -> &mut T {
132128
// SAFETY: the caller must guarantee that `self` meets all the
133129
// requirements for a mutable reference.
134-
unsafe { &mut *self.as_ptr() }
130+
unsafe { self.pointer.as_mut() }
135131
}
136132

137133
/// Casts to a pointer of another type.
138134
#[must_use = "`self` will be dropped if the result is not used"]
139135
#[inline]
140136
pub const fn cast<U>(self) -> Unique<U> {
141-
// SAFETY: Unique::new_unchecked() creates a new unique and needs
142-
// the given pointer to not be null.
143-
// Since we are passing self as a pointer, it cannot be null.
144-
unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) }
137+
Unique::from(self.pointer.cast())
145138
}
146139
}
147140

@@ -184,7 +177,17 @@ impl<T: ?Sized> const From<&mut T> for Unique<T> {
184177
/// This conversion is infallible since references cannot be null.
185178
#[inline]
186179
fn from(reference: &mut T) -> Self {
187-
// SAFETY: A mutable reference cannot be null
188-
unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
180+
Self::from(NonNull::from(reference))
181+
}
182+
}
183+
184+
#[unstable(feature = "ptr_internals", issue = "none")]
185+
impl<T: ?Sized> const From<NonNull<T>> for Unique<T> {
186+
/// Converts a `NonNull<T>` to a `Unique<T>`.
187+
///
188+
/// This conversion is infallible since `NonNull` cannot be null.
189+
#[inline]
190+
fn from(pointer: NonNull<T>) -> Self {
191+
Unique { pointer, _marker: PhantomData }
189192
}
190193
}

0 commit comments

Comments
 (0)