3333 /// those are embeddable in instruction encoding, for example:
3434 ///
3535 /// ```asm
36- /// // (https://godbolt.org/z/jqcYPWEr3)
36+ /// // (< https://godbolt.org/z/jqcYPWEr3> )
3737 /// example::shift_read3:
3838 /// mov eax, dword ptr [8*rdi]
3939 /// ret
4949 /// - `shift_read3` uses `<< 3` (the tag is in the most-significant bits)
5050 /// - `mask_read3` uses `& !0b111` (the tag is in the least-significant bits)
5151 ///
52- /// The shift approach thus produces less instructions and is likely faster.
52+ /// The shift approach thus produces less instructions and is likely faster
53+ /// (see <https://godbolt.org/z/Y913sMdWb>).
5354 ///
5455 /// Encoding diagram:
5556 /// ```text
@@ -66,12 +67,21 @@ where
6667 tag_ghost : PhantomData < T > ,
6768}
6869
70+ // Note that even though `CopyTaggedPtr` is only really expected to work with
71+ // `P: Copy`, can't add `P: Copy` bound, because `CopyTaggedPtr` is used in the
72+ // `TaggedPtr`'s implementation.
6973impl < P , T , const CP : bool > CopyTaggedPtr < P , T , CP >
7074where
7175 P : Pointer ,
7276 T : Tag ,
7377{
7478 /// Tags `pointer` with `tag`.
79+ ///
80+ /// Note that this leaks `pointer`: it won't be dropped when
81+ /// `CopyTaggedPtr` is dropped. If you have a pointer with a significant
82+ /// drop, use [`TaggedPtr`] instead.
83+ ///
84+ /// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr
7585 pub fn new ( pointer : P , tag : T ) -> Self {
7686 Self { packed : Self :: pack ( P :: into_ptr ( pointer) , tag) , tag_ghost : PhantomData }
7787 }
95105 let tag = self . packed . addr ( ) . get ( ) >> Self :: TAG_BIT_SHIFT ;
96106
97107 // Safety:
98- //
108+ // The shift retrieves the original value from `T::into_usize`,
109+ // satisfying `T::from_usize`'s preconditions.
99110 unsafe { T :: from_usize ( tag) }
100111 }
101112
@@ -152,6 +163,10 @@ where
152163 //
153164 // Semantically this is just `f(&self.pointer)` (where `self.pointer`
154165 // is non-packed original pointer).
166+ //
167+ // Note that even though `CopyTaggedPtr` is only really expected to
168+ // work with `P: Copy`, we have to assume `P: ?Copy`, because
169+ // `CopyTaggedPtr` is used in the `TaggedPtr`'s implementation.
155170 let ptr = unsafe { ManuallyDrop :: new ( P :: from_ptr ( self . pointer_raw ( ) ) ) } ;
156171 f ( & ptr)
157172 }
0 commit comments