]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_data_structures/src/tagged_ptr/drop.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / compiler / rustc_data_structures / src / tagged_ptr / drop.rs
CommitLineData
3dfed10e
XL
1use super::{Pointer, Tag};
2use crate::stable_hasher::{HashStable, StableHasher};
3use std::fmt;
4
5use super::CopyTaggedPtr;
6
7/// A TaggedPtr implementing `Drop`.
8///
9/// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without
10/// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that,
11/// wrap the TaggedPtr.
12pub struct TaggedPtr<P, T, const COMPARE_PACKED: bool>
13where
14 P: Pointer,
15 T: Tag,
16{
17 raw: CopyTaggedPtr<P, T, COMPARE_PACKED>,
18}
19
20impl<P, T, const COMPARE_PACKED: bool> Clone for TaggedPtr<P, T, COMPARE_PACKED>
21where
22 P: Pointer + Clone,
23 T: Tag,
24{
25 fn clone(&self) -> Self {
26 unsafe { Self::new(P::with_ref(self.raw.pointer_raw(), |p| p.clone()), self.raw.tag()) }
27 }
28}
29
30// We pack the tag into the *upper* bits of the pointer to ease retrieval of the
31// value; a right shift is a multiplication and those are embeddable in
32// instruction encoding.
33impl<P, T, const COMPARE_PACKED: bool> TaggedPtr<P, T, COMPARE_PACKED>
34where
35 P: Pointer,
36 T: Tag,
37{
38 pub fn new(pointer: P, tag: T) -> Self {
39 TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) }
40 }
41
42 pub fn pointer_ref(&self) -> &P::Target {
43 self.raw.pointer_ref()
44 }
3dfed10e
XL
45 pub fn tag(&self) -> T {
46 self.raw.tag()
47 }
3dfed10e
XL
48}
49
50impl<P, T, const COMPARE_PACKED: bool> std::ops::Deref for TaggedPtr<P, T, COMPARE_PACKED>
51where
52 P: Pointer,
53 T: Tag,
54{
55 type Target = P::Target;
56 fn deref(&self) -> &Self::Target {
57 self.raw.pointer_ref()
58 }
59}
60
61impl<P, T, const COMPARE_PACKED: bool> std::ops::DerefMut for TaggedPtr<P, T, COMPARE_PACKED>
62where
63 P: Pointer + std::ops::DerefMut,
64 T: Tag,
65{
66 fn deref_mut(&mut self) -> &mut Self::Target {
67 self.raw.pointer_mut()
68 }
69}
70
71impl<P, T, const COMPARE_PACKED: bool> Drop for TaggedPtr<P, T, COMPARE_PACKED>
72where
73 P: Pointer,
74 T: Tag,
75{
76 fn drop(&mut self) {
77 // No need to drop the tag, as it's Copy
78 unsafe {
9c376795 79 drop(P::from_usize(self.raw.pointer_raw()));
3dfed10e
XL
80 }
81 }
82}
83
84impl<P, T, const COMPARE_PACKED: bool> fmt::Debug for TaggedPtr<P, T, COMPARE_PACKED>
85where
86 P: Pointer,
87 P::Target: fmt::Debug,
88 T: Tag + fmt::Debug,
89{
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 f.debug_struct("TaggedPtr")
92 .field("pointer", &self.pointer_ref())
93 .field("tag", &self.tag())
94 .finish()
95 }
96}
97
98impl<P, T> PartialEq for TaggedPtr<P, T, true>
99where
100 P: Pointer,
101 T: Tag,
102{
103 fn eq(&self, other: &Self) -> bool {
104 self.raw.eq(&other.raw)
105 }
106}
107
108impl<P, T> Eq for TaggedPtr<P, T, true>
109where
110 P: Pointer,
111 T: Tag,
112{
113}
114
115impl<P, T> std::hash::Hash for TaggedPtr<P, T, true>
116where
117 P: Pointer,
118 T: Tag,
119{
120 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
121 self.raw.hash(state);
122 }
123}
124
125impl<P, T, HCX, const COMPARE_PACKED: bool> HashStable<HCX> for TaggedPtr<P, T, COMPARE_PACKED>
126where
127 P: Pointer + HashStable<HCX>,
128 T: Tag + HashStable<HCX>,
129{
130 fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
131 self.raw.hash_stable(hcx, hasher);
132 }
133}