1 use crate::stable_hasher
::{HashStable, StableHasher}
;
2 use std
::cmp
::Ordering
;
3 use std
::hash
::{Hash, Hasher}
;
8 #[derive(Clone, Copy, Debug)]
12 /// A reference to a value that is interned, and is known to be unique.
14 /// Note that it is possible to have a `T` and a `Interned<T>` that are (or
15 /// refer to) equal but different values. But if you have two different
16 /// `Interned<T>`s, they both refer to the same value, at a single location in
17 /// memory. This means that equality and hashing can be done on the value's
18 /// address rather than the value's contents, which can improve performance.
20 /// The `PrivateZst` field means you can pattern match with `Interned(v, _)`
21 /// but you can only construct a `Interned` with `new_unchecked`, and not
24 #[rustc_pass_by_value]
25 pub struct Interned
<'a
, T
>(pub &'a T
, pub private
::PrivateZst
);
27 impl<'a
, T
> Interned
<'a
, T
> {
28 /// Create a new `Interned` value. The value referred to *must* be interned
29 /// and thus be unique, and it *must* remain unique in the future. This
30 /// function has `_unchecked` in the name but is not `unsafe`, because if
31 /// the uniqueness condition is violated condition it will cause incorrect
32 /// behaviour but will not affect memory safety.
34 pub const fn new_unchecked(t
: &'a T
) -> Self {
35 Interned(t
, private
::PrivateZst
)
39 impl<'a
, T
> Clone
for Interned
<'a
, T
> {
40 fn clone(&self) -> Self {
45 impl<'a
, T
> Copy
for Interned
<'a
, T
> {}
47 impl<'a
, T
> Deref
for Interned
<'a
, T
> {
51 fn deref(&self) -> &T
{
56 impl<'a
, T
> PartialEq
for Interned
<'a
, T
> {
58 fn eq(&self, other
: &Self) -> bool
{
59 // Pointer equality implies equality, due to the uniqueness constraint.
60 ptr
::eq(self.0, other
.0)
64 impl<'a
, T
> Eq
for Interned
<'a
, T
> {}
66 impl<'a
, T
: PartialOrd
> PartialOrd
for Interned
<'a
, T
> {
67 fn partial_cmp(&self, other
: &Interned
<'a
, T
>) -> Option
<Ordering
> {
68 // Pointer equality implies equality, due to the uniqueness constraint,
69 // but the contents must be compared otherwise.
70 if ptr
::eq(self.0, other
.0) {
73 let res
= self.0.partial_cmp(other
.0);
74 debug_assert_ne
!(res
, Some(Ordering
::Equal
));
80 impl<'a
, T
: Ord
> Ord
for Interned
<'a
, T
> {
81 fn cmp(&self, other
: &Interned
<'a
, T
>) -> Ordering
{
82 // Pointer equality implies equality, due to the uniqueness constraint,
83 // but the contents must be compared otherwise.
84 if ptr
::eq(self.0, other
.0) {
87 let res
= self.0.cmp(other
.0);
88 debug_assert_ne
!(res
, Ordering
::Equal
);
94 impl<'a
, T
> Hash
for Interned
<'a
, T
> {
96 fn hash
<H
: Hasher
>(&self, s
: &mut H
) {
97 // Pointer hashing is sufficient, due to the uniqueness constraint.
102 impl<T
, CTX
> HashStable
<CTX
> for Interned
<'_
, T
>
106 fn hash_stable(&self, hcx
: &mut CTX
, hasher
: &mut StableHasher
) {
107 self.0.hash_stable(hcx
, hasher
);