rustc_data_structures/
intern.rs1use std::cmp::Ordering;
2use std::fmt::{self, Debug};
3use std::hash::{Hash, Hasher};
4use std::ops::Deref;
5use std::ptr;
6
7use crate::stable_hasher::{HashStable, StableHasher};
8
9mod private {
10 #[derive(Clone, Copy, Debug)]
11 pub struct PrivateZst;
12}
13
14#[rustc_pass_by_value]
26pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst);
27
28impl<'a, T> Interned<'a, T> {
29 #[inline]
35 pub const fn new_unchecked(t: &'a T) -> Self {
36 Interned(t, private::PrivateZst)
37 }
38}
39
40impl<'a, T> Clone for Interned<'a, T> {
41 fn clone(&self) -> Self {
42 *self
43 }
44}
45
46impl<'a, T> Copy for Interned<'a, T> {}
47
48impl<'a, T> Deref for Interned<'a, T> {
49 type Target = T;
50
51 #[inline]
52 fn deref(&self) -> &T {
53 self.0
54 }
55}
56
57impl<'a, T> PartialEq for Interned<'a, T> {
58 #[inline]
59 fn eq(&self, other: &Self) -> bool {
60 ptr::eq(self.0, other.0)
62 }
63}
64
65impl<'a, T> Eq for Interned<'a, T> {}
66
67impl<'a, T: PartialOrd> PartialOrd for Interned<'a, T> {
68 fn partial_cmp(&self, other: &Interned<'a, T>) -> Option<Ordering> {
69 if ptr::eq(self.0, other.0) {
72 Some(Ordering::Equal)
73 } else {
74 let res = self.0.partial_cmp(other.0);
75 debug_assert_ne!(res, Some(Ordering::Equal));
76 res
77 }
78 }
79}
80
81impl<'a, T: Ord> Ord for Interned<'a, T> {
82 fn cmp(&self, other: &Interned<'a, T>) -> Ordering {
83 if ptr::eq(self.0, other.0) {
86 Ordering::Equal
87 } else {
88 let res = self.0.cmp(other.0);
89 debug_assert_ne!(res, Ordering::Equal);
90 res
91 }
92 }
93}
94
95impl<'a, T> Hash for Interned<'a, T>
96where
97 T: Hash,
98{
99 #[inline]
100 fn hash<H: Hasher>(&self, s: &mut H) {
101 ptr::hash(self.0, s)
103 }
104}
105
106impl<T, CTX> HashStable<CTX> for Interned<'_, T>
107where
108 T: HashStable<CTX>,
109{
110 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
111 self.0.hash_stable(hcx, hasher);
112 }
113}
114
115impl<T: Debug> Debug for Interned<'_, T> {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 self.0.fmt(f)
118 }
119}
120
121#[cfg(test)]
122mod tests;