3
3
//! In order to utilize the pointer packing, you must have two types: a pointer,
4
4
//! and a tag.
5
5
//!
6
- //! The pointer must implement the `Pointer` trait, with the primary requirement
7
- //! being conversion to and from a usize . Note that the pointer must be
8
- //! dereferenceable, so raw pointers generally cannot implement the `Pointer`
9
- //! trait. This implies that the pointer must also be nonzero .
6
+ //! The pointer must implement the [ `Pointer`] trait, with the primary
7
+ //! requirement being convertible to and from a raw pointer . Note that the
8
+ //! pointer must be dereferenceable, so raw pointers generally cannot implement
9
+ //! the [`Pointer`] trait. This implies that the pointer must also be non-null .
10
10
//!
11
- //! Many common pointer types already implement the `Pointer` trait.
11
+ //! Many common pointer types already implement the [ `Pointer`] trait.
12
12
//!
13
- //! The tag must implement the `Tag` trait. We assert that the tag and `Pointer`
14
- //! are compatible at compile time.
13
+ //! The tag must implement the [`Tag`] trait.
14
+ //!
15
+ //! We assert that the tag and the [`Pointer`] types are compatible at compile
16
+ //! time.
15
17
16
18
use std:: ops:: Deref ;
17
19
use std:: ptr:: NonNull ;
@@ -71,32 +73,66 @@ pub unsafe trait Pointer: Deref {
71
73
/// [`Self::Target`]: Deref::Target
72
74
const BITS : usize ;
73
75
76
+ /// Turns this pointer into a raw, non-null pointer.
77
+ ///
78
+ /// The inverse of this function is [`from_ptr`].
79
+ ///
80
+ /// This function guarantees that the least-significant [`Self::BITS`] bits
81
+ /// are zero.
82
+ ///
83
+ /// [`from_ptr`]: Pointer::from_ptr
84
+ /// [`Self::BITS`]: Pointer::BITS
74
85
fn into_ptr ( self ) -> NonNull < Self :: Target > ;
75
86
87
+ /// Re-creates the original pointer, from a raw pointer returned by [`into_ptr`].
88
+ ///
76
89
/// # Safety
77
90
///
78
- /// The passed `ptr` must be returned from `into_usize`.
91
+ /// The passed `ptr` must be returned from [`into_ptr`].
92
+ ///
93
+ /// This acts as [`ptr::read::<Self>()`] semantically, it should not be called more than
94
+ /// once on non-[`Copy`] `Pointer`s.
79
95
///
80
- /// This acts as `ptr::read` semantically, it should not be called more than
81
- /// once on non-`Copy` `Pointer`s.
96
+ /// [`into_ptr`]: Pointer::into_ptr
97
+ /// [`ptr::read::<Self>()`]: std::ptr::read
82
98
unsafe fn from_ptr ( ptr : NonNull < Self :: Target > ) -> Self ;
83
99
}
84
100
85
- /// This describes tags that the `TaggedPtr` struct can hold.
101
+ /// This describes tags that the [ `TaggedPtr`] struct can hold.
86
102
///
87
103
/// # Safety
88
104
///
89
- /// The BITS constant must be correct.
105
+ /// The [`BITS`] constant must be correct.
106
+ ///
107
+ /// No more than [`BITS`] least significant bits may be set in the returned usize.
90
108
///
91
- /// No more than `BITS` least significant bits may be set in the returned usize.
109
+ /// [ `BITS`]: Tag::BITS
92
110
pub unsafe trait Tag : Copy {
111
+ /// Number of least-significant bits in the return value of [`into_usize`]
112
+ /// which may be non-zero. In other words this is the bit width of the
113
+ /// value.
114
+ ///
115
+ /// [`into_usize`]: Tag::into_usize
93
116
const BITS : usize ;
94
117
118
+ /// Turns this tag into an integer.
119
+ ///
120
+ /// The inverse of this function is [`from_usize`].
121
+ ///
122
+ /// This function guarantees that only the least-significant [`Self::BITS`]
123
+ /// bits can be non-zero.
124
+ ///
125
+ /// [`from_usize`]: Pointer::from_usize
126
+ /// [`Self::BITS`]: Tag::BITS
95
127
fn into_usize ( self ) -> usize ;
96
128
129
+ /// Re-creates the tag from the integer returned by [`into_usize`].
130
+ ///
97
131
/// # Safety
98
132
///
99
- /// The passed `tag` must be returned from `into_usize`.
133
+ /// The passed `tag` must be returned from [`into_usize`].
134
+ ///
135
+ /// [`into_usize`]: Tag::into_usize
100
136
unsafe fn from_usize ( tag : usize ) -> Self ;
101
137
}
102
138
@@ -111,6 +147,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
111
147
112
148
#[ inline]
113
149
unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
150
+ // Safety: `ptr` comes from `into_ptr` which calls `Box::into_raw`
114
151
Box :: from_raw ( ptr. as_ptr ( ) )
115
152
}
116
153
}
@@ -120,11 +157,13 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
120
157
121
158
#[ inline]
122
159
fn into_ptr ( self ) -> NonNull < T > {
160
+ // Safety: pointers from `Rc::into_raw` are valid & non-null
123
161
unsafe { NonNull :: new_unchecked ( Rc :: into_raw ( self ) . cast_mut ( ) ) }
124
162
}
125
163
126
164
#[ inline]
127
165
unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
166
+ // Safety: `ptr` comes from `into_ptr` which calls `Rc::into_raw`
128
167
Rc :: from_raw ( ptr. as_ptr ( ) )
129
168
}
130
169
}
@@ -134,11 +173,13 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
134
173
135
174
#[ inline]
136
175
fn into_ptr ( self ) -> NonNull < T > {
176
+ // Safety: pointers from `Arc::into_raw` are valid & non-null
137
177
unsafe { NonNull :: new_unchecked ( Arc :: into_raw ( self ) . cast_mut ( ) ) }
138
178
}
139
179
140
180
#[ inline]
141
181
unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
182
+ // Safety: `ptr` comes from `into_ptr` which calls `Arc::into_raw`
142
183
Arc :: from_raw ( ptr. as_ptr ( ) )
143
184
}
144
185
}
@@ -153,6 +194,8 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
153
194
154
195
#[ inline]
155
196
unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
197
+ // Safety:
198
+ // `ptr` comes from `into_ptr` which gets the pointer from a reference
156
199
ptr. as_ref ( )
157
200
}
158
201
}
@@ -167,6 +210,8 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
167
210
168
211
#[ inline]
169
212
unsafe fn from_ptr ( mut ptr : NonNull < T > ) -> Self {
213
+ // Safety:
214
+ // `ptr` comes from `into_ptr` which gets the pointer from a reference
170
215
ptr. as_mut ( )
171
216
}
172
217
}
0 commit comments