33//! In order to utilize the pointer packing, you must have two types: a pointer,
44//! and a tag.
55//!
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 .
1010//!
11- //! Many common pointer types already implement the `Pointer` trait.
11+ //! Many common pointer types already implement the [ `Pointer`] trait.
1212//!
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.
1517
1618use std:: ops:: Deref ;
1719use std:: ptr:: NonNull ;
@@ -71,32 +73,66 @@ pub unsafe trait Pointer: Deref {
7173 /// [`Self::Target`]: Deref::Target
7274 const BITS : usize ;
7375
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
7485 fn into_ptr ( self ) -> NonNull < Self :: Target > ;
7586
87+ /// Re-creates the original pointer, from a raw pointer returned by [`into_ptr`].
88+ ///
7689 /// # Safety
7790 ///
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.
7995 ///
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
8298 unsafe fn from_ptr ( ptr : NonNull < Self :: Target > ) -> Self ;
8399}
84100
85- /// This describes tags that the `TaggedPtr` struct can hold.
101+ /// This describes tags that the [ `TaggedPtr`] struct can hold.
86102///
87103/// # Safety
88104///
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.
90108///
91- /// No more than `BITS` least significant bits may be set in the returned usize.
109+ /// [ `BITS`]: Tag::BITS
92110pub 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
93116 const BITS : usize ;
94117
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
95127 fn into_usize ( self ) -> usize ;
96128
129+ /// Re-creates the tag from the integer returned by [`into_usize`].
130+ ///
97131 /// # Safety
98132 ///
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
100136 unsafe fn from_usize ( tag : usize ) -> Self ;
101137}
102138
@@ -111,6 +147,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
111147
112148 #[ inline]
113149 unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
150+ // Safety: `ptr` comes from `into_ptr` which calls `Box::into_raw`
114151 Box :: from_raw ( ptr. as_ptr ( ) )
115152 }
116153}
@@ -120,11 +157,13 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
120157
121158 #[ inline]
122159 fn into_ptr ( self ) -> NonNull < T > {
160+ // Safety: pointers from `Rc::into_raw` are valid & non-null
123161 unsafe { NonNull :: new_unchecked ( Rc :: into_raw ( self ) . cast_mut ( ) ) }
124162 }
125163
126164 #[ inline]
127165 unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
166+ // Safety: `ptr` comes from `into_ptr` which calls `Rc::into_raw`
128167 Rc :: from_raw ( ptr. as_ptr ( ) )
129168 }
130169}
@@ -134,11 +173,13 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
134173
135174 #[ inline]
136175 fn into_ptr ( self ) -> NonNull < T > {
176+ // Safety: pointers from `Arc::into_raw` are valid & non-null
137177 unsafe { NonNull :: new_unchecked ( Arc :: into_raw ( self ) . cast_mut ( ) ) }
138178 }
139179
140180 #[ inline]
141181 unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
182+ // Safety: `ptr` comes from `into_ptr` which calls `Arc::into_raw`
142183 Arc :: from_raw ( ptr. as_ptr ( ) )
143184 }
144185}
@@ -153,6 +194,8 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
153194
154195 #[ inline]
155196 unsafe fn from_ptr ( ptr : NonNull < T > ) -> Self {
197+ // Safety:
198+ // `ptr` comes from `into_ptr` which gets the pointer from a reference
156199 ptr. as_ref ( )
157200 }
158201}
@@ -167,6 +210,8 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
167210
168211 #[ inline]
169212 unsafe fn from_ptr ( mut ptr : NonNull < T > ) -> Self {
213+ // Safety:
214+ // `ptr` comes from `into_ptr` which gets the pointer from a reference
170215 ptr. as_mut ( )
171216 }
172217}
0 commit comments