1515
1616use std:: mem:: { self , ManuallyDrop } ;
1717use std:: ops:: Deref ;
18+ use std:: ptr:: NonNull ;
1819use std:: rc:: Rc ;
1920use std:: sync:: Arc ;
2021
@@ -29,21 +30,24 @@ pub use drop::TaggedPtr;
2930///
3031/// # Safety
3132///
32- /// The usize returned from `into_usize` must be a valid, dereferenceable,
33- /// pointer to [`<Self as Deref>::Target`]. Note that pointers to
34- /// [`Self::Target`] must be thin, even though [`Self::Target`] may not be
35- /// `Sized`.
33+ /// The pointer returned from [`into_ptr`] must be a [valid], pointer to
34+ /// [`<Self as Deref>::Target`]. Note that pointers to [`Self::Target`] must be
35+ /// thin, even though [`Self::Target`] may not be `Sized`.
3636///
37- /// Note that the returned pointer from `into_usize` should be castable to `&mut
38- /// <Self as Deref>::Target` if `Self: DerefMut`.
37+ /// Note that if `Self` implements [`DerefMut`] the pointer returned from
38+ /// [`into_ptr`] must be valid for writes (and thus calling [`NonNull::as_mut`]
39+ /// on it must be safe).
3940///
40- /// The BITS constant must be correct. At least `BITS` bits, least-significant,
41- /// must be zero on all returned pointers from `into_usize` .
41+ /// The ` BITS` constant must be correct. At least `BITS` bits, least-significant,
42+ /// must be zero on all pointers returned from [`into_ptr`] .
4243///
4344/// For example, if the alignment of [`Self::Target`] is 2, then `BITS` should be 1.
4445///
46+ /// [`into_ptr`]: Pointer::into_ptr
47+ /// [valid]: std::ptr#safety
4548/// [`<Self as Deref>::Target`]: Deref::Target
4649/// [`Self::Target`]: Deref::Target
50+ /// [`DerefMut`]: std::ops::DerefMut
4751pub unsafe trait Pointer : Deref {
4852 /// Number of unused (always zero) **least significant bits** in this
4953 /// pointer, usually related to the pointees alignment.
@@ -63,15 +67,15 @@ pub unsafe trait Pointer: Deref {
6367 /// [`Self::Target`]: Deref::Target
6468 const BITS : usize ;
6569
66- fn into_usize ( self ) -> usize ;
70+ fn into_ptr ( self ) -> NonNull < Self :: Target > ;
6771
6872 /// # Safety
6973 ///
7074 /// The passed `ptr` must be returned from `into_usize`.
7175 ///
7276 /// This acts as `ptr::read` semantically, it should not be called more than
7377 /// once on non-`Copy` `Pointer`s.
74- unsafe fn from_usize ( ptr : usize ) -> Self ;
78+ unsafe fn from_ptr ( ptr : NonNull < Self :: Target > ) -> Self ;
7579
7680 /// This provides a reference to the `Pointer` itself, rather than the
7781 /// `Deref::Target`. It is used for cases where we want to call methods that
@@ -81,7 +85,7 @@ pub unsafe trait Pointer: Deref {
8185 /// # Safety
8286 ///
8387 /// The passed `ptr` must be returned from `into_usize`.
84- unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : usize , f : F ) -> R ;
88+ unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : NonNull < Self :: Target > , f : F ) -> R ;
8589}
8690
8791/// This describes tags that the `TaggedPtr` struct can hold.
@@ -106,17 +110,18 @@ unsafe impl<T> Pointer for Box<T> {
106110 const BITS : usize = bits_for :: < Self :: Target > ( ) ;
107111
108112 #[ inline]
109- fn into_usize ( self ) -> usize {
110- Box :: into_raw ( self ) as usize
113+ fn into_ptr ( self ) -> NonNull < T > {
114+ // Safety: pointers from `Box::into_raw` are valid & non-null
115+ unsafe { NonNull :: new_unchecked ( Box :: into_raw ( self ) ) }
111116 }
112117
113118 #[ inline]
114- unsafe fn from_usize ( ptr : usize ) -> Self {
115- Box :: from_raw ( ptr as * mut T )
119+ unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
120+ Box :: from_raw ( ptr. as_ptr ( ) )
116121 }
117122
118- unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : usize , f : F ) -> R {
119- let raw = ManuallyDrop :: new ( Self :: from_usize ( ptr) ) ;
123+ unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : NonNull < T > , f : F ) -> R {
124+ let raw = ManuallyDrop :: new ( Self :: from_ptr ( ptr) ) ;
120125 f ( & raw )
121126 }
122127}
@@ -125,17 +130,17 @@ unsafe impl<T> Pointer for Rc<T> {
125130 const BITS : usize = bits_for :: < Self :: Target > ( ) ;
126131
127132 #[ inline]
128- fn into_usize ( self ) -> usize {
129- Rc :: into_raw ( self ) as usize
133+ fn into_ptr ( self ) -> NonNull < T > {
134+ unsafe { NonNull :: new_unchecked ( Rc :: into_raw ( self ) . cast_mut ( ) ) }
130135 }
131136
132137 #[ inline]
133- unsafe fn from_usize ( ptr : usize ) -> Self {
134- Rc :: from_raw ( ptr as * const T )
138+ unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
139+ Rc :: from_raw ( ptr. as_ptr ( ) )
135140 }
136141
137- unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : usize , f : F ) -> R {
138- let raw = ManuallyDrop :: new ( Self :: from_usize ( ptr) ) ;
142+ unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : NonNull < T > , f : F ) -> R {
143+ let raw = ManuallyDrop :: new ( Self :: from_ptr ( ptr) ) ;
139144 f ( & raw )
140145 }
141146}
@@ -144,17 +149,17 @@ unsafe impl<T> Pointer for Arc<T> {
144149 const BITS : usize = bits_for :: < Self :: Target > ( ) ;
145150
146151 #[ inline]
147- fn into_usize ( self ) -> usize {
148- Arc :: into_raw ( self ) as usize
152+ fn into_ptr ( self ) -> NonNull < T > {
153+ unsafe { NonNull :: new_unchecked ( Arc :: into_raw ( self ) . cast_mut ( ) ) }
149154 }
150155
151156 #[ inline]
152- unsafe fn from_usize ( ptr : usize ) -> Self {
153- Arc :: from_raw ( ptr as * const T )
157+ unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
158+ Arc :: from_raw ( ptr. as_ptr ( ) )
154159 }
155160
156- unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : usize , f : F ) -> R {
157- let raw = ManuallyDrop :: new ( Self :: from_usize ( ptr) ) ;
161+ unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : NonNull < T > , f : F ) -> R {
162+ let raw = ManuallyDrop :: new ( Self :: from_ptr ( ptr) ) ;
158163 f ( & raw )
159164 }
160165}
@@ -163,32 +168,35 @@ unsafe impl<'a, T: 'a> Pointer for &'a T {
163168 const BITS : usize = bits_for :: < Self :: Target > ( ) ;
164169
165170 #[ inline]
166- fn into_usize ( self ) -> usize {
167- self as * const T as usize
171+ fn into_ptr ( self ) -> NonNull < T > {
172+ NonNull :: from ( self )
168173 }
169174
170175 #[ inline]
171- unsafe fn from_usize ( ptr : usize ) -> Self {
172- & * ( ptr as * const T )
176+ unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
177+ ptr. as_ref ( )
173178 }
174179
175- unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : usize , f : F ) -> R {
176- f ( & * ( & ptr as * const usize as * const Self ) )
180+ unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : NonNull < T > , f : F ) -> R {
181+ f ( & ptr. as_ref ( ) )
177182 }
178183}
179184
180185unsafe impl < ' a , T : ' a > Pointer for & ' a mut T {
181186 const BITS : usize = bits_for :: < Self :: Target > ( ) ;
187+
182188 #[ inline]
183- fn into_usize ( self ) -> usize {
184- self as * mut T as usize
189+ fn into_ptr ( self ) -> NonNull < T > {
190+ NonNull :: from ( self )
185191 }
192+
186193 #[ inline]
187- unsafe fn from_usize ( ptr : usize ) -> Self {
188- & mut * ( ptr as * mut T )
194+ unsafe fn from_ptr ( mut ptr : NonNull < T > ) -> Self {
195+ ptr. as_mut ( )
189196 }
190- unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( ptr : usize , f : F ) -> R {
191- f ( & * ( & ptr as * const usize as * const Self ) )
197+
198+ unsafe fn with_ref < R , F : FnOnce ( & Self ) -> R > ( mut ptr : NonNull < T > , f : F ) -> R {
199+ f ( & ptr. as_mut ( ) )
192200 }
193201}
194202
0 commit comments